From 2ba39bd0f0b27152de78394d2a37f3f81016d848 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Singh Date: Thu, 10 Oct 2019 18:06:26 +0530 Subject: Fixed#731 Added check for local file url starting with `$HOME` / `~` to expand them using `os.path.expanduser`. --- git/cmd.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/git/cmd.py b/git/cmd.py index 2d288b25..a06daaaf 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -330,6 +330,10 @@ class Git(LazyMixin): but git stops liking them as it will escape the backslashes. Hence we undo the escaping just to be sure. """ + if url.startswith('$HOME/'): + url = url.replace('$HOME/', '~/') + if url.startswith('~'): + url = os.path.expanduser(url) url = url.replace("\\\\", "\\").replace("\\", "/") return url -- cgit v1.2.1 From 43564d2e8f3b95f33e10a5c8cc2d75c0252d659a Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Singh Date: Wed, 16 Oct 2019 21:57:51 +0530 Subject: Update cmd.py --- git/cmd.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index a06daaaf..78319c75 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -330,8 +330,7 @@ class Git(LazyMixin): but git stops liking them as it will escape the backslashes. Hence we undo the escaping just to be sure. """ - if url.startswith('$HOME/'): - url = url.replace('$HOME/', '~/') + url = os.path.expandvars(url) if url.startswith('~'): url = os.path.expanduser(url) url = url.replace("\\\\", "\\").replace("\\", "/") -- cgit v1.2.1 From 59ad90694b5393ce7f6790ade9cb58c24b8028e5 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Thu, 17 Oct 2019 22:15:45 -0500 Subject: Adding diff support for copied files, still working on test --- AUTHORS | 1 + git/diff.py | 29 +++++++++++++++++++++-------- git/test/fixtures/diff_copied_mode | 4 ++++ git/test/fixtures/diff_copied_mode_raw | 1 + git/test/test_diff.py | 21 +++++++++++++++++++++ 5 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 git/test/fixtures/diff_copied_mode create mode 100644 git/test/fixtures/diff_copied_mode_raw diff --git a/AUTHORS b/AUTHORS index e91fd78b..a7a19d54 100644 --- a/AUTHORS +++ b/AUTHORS @@ -34,5 +34,6 @@ Contributors are: -Stefan Stancu -César Izurieta -Arthur Milchior +-JJ Graham Portions derived from other open source works and are clearly marked. diff --git a/git/diff.py b/git/diff.py index 10cb9f02..5a63d44c 100644 --- a/git/diff.py +++ b/git/diff.py @@ -193,6 +193,8 @@ class DiffIndex(list): yield diff elif change_type == "D" and diff.deleted_file: yield diff + elif change_type == "C" and diff.copied_file: + yield diff elif change_type == "R" and diff.renamed: yield diff elif change_type == "M" and diff.a_blob and diff.b_blob and diff.a_blob != diff.b_blob: @@ -243,6 +245,7 @@ class Diff(object): ^rename[ ]to[ ](?P.*)(?:\n|$))? (?:^new[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? + (?:^copied[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^---[ ](?P[^\t\n\r\f\v]*)[\t\r\f\v]*(?:\n|$))? @@ -253,11 +256,11 @@ class Diff(object): NULL_BIN_SHA = b"\0" * 20 __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "a_rawpath", "b_rawpath", - "new_file", "deleted_file", "raw_rename_from", "raw_rename_to", - "diff", "change_type", "score") + "new_file", "deleted_file", "copied_file", "raw_rename_from", + "raw_rename_to", "diff", "change_type", "score") def __init__(self, repo, a_rawpath, b_rawpath, a_blob_id, b_blob_id, a_mode, - b_mode, new_file, deleted_file, raw_rename_from, + b_mode, new_file, deleted_file, copied_file, raw_rename_from, raw_rename_to, diff, change_type, score): self.a_mode = a_mode @@ -285,6 +288,7 @@ class Diff(object): self.new_file = new_file self.deleted_file = deleted_file + self.copied_file = copied_file # be clear and use None instead of empty strings assert raw_rename_from is None or isinstance(raw_rename_from, binary_type) @@ -336,6 +340,8 @@ class Diff(object): msg += '\nfile deleted in rhs' if self.new_file: msg += '\nfile added in rhs' + if self.copied_file: + msg += '\nfile %r copied from %r' % (self.b_path, self.a_path) if self.rename_from: msg += '\nfile renamed from %r' % self.rename_from if self.rename_to: @@ -419,11 +425,12 @@ class Diff(object): a_path_fallback, b_path_fallback, \ old_mode, new_mode, \ rename_from, rename_to, \ - new_file_mode, deleted_file_mode, \ + new_file_mode, deleted_file_mode, copied_file_mode, \ a_blob_id, b_blob_id, b_mode, \ a_path, b_path = header.groups() - new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode) + new_file, deleted_file, copied_file = \ + bool(new_file_mode), bool(deleted_file_mode), bool(copied_file_mode) a_path = cls._pick_best_path(a_path, rename_from, a_path_fallback) b_path = cls._pick_best_path(b_path, rename_to, b_path_fallback) @@ -445,7 +452,7 @@ class Diff(object): b_blob_id and b_blob_id.decode(defenc), a_mode and a_mode.decode(defenc), b_mode and b_mode.decode(defenc), - new_file, deleted_file, + new_file, deleted_file, copied_file, rename_from, rename_to, None, None, None)) @@ -485,6 +492,7 @@ class Diff(object): b_path = path.encode(defenc) deleted_file = False new_file = False + copied_file = False rename_from = None rename_to = None @@ -496,6 +504,11 @@ class Diff(object): elif change_type == 'A': a_blob_id = None new_file = True + elif change_type == 'C': + copied_file = True + a_path, b_path = path.split('\t', 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 = a_path.encode(defenc) @@ -507,8 +520,8 @@ class Diff(object): # 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, rename_from, rename_to, '', - change_type, score) + 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) diff --git a/git/test/fixtures/diff_copied_mode b/git/test/fixtures/diff_copied_mode new file mode 100644 index 00000000..60707afc --- /dev/null +++ b/git/test/fixtures/diff_copied_mode @@ -0,0 +1,4 @@ +diff --git a/test1.txt b/test2.txt +similarity index 100% +copy from test1.txt +copy to test2.txt diff --git a/git/test/fixtures/diff_copied_mode_raw b/git/test/fixtures/diff_copied_mode_raw new file mode 100644 index 00000000..7f414d81 --- /dev/null +++ b/git/test/fixtures/diff_copied_mode_raw @@ -0,0 +1 @@ +:100644 100644 cfe9dea cfe9dea C100 test1.txt test2.txt diff --git a/git/test/test_diff.py b/git/test/test_diff.py index e47b9331..079f8bea 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -112,6 +112,27 @@ class TestDiff(TestBase): self.assertEqual(diff.score, 100) self.assertEqual(len(list(diffs.iter_change_type('R'))), 1) + def test_diff_with_copied_file(self): + output = StringProcessAdapter(fixture('diff_copied_mode')) + diffs = Diff._index_from_patch_format(self.rorepo, output) + self._assert_diff_format(diffs) + + assert_equal(1, len(diffs)) + + diff = diffs[0] + print(diff) + assert_true(diff.copied_file) + assert isinstance(str(diff), str) + + output = StringProcessAdapter(fixture('diff_copied_mode_raw')) + diffs = Diff._index_from_raw_format(self.rorepo, output) + self.assertEqual(len(diffs), 1) + diff = diffs[0] + self.assertEqual(diff.change_type, 'C') + self.assertEqual(diff.score, 100) + self.assertEqual(len(list(diffs.iter_change_type('C'))), 1) + + def test_diff_with_change_in_type(self): output = StringProcessAdapter(fixture('diff_change_in_type')) diffs = Diff._index_from_patch_format(self.rorepo, output) -- cgit v1.2.1 From 71b3845807458766cd715c60a5f244836f4273b6 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Thu, 17 Oct 2019 23:04:22 -0500 Subject: Fixed new test for copied files --- git/diff.py | 6 ++++-- git/test/fixtures/diff_copied_mode_raw | 2 +- git/test/test_diff.py | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/git/diff.py b/git/diff.py index 5a63d44c..8bb0f839 100644 --- a/git/diff.py +++ b/git/diff.py @@ -167,7 +167,7 @@ class DiffIndex(list): # R = Renamed # M = Modified # T = Changed in the type - change_type = ("A", "D", "R", "M", "T") + change_type = ("A", "C", "D", "R", "M", "T") def iter_change_type(self, change_type): """ @@ -245,7 +245,9 @@ class Diff(object): ^rename[ ]to[ ](?P.*)(?:\n|$))? (?:^new[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? - (?:^copied[ ]file[ ]mode[ ](?P.+)(?:\n|$))? + (?:^similarity[ ]index[ ]\d+%\n + ^copy[ ]from[ ].*\n + ^copy[ ]to[ ](?P.*)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^---[ ](?P[^\t\n\r\f\v]*)[\t\r\f\v]*(?:\n|$))? diff --git a/git/test/fixtures/diff_copied_mode_raw b/git/test/fixtures/diff_copied_mode_raw index 7f414d81..7640f3ab 100644 --- a/git/test/fixtures/diff_copied_mode_raw +++ b/git/test/fixtures/diff_copied_mode_raw @@ -1 +1 @@ -:100644 100644 cfe9dea cfe9dea C100 test1.txt test2.txt +:100644 100644 cfe9deac6e10683917e80f877566b58644aa21df cfe9deac6e10683917e80f877566b58644aa21df C100 test1.txt test2.txt diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 079f8bea..4d71443f 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -120,7 +120,6 @@ class TestDiff(TestBase): assert_equal(1, len(diffs)) diff = diffs[0] - print(diff) assert_true(diff.copied_file) assert isinstance(str(diff), str) -- cgit v1.2.1 From a3c3efd20c50b2a9db98a892b803eb285b2a4f83 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Fri, 18 Oct 2019 10:27:38 -0500 Subject: Expanded new test for copied file --- git/test/test_diff.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 4d71443f..e1b345b5 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -121,6 +121,8 @@ class TestDiff(TestBase): diff = diffs[0] assert_true(diff.copied_file) + assert_true(diff.a_path, u'test1.txt') + assert_true(diff.b_path, u'test2.txt') assert isinstance(str(diff), str) output = StringProcessAdapter(fixture('diff_copied_mode_raw')) @@ -129,9 +131,10 @@ class TestDiff(TestBase): diff = diffs[0] self.assertEqual(diff.change_type, 'C') self.assertEqual(diff.score, 100) + self.assertEqual(diff.a_path, u'test1.txt') + self.assertEqual(diff.b_path, u'test2.txt') self.assertEqual(len(list(diffs.iter_change_type('C'))), 1) - def test_diff_with_change_in_type(self): output = StringProcessAdapter(fixture('diff_change_in_type')) diffs = Diff._index_from_patch_format(self.rorepo, output) -- cgit v1.2.1 From 4744efbb68c562adf7b42fc33381d27a463ae07a Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Fri, 18 Oct 2019 10:32:30 -0500 Subject: Updating variable name to more accurately reflect contents --- git/diff.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git/diff.py b/git/diff.py index 8bb0f839..80e0be6a 100644 --- a/git/diff.py +++ b/git/diff.py @@ -247,7 +247,7 @@ class Diff(object): (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^similarity[ ]index[ ]\d+%\n ^copy[ ]from[ ].*\n - ^copy[ ]to[ ](?P.*)(?:\n|$))? + ^copy[ ]to[ ](?P.*)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^---[ ](?P[^\t\n\r\f\v]*)[\t\r\f\v]*(?:\n|$))? @@ -427,12 +427,12 @@ class Diff(object): a_path_fallback, b_path_fallback, \ old_mode, new_mode, \ rename_from, rename_to, \ - new_file_mode, deleted_file_mode, copied_file_mode, \ + new_file_mode, deleted_file_mode, copied_file_name, \ a_blob_id, b_blob_id, b_mode, \ a_path, b_path = header.groups() new_file, deleted_file, copied_file = \ - bool(new_file_mode), bool(deleted_file_mode), bool(copied_file_mode) + bool(new_file_mode), bool(deleted_file_mode), bool(copied_file_name) a_path = cls._pick_best_path(a_path, rename_from, a_path_fallback) b_path = cls._pick_best_path(b_path, rename_to, b_path_fallback) -- cgit v1.2.1 From 95897f99551db8d81ca77adec3f44e459899c20b Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Fri, 18 Oct 2019 14:49:06 -0500 Subject: Satisfying flake8 --- git/diff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git/diff.py b/git/diff.py index 80e0be6a..0150d675 100644 --- a/git/diff.py +++ b/git/diff.py @@ -258,7 +258,7 @@ class Diff(object): NULL_BIN_SHA = b"\0" * 20 __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "a_rawpath", "b_rawpath", - "new_file", "deleted_file", "copied_file", "raw_rename_from", + "new_file", "deleted_file", "copied_file", "raw_rename_from", "raw_rename_to", "diff", "change_type", "score") def __init__(self, repo, a_rawpath, b_rawpath, a_blob_id, b_blob_id, a_mode, @@ -432,7 +432,7 @@ class Diff(object): a_path, b_path = header.groups() new_file, deleted_file, copied_file = \ - bool(new_file_mode), bool(deleted_file_mode), bool(copied_file_name) + bool(new_file_mode), bool(deleted_file_mode), bool(copied_file_name) a_path = cls._pick_best_path(a_path, rename_from, a_path_fallback) b_path = cls._pick_best_path(b_path, rename_to, b_path_fallback) -- cgit v1.2.1 From 6fd090293792884f5a0d05f69109da1c970c3cab Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sat, 19 Oct 2019 11:36:00 +0200 Subject: Fix pickling of tzoffset Fixes #650 --- git/objects/util.py | 3 +++ git/test/test_util.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/git/objects/util.py b/git/objects/util.py index 7b6a2763..5dbd9822 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -105,6 +105,9 @@ class tzoffset(tzinfo): self._offset = timedelta(seconds=-secs_west_of_utc) self._name = name or 'fixed' + def __reduce__(self): + return tzoffset, (-self._offset.total_seconds(), self._name) + def utcoffset(self, dt): return self._offset diff --git a/git/test/test_util.py b/git/test/test_util.py index b5f9d222..a4d9d7ad 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -4,6 +4,7 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import pickle import tempfile import time from unittest import skipIf @@ -280,3 +281,9 @@ class TestUtils(TestBase): # Wrong offset: UTC-9000, should return datetime + tzoffset(UTC) altz = utctz_to_altz('-9000') self.assertEqual(datetime.fromtimestamp(1522827734, tzoffset(0)), from_timestamp(1522827734, altz)) + + def test_pickle_tzoffset(self): + t1 = tzoffset(555) + t2 = pickle.loads(pickle.dumps(t1)) + self.assertEqual(t1._offset, t2._offset) + self.assertEqual(t1._name, t2._name) -- cgit v1.2.1 From b303cb0c5995bf9c74db34a8082cdf5258c250fe Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Sun, 20 Oct 2019 15:40:06 -0500 Subject: Initial stab at fixing diffs involving submodule changes --- git/cmd.py | 2 +- git/diff.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/git/cmd.py b/git/cmd.py index 78319c75..263c8ba7 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -67,7 +67,7 @@ __all__ = ('Git',) def handle_process_output(process, stdout_handler, stderr_handler, finalizer=None, decode_streams=True): - """Registers for notifications to lean that process output is ready to read, and dispatches lines to + """Registers for notifications to learn that process output is ready to read, and dispatches lines to the respective line handlers. This function returns once the finalizer returns diff --git a/git/diff.py b/git/diff.py index 0150d675..3dbe0866 100644 --- a/git/diff.py +++ b/git/diff.py @@ -278,6 +278,14 @@ class Diff(object): if self.b_mode: self.b_mode = mode_str_to_int(self.b_mode) + # Determine whether this diff references a submodule, if it does then + # we need to overwrite "repo" to the corresponding submodule's repo instead + if repo and a_rawpath: + for submodule in repo.submodules: + if submodule.path == a_rawpath.decode("utf-8"): + repo = submodule.module() + break + if a_blob_id is None or a_blob_id == self.NULL_HEX_SHA: self.a_blob = None else: -- cgit v1.2.1 From 544ceecf1a8d397635592d82808d3bb1a6d57e76 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Sun, 20 Oct 2019 16:13:31 -0500 Subject: Adding command to init-tests-after-clone.sh to make sure submodules are recursively cloned as well --- init-tests-after-clone.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init-tests-after-clone.sh b/init-tests-after-clone.sh index 0d445891..e852f3cd 100755 --- a/init-tests-after-clone.sh +++ b/init-tests-after-clone.sh @@ -12,4 +12,5 @@ git checkout master || git checkout -b master git reset --hard HEAD~1 git reset --hard HEAD~1 git reset --hard HEAD~1 -git reset --hard __testing_point__ \ No newline at end of file +git reset --hard __testing_point__ +git submodule update --init --recursive \ No newline at end of file -- cgit v1.2.1 From a086625da1939d2ccfc0dd27e4d5d63f47c3d2c9 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Sun, 20 Oct 2019 19:15:45 -0500 Subject: Added new test to cover the issue this fix addresses (#891) --- git/test/test_diff.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/git/test/test_diff.py b/git/test/test_diff.py index e1b345b5..1bab4510 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -5,12 +5,15 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import ddt +import shutil +import tempfile from git import ( Repo, GitCommandError, Diff, DiffIndex, NULL_TREE, + Submodule, ) from git.cmd import Git from git.test.lib import ( @@ -19,7 +22,6 @@ from git.test.lib import ( fixture, assert_equal, assert_true, - ) from git.test.lib import with_rw_directory @@ -29,9 +31,15 @@ import os.path as osp @ddt.ddt class TestDiff(TestBase): + def setUp(self): + self.repo_dir = tempfile.mkdtemp() + self.submodule_dir = tempfile.mkdtemp() + def tearDown(self): import gc gc.collect() + shutil.rmtree(self.repo_dir) + shutil.rmtree(self.submodule_dir) def _assert_diff_format(self, diffs): # verify that the format of the diff is sane @@ -68,7 +76,8 @@ class TestDiff(TestBase): r.git.commit(all=True, message="change on topic branch") # there must be a merge-conflict - self.failUnlessRaises(GitCommandError, r.git.cherry_pick, 'master') + with self.assertRaises(GitCommandError): + r.git.cherry_pick('master') # Now do the actual testing - this should just work self.assertEqual(len(r.index.diff(None)), 2) @@ -267,6 +276,43 @@ class TestDiff(TestBase): self.assertIsNone(diff_index[0].a_path, repr(diff_index[0].a_path)) self.assertEqual(diff_index[0].b_path, u'file with spaces', repr(diff_index[0].b_path)) + def test_diff_submodule(self): + """Test that diff is able to correctly diff commits that cover submodule changes""" + # Init a temp git repo that will be referenced as a submodule + sub = Repo.init(self.submodule_dir) + with open(f"{self.submodule_dir}/subfile", "w") as sub_subfile: + sub_subfile.write("") + sub.index.add(["subfile"]) + sub.index.commit("first commit") + + # Init a temp git repo that will incorporate the submodule + repo = Repo.init(self.repo_dir) + with open(f"{self.repo_dir}/test", "w") as foo_test: + foo_test.write("") + repo.index.add(['test']) + Submodule.add(repo, "subtest", "sub", url=f"file://{self.submodule_dir}") + repo.index.commit("first commit") + repo.create_tag('1') + + # Add a commit to the submodule + submodule = repo.submodule('subtest') + with open(f"{self.repo_dir}/sub/subfile", "w") as foo_sub_subfile: + foo_sub_subfile.write("blub") + submodule.module().index.add(["subfile"]) + submodule.module().index.commit("changed subfile") + submodule.binsha = submodule.module().head.commit.binsha + + # Commit submodule updates in parent repo + repo.index.add([submodule]) + repo.index.commit("submodule changed") + repo.create_tag('2') + + diff = repo.commit('1').diff(repo.commit('2'))[0] + # If diff is unable to find the commit hashes (looks in wrong repo) the *_blob.size + # property will be a string containing exception text, an int indicates success + self.assertIsInstance(diff.a_blob.size, int) + self.assertIsInstance(diff.b_blob.size, int) + def test_diff_interface(self): # test a few variations of the main diff routine assertion_map = {} -- cgit v1.2.1 From 44496c6370d8f9b15b953a88b33816a92096ce4d Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Sun, 20 Oct 2019 19:52:03 -0500 Subject: Removing f-strings to maintain 3.4 and 3.5 compatability --- git/test/test_diff.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 1bab4510..56e51289 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -280,23 +280,23 @@ class TestDiff(TestBase): """Test that diff is able to correctly diff commits that cover submodule changes""" # Init a temp git repo that will be referenced as a submodule sub = Repo.init(self.submodule_dir) - with open(f"{self.submodule_dir}/subfile", "w") as sub_subfile: + with open(self.submodule_dir + "/subfile", "w") as sub_subfile: sub_subfile.write("") sub.index.add(["subfile"]) sub.index.commit("first commit") # Init a temp git repo that will incorporate the submodule repo = Repo.init(self.repo_dir) - with open(f"{self.repo_dir}/test", "w") as foo_test: + with open(self.repo_dir + "/test", "w") as foo_test: foo_test.write("") repo.index.add(['test']) - Submodule.add(repo, "subtest", "sub", url=f"file://{self.submodule_dir}") + Submodule.add(repo, "subtest", "sub", url="file://" + self.submodule_dir) repo.index.commit("first commit") repo.create_tag('1') # Add a commit to the submodule submodule = repo.submodule('subtest') - with open(f"{self.repo_dir}/sub/subfile", "w") as foo_sub_subfile: + with open(self.repo_dir + "/sub/subfile", "w") as foo_sub_subfile: foo_sub_subfile.write("blub") submodule.module().index.add(["subfile"]) submodule.module().index.commit("changed subfile") -- cgit v1.2.1 From 14d7034adc2698c1e7dd13570c23d217c753e932 Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Mon, 21 Oct 2019 17:16:59 -0500 Subject: Fix #852 by tweaking regex to handle -R option to git diff --- git/diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/diff.py b/git/diff.py index 3dbe0866..a0076f0c 100644 --- a/git/diff.py +++ b/git/diff.py @@ -237,7 +237,7 @@ class Diff(object): # precompiled regex re_header = re.compile(br""" ^diff[ ]--git - [ ](?P"?a/.+?"?)[ ](?P"?b/.+?"?)\n + [ ](?P"?[ab]/.+?"?)[ ](?P"?[ab]/.+?"?)\n (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? (?:^similarity[ ]index[ ]\d+%\n -- cgit v1.2.1 From 38c624f74061a459a94f6d1dac250271f5548dab Mon Sep 17 00:00:00 2001 From: JJ Graham Date: Mon, 21 Oct 2019 17:28:00 -0500 Subject: Adding assertions to existing test case to cover this change --- git/test/test_diff.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 56e51289..e4e7556d 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -68,7 +68,12 @@ class TestDiff(TestBase): with open(fp, 'w') as fs: fs.write("Hola Mundo") - r.git.commit(all=True, message="change on master") + r.git.add(Git.polish_url(fp)) + self.assertEqual(len(r.index.diff("HEAD", create_patch=True)), 1, + "create_patch should generate patch of diff to HEAD") + r.git.commit(message="change on master") + self.assertEqual(len(r.index.diff("HEAD", create_patch=True)), 0, + "create_patch should generate no patch, already on HEAD") r.git.checkout('HEAD~1', b='topic') with open(fp, 'w') as fs: -- cgit v1.2.1 From c2636d216d43b40a477d3a5180f308fc071abaeb Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 22 Oct 2019 12:41:09 +0200 Subject: bump patch level --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 75a22a26..b0f2dcb3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.3 +3.0.4 -- cgit v1.2.1 From 74930577ec77fefe6ae9989a5aeb8f244923c9ac Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 22 Oct 2019 12:47:19 +0200 Subject: Update changelog; improve README to prevent release mistakes in future. --- README.md | 7 ++++--- doc/source/changes.rst | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3734019e..46867a4c 100644 --- a/README.md +++ b/README.md @@ -110,12 +110,13 @@ Please have a look at the [contributions file][contributing]. ### How to make a new release -* Update/verify the version in the `VERSION` file -* Update/verify that the changelog has been updated +* Update/verify the **version** in the `VERSION` file +* Update/verify that the `doc/source/changes.rst` changelog file was updated * Commit everything * Run `git tag -s ` to tag the version in Git * Run `make release` -* Finally, set the upcoming version in the `VERSION` file, usually be +* Close the milestone mentioned in the _changelog_ and create a new one. _Do not reuse milestones by renaming them_. +* set the upcoming version in the `VERSION` file, usually be incrementing the patch level, and possibly by appending `-dev`. Probably you want to `git push` once more. diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 356056e7..ff5c0459 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,12 @@ Changelog ========= +3.0.4 - Bugfixes +============================================= + +see the following for details: +https://github.com/gitpython-developers/gitpython/milestone/31?closed=1 + 3.0.3 - Bugfixes ============================================= -- cgit v1.2.1 From dfa0eac1578bff14a8f7fa00bfc3c57aba24f877 Mon Sep 17 00:00:00 2001 From: Ben Thayer Date: Tue, 22 Oct 2019 14:39:50 -0500 Subject: Added exception handling for WinError6 --- git/cmd.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 263c8ba7..484a0181 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -365,8 +365,11 @@ class Git(LazyMixin): proc.stderr.close() # did the process finish already so we have a return code ? - if proc.poll() is not None: - return + try: + if proc.poll() is not None: + return + except OSError as ex: + log.info("Ignored error after process had died: %r", ex) # can be that nothing really exists anymore ... if os is None or getattr(os, 'kill', None) is None: -- cgit v1.2.1