diff options
author | Lars Schneider <larsxschneider@gmail.com> | 2015-09-21 12:01:41 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-09-22 12:15:17 -0700 |
commit | 1f5f3907117021961545e42097829001b58288db (patch) | |
tree | a40aa1d07966ba00d81a4a1c9daece2aada906b3 | |
parent | fe18a0f2793b7559d5565bc65b53c7c018de3c21 (diff) | |
download | git-ls/p4-translation-failure.tar.gz |
git-p4: handle "Translation of file content failed"ls/p4-translation-failure
A P4 repository can get into a state where it contains a file with
type UTF-16 that does not contain a valid UTF-16 BOM. If git-p4
attempts to retrieve the file then the process crashes with a
"Translation of file content failed" error.
More info here: http://answers.perforce.com/articles/KB/3117
Fix this by detecting this error and retrieving the file as binary
instead. The result in Git is the same.
Known issue: This works only if git-p4 is executed in verbose mode.
In normal mode no exceptions are thrown and git-p4 just exits.
Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | git-p4.py | 27 | ||||
-rwxr-xr-x | t/t9825-git-p4-handle-utf16-without-bom.sh | 2 |
2 files changed, 17 insertions, 12 deletions
@@ -134,13 +134,11 @@ def read_pipe(c, ignore_error=False): sys.stderr.write('Reading pipe: %s\n' % str(c)) expand = isinstance(c,basestring) - p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand) - pipe = p.stdout - val = pipe.read() - if p.wait() and not ignore_error: - die('Command failed: %s' % str(c)) - - return val + p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand) + (out, err) = p.communicate() + if p.returncode != 0 and not ignore_error: + die('Command failed: %s\nError: %s' % (str(c), err)) + return out def p4_read_pipe(c, ignore_error=False): real_cmd = p4_build_cmd(c) @@ -2193,10 +2191,17 @@ class P4Sync(Command, P4UserMap): # them back too. This is not needed to the cygwin windows version, # just the native "NT" type. # - text = p4_read_pipe(['print', '-q', '-o', '-', "%s@%s" % (file['depotFile'], file['change']) ]) - if p4_version_string().find("/NT") >= 0: - text = text.replace("\r\n", "\n") - contents = [ text ] + try: + text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (file['depotFile'], file['change'])]) + except Exception as e: + if 'Translation of file content failed' in str(e): + type_base = 'binary' + else: + raise e + else: + if p4_version_string().find('/NT') >= 0: + text = text.replace('\r\n', '\n') + contents = [ text ] if type_base == "apple": # Apple filetype files will be streamed as a concatenation of diff --git a/t/t9825-git-p4-handle-utf16-without-bom.sh b/t/t9825-git-p4-handle-utf16-without-bom.sh index bdd5911102..1551845dc1 100755 --- a/t/t9825-git-p4-handle-utf16-without-bom.sh +++ b/t/t9825-git-p4-handle-utf16-without-bom.sh @@ -29,7 +29,7 @@ test_expect_success 'init depot with UTF-16 encoded file and artificially remove ) ' -test_expect_failure 'clone depot with invalid UTF-16 file in verbose mode' ' +test_expect_success 'clone depot with invalid UTF-16 file in verbose mode' ' git p4 clone --dest="$git" --verbose //depot && test_when_finished cleanup_git && ( |