From 90a6e1c8f793571730f1c77f2dce745813938b66 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 5 Jan 2021 20:34:42 +0800 Subject: [PATCH 1/3] Add '-z' on top of '--raw' to avoid path name mangling Authored based on https://github.com/gitpython-developers/GitPython/issues/1099#issuecomment-754606044 Fixes #1099 --- git/diff.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git/diff.py b/git/diff.py index 0fc30b9eb..17ef15af9 100644 --- a/git/diff.py +++ b/git/diff.py @@ -108,6 +108,7 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs): args.append("-p") else: args.append("--raw") + args.append("-z") # in any way, assure we don't see colored output, # fixes https://github.com/gitpython-developers/GitPython/issues/172 @@ -483,7 +484,7 @@ def handle_diff_line(line): if not line.startswith(":"): return - meta, _, path = line[1:].partition('\t') + meta, _, path = line[1:].partition('\x00') old_mode, new_mode, a_blob_id, b_blob_id, _change_type = meta.split(None, 4) # Change type can be R100 # R: status letter From 21e2c4589934d4801c15a482a37322cb704fc55b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 5 Jan 2021 21:53:24 +0800 Subject: [PATCH 2/3] try fixing up test fixtures and implementation --- git/diff.py | 4 ++-- test/test_diff.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/git/diff.py b/git/diff.py index 17ef15af9..cd7cc23c4 100644 --- a/git/diff.py +++ b/git/diff.py @@ -511,11 +511,11 @@ def handle_diff_line(line): new_file = True elif change_type == 'C': copied_file = True - a_path, b_path = path.split('\t', 1) + a_path, b_path = path.split('\x00', 1) a_path = a_path.encode(defenc) b_path = b_path.encode(defenc) elif change_type == 'R': - a_path, b_path = path.split('\t', 1) + a_path, b_path = path.split('\x00', 1) a_path = a_path.encode(defenc) b_path = b_path.encode(defenc) rename_from, rename_to = a_path, b_path diff --git a/test/test_diff.py b/test/test_diff.py index 378a58de5..c6c9b67a0 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -26,6 +26,10 @@ import os.path as osp +def to_raw(input): + return input.replace(b'\t', b'\x00') + + @ddt.ddt class TestDiff(TestBase): @@ -112,7 +116,7 @@ def test_diff_with_rename(self): self.assertEqual(diff.raw_rename_to, b'm\xc3\xbcller') assert isinstance(str(diff), str) - output = StringProcessAdapter(fixture('diff_rename_raw')) + output = StringProcessAdapter(to_raw(fixture('diff_rename_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] @@ -137,7 +141,7 @@ def test_diff_with_copied_file(self): self.assertTrue(diff.b_path, 'test2.txt') assert isinstance(str(diff), str) - output = StringProcessAdapter(fixture('diff_copied_mode_raw')) + output = StringProcessAdapter(to_raw(fixture('diff_copied_mode_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] @@ -165,7 +169,7 @@ def test_diff_with_change_in_type(self): self.assertIsNotNone(diff.new_file) assert isinstance(str(diff), str) - output = StringProcessAdapter(fixture('diff_change_in_type_raw')) + output = StringProcessAdapter(to_raw(fixture('diff_change_in_type_raw'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] @@ -175,7 +179,7 @@ def test_diff_with_change_in_type(self): self.assertEqual(len(list(diffs.iter_change_type('T'))), 1) def test_diff_of_modified_files_not_added_to_the_index(self): - output = StringProcessAdapter(fixture('diff_abbrev-40_full-index_M_raw_no-color')) + output = StringProcessAdapter(to_raw(fixture('diff_abbrev-40_full-index_M_raw_no-color'))) diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1, 'one modification') From 6e5d85864657f6c44a4aa20730b7fda2bbd54f1a Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 5 Jan 2021 15:53:32 +0100 Subject: [PATCH 3/3] Fix handle_diff_line for -z option. --- git/diff.py | 98 ++++++++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/git/diff.py b/git/diff.py index cd7cc23c4..a9dc4b572 100644 --- a/git/diff.py +++ b/git/diff.py @@ -479,55 +479,55 @@ def _index_from_raw_format(cls, repo, proc): index = DiffIndex() - def handle_diff_line(line): - line = line.decode(defenc) - if not line.startswith(":"): - return - - meta, _, path = line[1:].partition('\x00') - old_mode, new_mode, a_blob_id, b_blob_id, _change_type = meta.split(None, 4) - # Change type can be R100 - # R: status letter - # 100: score (in case of copy and rename) - change_type = _change_type[0] - score_str = ''.join(_change_type[1:]) - score = int(score_str) if score_str.isdigit() else None - path = path.strip() - a_path = path.encode(defenc) - b_path = path.encode(defenc) - deleted_file = False - new_file = False - copied_file = False - rename_from = None - rename_to = None - - # NOTE: We cannot conclude from the existence of a blob to change type - # as diffs with the working do not have blobs yet - if change_type == 'D': - b_blob_id = None - deleted_file = True - elif change_type == 'A': - a_blob_id = None - new_file = True - elif change_type == 'C': - copied_file = True - a_path, b_path = path.split('\x00', 1) - a_path = a_path.encode(defenc) - b_path = b_path.encode(defenc) - elif change_type == 'R': - a_path, b_path = path.split('\x00', 1) - a_path = a_path.encode(defenc) - b_path = b_path.encode(defenc) - rename_from, rename_to = a_path, b_path - elif change_type == 'T': - # Nothing to do - pass - # END add/remove handling - - diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode, - new_file, deleted_file, copied_file, rename_from, rename_to, - '', change_type, score) - index.append(diff) + def handle_diff_line(lines): + lines = lines.decode(defenc) + + for line in lines.split(':')[1:]: + meta, _, path = line.partition('\x00') + path = path.rstrip('\x00') + old_mode, new_mode, a_blob_id, b_blob_id, _change_type = meta.split(None, 4) + # Change type can be R100 + # R: status letter + # 100: score (in case of copy and rename) + change_type = _change_type[0] + score_str = ''.join(_change_type[1:]) + score = int(score_str) if score_str.isdigit() else None + path = path.strip() + a_path = path.encode(defenc) + b_path = path.encode(defenc) + deleted_file = False + new_file = False + copied_file = False + rename_from = None + rename_to = None + + # NOTE: We cannot conclude from the existence of a blob to change type + # as diffs with the working do not have blobs yet + if change_type == 'D': + b_blob_id = None + deleted_file = True + elif change_type == 'A': + a_blob_id = None + new_file = True + elif change_type == 'C': + copied_file = True + a_path, b_path = path.split('\x00', 1) + a_path = a_path.encode(defenc) + b_path = b_path.encode(defenc) + elif change_type == 'R': + a_path, b_path = path.split('\x00', 1) + a_path = a_path.encode(defenc) + b_path = b_path.encode(defenc) + rename_from, rename_to = a_path, b_path + elif change_type == 'T': + # Nothing to do + pass + # END add/remove handling + + diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode, + new_file, deleted_file, copied_file, rename_from, rename_to, + '', change_type, score) + index.append(diff) handle_process_output(proc, handle_diff_line, None, finalize_process, decode_streams=False) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy