summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Driessen <me@nvie.com>2016-04-12 15:55:01 +0200
committerVincent Driessen <me@nvie.com>2016-04-14 12:39:37 +0200
commit5de21c7fa2bdd5cd50c4f62ba848af54589167d0 (patch)
treec0bd1badbffa52299162d9318fd9583eeead574a
parent83156b950bb76042198950f2339cb940f1170ee2 (diff)
downloadgitpython-5de21c7fa2bdd5cd50c4f62ba848af54589167d0.tar.gz
Support "root" as a special value in .diff() calls
This enabled getting diff patches for root commits.
-rw-r--r--git/diff.py14
-rw-r--r--git/test/fixtures/diff_initial10
-rw-r--r--git/test/test_diff.py17
3 files changed, 36 insertions, 5 deletions
diff --git a/git/diff.py b/git/diff.py
index 062220df..eada73b9 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -49,6 +49,7 @@ class Diffable(object):
If None, we will be compared to the working tree.
If Treeish, it will be compared against the respective tree
If Index ( type ), it will be compared against the index.
+ If the string 'root', it will compare the empty tree against this tree.
It defaults to Index to assure the method will not by-default fail
on bare repositories.
@@ -87,10 +88,15 @@ class Diffable(object):
if paths is not None and not isinstance(paths, (tuple, list)):
paths = [paths]
- if other is not None and other is not self.Index:
- args.insert(0, other)
+ diff_cmd = self.repo.git.diff
if other is self.Index:
- args.insert(0, "--cached")
+ args.insert(0, '--cached')
+ elif other == 'root':
+ args.insert(0, '--root')
+ diff_cmd = self.repo.git.diff_tree
+ elif other is not None:
+ args.insert(0, other)
+ diff_cmd = self.repo.git.diff_tree
args.insert(0, self)
@@ -101,7 +107,7 @@ class Diffable(object):
# END paths handling
kwargs['as_process'] = True
- proc = self.repo.git.diff(*self._process_diff_args(args), **kwargs)
+ proc = diff_cmd(*self._process_diff_args(args), **kwargs)
diff_method = Diff._index_from_raw_format
if create_patch:
diff --git a/git/test/fixtures/diff_initial b/git/test/fixtures/diff_initial
new file mode 100644
index 00000000..6037c677
--- /dev/null
+++ b/git/test/fixtures/diff_initial
@@ -0,0 +1,10 @@
+--- /dev/null
++++ b/CHANGES
+@@ -0,0 +1,7 @@
++=======
++CHANGES
++=======
++
++0.1.0
++=====
++initial release
diff --git a/git/test/test_diff.py b/git/test/test_diff.py
index b0d98248..136e6fd9 100644
--- a/git/test/test_diff.py
+++ b/git/test/test_diff.py
@@ -128,6 +128,21 @@ class TestDiff(TestBase):
assert res[0].deleted_file
assert res[0].b_path == ''
+ def test_diff_initial_commit(self):
+ initial_commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781')
+
+ # Without creating a patch...
+ diff_index = initial_commit.diff('root')
+ assert diff_index[0].b_path == 'CHANGES'
+ assert diff_index[0].new_file
+ assert diff_index[0].diff == ''
+
+ # ...and with creating a patch
+ diff_index = initial_commit.diff('root', create_patch=True)
+ assert diff_index[0].b_path == 'CHANGES'
+ assert diff_index[0].new_file
+ assert diff_index[0].diff == fixture('diff_initial')
+
def test_diff_patch_format(self):
# test all of the 'old' format diffs for completness - it should at least
# be able to deal with it
@@ -149,7 +164,7 @@ class TestDiff(TestBase):
diff_item = commit.tree
# END use tree every second item
- for other in (None, commit.Index, commit.parents[0]):
+ for other in (None, 'root', commit.Index, commit.parents[0]):
for paths in (None, "CHANGES", ("CHANGES", "lib")):
for create_patch in range(2):
diff_index = diff_item.diff(other=other, paths=paths, create_patch=create_patch)