Skip to content

Commit 5de21c7

Browse files
committed
Support "root" as a special value in .diff() calls
This enabled getting diff patches for root commits.
1 parent 83156b9 commit 5de21c7

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

‎git/diff.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs):
4949
If None, we will be compared to the working tree.
5050
If Treeish, it will be compared against the respective tree
5151
If Index ( type ), it will be compared against the index.
52+
If the string 'root', it will compare the empty tree against this tree.
5253
It defaults to Index to assure the method will not by-default fail
5354
on bare repositories.
5455
@@ -87,10 +88,15 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs):
8788
if paths is not None and not isinstance(paths, (tuple, list)):
8889
paths = [paths]
8990

90-
if other is not None and other is not self.Index:
91-
args.insert(0, other)
91+
diff_cmd = self.repo.git.diff
9292
if other is self.Index:
93-
args.insert(0, "--cached")
93+
args.insert(0, '--cached')
94+
elif other == 'root':
95+
args.insert(0, '--root')
96+
diff_cmd = self.repo.git.diff_tree
97+
elif other is not None:
98+
args.insert(0, other)
99+
diff_cmd = self.repo.git.diff_tree
94100

95101
args.insert(0, self)
96102

@@ -101,7 +107,7 @@ def diff(self, other=Index, paths=None, create_patch=False, **kwargs):
101107
# END paths handling
102108

103109
kwargs['as_process'] = True
104-
proc = self.repo.git.diff(*self._process_diff_args(args), **kwargs)
110+
proc = diff_cmd(*self._process_diff_args(args), **kwargs)
105111

106112
diff_method = Diff._index_from_raw_format
107113
if create_patch:

‎git/test/fixtures/diff_initial

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--- /dev/null
2+
+++ b/CHANGES
3+
@@ -0,0 +1,7 @@
4+
+=======
5+
+CHANGES
6+
+=======
7+
+
8+
+0.1.0
9+
+=====
10+
+initial release

‎git/test/test_diff.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,21 @@ def test_diff_index_raw_format(self):
128128
assert res[0].deleted_file
129129
assert res[0].b_path == ''
130130

131+
def test_diff_initial_commit(self):
132+
initial_commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781')
133+
134+
# Without creating a patch...
135+
diff_index = initial_commit.diff('root')
136+
assert diff_index[0].b_path == 'CHANGES'
137+
assert diff_index[0].new_file
138+
assert diff_index[0].diff == ''
139+
140+
# ...and with creating a patch
141+
diff_index = initial_commit.diff('root', create_patch=True)
142+
assert diff_index[0].b_path == 'CHANGES'
143+
assert diff_index[0].new_file
144+
assert diff_index[0].diff == fixture('diff_initial')
145+
131146
def test_diff_patch_format(self):
132147
# test all of the 'old' format diffs for completness - it should at least
133148
# be able to deal with it
@@ -149,7 +164,7 @@ def test_diff_interface(self):
149164
diff_item = commit.tree
150165
# END use tree every second item
151166

152-
for other in (None, commit.Index, commit.parents[0]):
167+
for other in (None, 'root', commit.Index, commit.parents[0]):
153168
for paths in (None, "CHANGES", ("CHANGES", "lib")):
154169
for create_patch in range(2):
155170
diff_index = diff_item.diff(other=other, paths=paths, create_patch=create_patch)

0 commit comments

Comments
 (0)