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

Commitd82a6c5

Browse files
committed
fix(tree): tree item sort now uses git-style
Previously it was possible to generate trees which didn'tappear legit to git as gitpython's sorting was a simple alpha-numericsort. Git uses one that minimizes literal string comparisons though,and thus behaves slightly differently sometimes.Fixes#369
1 parenta1a5976 commitd82a6c5

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

‎git/objects/tree.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,53 @@
1818
tree_to_stream
1919
)
2020

21+
fromgitdb.utils.compatimportPY3
22+
23+
ifPY3:
24+
cmp=lambdaa,b: (a>b)- (a<b)
25+
2126
__all__= ("TreeModifier","Tree")
2227

2328

29+
defgit_cmp(t1,t2):
30+
a,b=t1[2],t2[2]
31+
len_a,len_b=len(a),len(b)
32+
min_len=min(len_a,len_b)
33+
min_cmp=cmp(a[:min_len],b[:min_len])
34+
35+
ifmin_cmp:
36+
returnmin_cmp
37+
38+
# return len_a - len_b
39+
returnlen_b-len_a
40+
41+
ifPY3:
42+
# taken from https://wiki.python.org/moin/HowTo/Sorting#The_Old_Way_Using_the_cmp_Parameter
43+
classCmpToKey(object):
44+
__slots__='obj'
45+
46+
def__init__(self,obj,*args):
47+
self.obj=obj
48+
49+
def__lt__(self,other):
50+
returngit_cmp(self.obj,other.obj)<0
51+
52+
def__gt__(self,other):
53+
returngit_cmp(self.obj,other.obj)>0
54+
55+
def__eq__(self,other):
56+
returngit_cmp(self.obj,other.obj)==0
57+
58+
def__le__(self,other):
59+
returngit_cmp(self.obj,other.obj)<=0
60+
61+
def__ge__(self,other):
62+
returngit_cmp(self.obj,other.obj)>=0
63+
64+
def__ne__(self,other):
65+
returngit_cmp(self.obj,other.obj)!=0
66+
67+
2468
classTreeModifier(object):
2569

2670
"""A utility class providing methods to alter the underlying cache in a list-like fashion.
@@ -47,7 +91,10 @@ def set_done(self):
4791
It may be called several times, but be aware that each call will cause
4892
a sort operation
4993
:return self:"""
50-
self._cache.sort(key=lambdat:t[2])# sort by name
94+
ifPY3:
95+
self._cache.sort(key=CmpToKey)
96+
else:
97+
self._cache.sort(cmp=git_cmp)
5198
returnself
5299
#} END interface
53100

@@ -286,3 +333,4 @@ def _deserialize(self, stream):
286333

287334
# finalize map definition
288335
Tree._map_id_to_type[Tree.tree_id]=Tree
336+
#

‎git/test/test_tree.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,30 @@ def test_serializable(self):
7777
# del again, its fine
7878
del(mod[invalid_name])
7979

80+
# SPECIAL ORDERING !
81+
# Add items which should sort differently from standard alum sort order
82+
mod.add(hexsha,Tree.blob_id<<12,'fild')
83+
mod.add(hexsha,Tree.blob_id<<12,'file')
84+
mod.add(hexsha,Tree.blob_id<<12,'file.second')
85+
mod.add(hexsha,Tree.blob_id<<12,'filf')
86+
87+
defnames_in_mod_cache():
88+
return [t[2]fortinmod._cache]
89+
90+
defchunk_from(a,name,size):
91+
index=a.index(name)
92+
returna[index:index+size]
93+
94+
assertchunk_from(names_in_mod_cache(),'fild',4)== ['fild','file','file.second',
95+
'filf']
96+
8097
# have added one item, we are done
8198
mod.set_done()
8299
mod.set_done()# multiple times are okay
83100

101+
assertchunk_from(names_in_mod_cache(),'fild',4)== ['fild','file.second','file',
102+
'filf']
103+
84104
# serialize, its different now
85105
stream=BytesIO()
86106
testtree._serialize(stream)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp