Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9acc780

Browse files
committed
DiffIndex implemented including test
1 parente063d10 commit9acc780

File tree

3 files changed

+79
-12
lines changed

3 files changed

+79
-12
lines changed

‎CHANGES‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ Diff
8080
* Members a a_commit and b_commit renamed to a_blob and b_blob - they are populated
8181
with Blob objects if possible
8282
* Members a_path and b_path removed as this information is kept in the blobs
83+
* Diffs are now returned as DiffIndex allowing to more quickly find the kind of
84+
diffs you are interested in
85+
86+
Diffing
87+
-------
88+
* Commit and Tree objects now support diffing natively with a common interface to
89+
compare agains other Commits or Trees, against the working tree or against the index.
8390

8491
Blob
8592
----

‎lib/git/diff.py‎

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ class Diffable(object):
2222
# them in this tuple
2323
_diff_args=tuple()
2424

25+
# Temporary standin for Index type until we have a real index type
26+
classIndex(object):
27+
pass
28+
2529
defdiff(self,other=None,paths=None,create_patch=False,**kwargs):
2630
"""
2731
Creates diffs between two items being trees, trees and index or an
@@ -30,6 +34,7 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
3034
``other``
3135
Is the item to compare us with.
3236
If None, we will be compared to the working tree.
37+
If Index ( type ), it will be compared against the index
3338
3439
``paths``
3540
is a list of paths or a single path to limit the diff to.
@@ -63,8 +68,10 @@ def diff(self, other=None, paths=None, create_patch=False, **kwargs):
6368
ifpathsisnotNoneandnotisinstance(paths, (tuple,list)):
6469
paths= [paths ]
6570

66-
ifotherisnotNone:
71+
ifotherisnotNoneandotherisnotself.Index:
6772
args.insert(0,other)
73+
ifotherisself.Index:
74+
args.insert(0,"--cached")
6875

6976
args.insert(0,self)
7077

@@ -90,7 +97,33 @@ class DiffIndex(list):
9097
9198
The class improves the diff handling convenience
9299
"""
100+
# change type invariant identifying possible ways a blob can have changed
101+
# A = Added
102+
# D = Deleted
103+
# R = Renamed
104+
# NOTE: 'Modified' mode is impllied as it wouldn't be listed as a diff otherwise
105+
change_type= ("A","D","R")
106+
93107

108+
defiter_change_type(self,change_type):
109+
"""
110+
Return
111+
iterator yieling Diff instances that match the given change_type
112+
113+
``change_type``
114+
Member of DiffIndex.change_type
115+
"""
116+
ifchange_typenotinself.change_type:
117+
raiseValueError("Invalid change type: %s"%change_type )
118+
119+
fordiffinself:
120+
ifchange_type=="A"anddiff.new_file:
121+
yielddiff
122+
elifchange_type=="D"anddiff.deleted_file:
123+
yielddiff
124+
elifchange_type=="R"anddiff.renamed:
125+
yielddiff
126+
# END for each diff
94127

95128

96129
classDiff(object):
@@ -132,7 +165,7 @@ class Diff(object):
132165
""",re.VERBOSE|re.MULTILINE)
133166
re_is_null_hexsha=re.compile(r'^0{40}$' )
134167
__slots__= ("a_blob","b_blob","a_mode","b_mode","new_file","deleted_file",
135-
"rename_from","rename_to","renamed","diff")
168+
"rename_from","rename_to","diff")
136169

137170
def__init__(self,repo,a_path,b_path,a_blob_id,b_blob_id,a_mode,
138171
b_mode,new_file,deleted_file,rename_from,
@@ -148,17 +181,29 @@ def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode,
148181

149182
self.a_mode=a_mode
150183
self.b_mode=b_mode
184+
151185
ifself.a_mode:
152186
self.a_mode=blob.Blob._mode_str_to_int(self.a_mode )
153187
ifself.b_mode:
154188
self.b_mode=blob.Blob._mode_str_to_int(self.b_mode )
189+
155190
self.new_file=new_file
156191
self.deleted_file=deleted_file
157-
self.rename_from=rename_from
158-
self.rename_to=rename_to
159-
self.renamed=rename_from!=rename_to
192+
193+
# be clear and use None instead of empty strings
194+
self.rename_from=rename_fromorNone
195+
self.rename_to=rename_toorNone
196+
160197
self.diff=diff
161198

199+
@property
200+
defrenamed(self):
201+
"""
202+
Returns:
203+
True if the blob of our diff has been renamed
204+
"""
205+
returnself.rename_from!=self.rename_to
206+
162207
@classmethod
163208
def_index_from_patch_format(cls,repo,stream):
164209
"""
@@ -210,20 +255,22 @@ def _index_from_raw_format(cls, repo, stream):
210255
ifnotline.startswith(":"):
211256
continue
212257
# END its not a valid diff line
213-
old_mode,new_mode,a_blob_id,b_blob_id,modification_id,path=line[1:].split()
258+
old_mode,new_mode,a_blob_id,b_blob_id,change_type,path=line[1:].split()
214259
a_path=path
215260
b_path=path
216261
deleted_file=False
217262
new_file=False
218-
ifmodification_id=='D':
263+
264+
# NOTE: We cannot conclude from the existance of a blob to change type
265+
# as diffs with the working do not have blobs yet
266+
ifchange_type=='D':
219267
b_path=None
220268
deleted_file=True
221-
elifmodification_id=='A':
269+
elifchange_type=='A':
222270
a_path=None
223271
new_file=True
224272
# END add/remove handling
225273

226-
227274
diff=Diff(repo,a_path,b_path,a_blob_id,b_blob_id,old_mode,new_mode,
228275
new_file,deleted_file,None,None,'')
229276
index.append(diff)

‎test/git/test_diff.py‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,35 @@ def test_diff_patch_format(self):
4242

4343
deftest_diff_interface(self):
4444
# test a few variations of the main diff routine
45+
assertion_map=dict()
4546
fori,commitinenumerate(self.repo.iter_commits('0.1.6',max_count=10)):
4647
diff_item=commit
4748
ifi%2==0:
4849
diff_item=commit.tree
4950
# END use tree every second item
5051

51-
forotherin (None,commit.parents[0]):
52+
forotherin (None,commit.Index,commit.parents[0]):
5253
forpathsin (None,"CHANGES", ("CHANGES","lib")):
5354
forcreate_patchinrange(2):
5455
diff_index=diff_item.diff(other,paths,create_patch)
5556
assertisinstance(diff_index,DiffIndex)
5657

57-
# TODO: test diff index
58+
ifdiff_index:
59+
forctinDiffIndex.change_type:
60+
key='ct_%s'%ct
61+
assertion_map.setdefault(key,0)
62+
assertion_map[key]=assertion_map[key]+len(list(diff_index.iter_change_type(ct)))
63+
# END for each changetype
64+
# END diff index checking
5865
# END for each patch option
5966
# END for each path option
6067
# END for each other side
6168
# END for each commit
6269

63-
self.fail("TODO: Test full diff interface on commits, trees, index, patch and non-patch" )
70+
# assert we could always find at least one instance of the members we
71+
# can iterate in the diff index - if not this indicates its not working correctly
72+
# or our test does not span the whole range of possibilities
73+
forkey,valueinassertion_map.items():
74+
assertvalue,"Did not find diff for %s"%key
75+
# END for each iteration type
76+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp