Skip to content

Commit d28c20b

Browse files
authored
Merge pull request #1799 from et-repositories/main
fix: treeNotSorted issue
2 parents 6978325 + bda5a17 commit d28c20b

File tree

3 files changed

+60
-49
lines changed

3 files changed

+60
-49
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,6 @@ Contributors are:
5353
-Santos Gallegos <stsewd _at_ proton.me>
5454
-Wenhan Zhu <wzhu.cosmos _at_ gmail.com>
5555
-Eliah Kagan <eliah.kagan _at_ gmail.com>
56+
-Ethan Lin <et.repositories _at_ gmail.com>
5657

5758
Portions derived from other open source works and are clearly marked.

git/objects/tree.py

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -53,54 +53,6 @@
5353
__all__ = ("TreeModifier", "Tree")
5454

5555

56-
def git_cmp(t1: TreeCacheTup, t2: TreeCacheTup) -> int:
57-
a, b = t1[2], t2[2]
58-
# assert isinstance(a, str) and isinstance(b, str)
59-
len_a, len_b = len(a), len(b)
60-
min_len = min(len_a, len_b)
61-
min_cmp = cmp(a[:min_len], b[:min_len])
62-
63-
if min_cmp:
64-
return min_cmp
65-
66-
return len_a - len_b
67-
68-
69-
def merge_sort(a: List[TreeCacheTup], cmp: Callable[[TreeCacheTup, TreeCacheTup], int]) -> None:
70-
if len(a) < 2:
71-
return
72-
73-
mid = len(a) // 2
74-
lefthalf = a[:mid]
75-
righthalf = a[mid:]
76-
77-
merge_sort(lefthalf, cmp)
78-
merge_sort(righthalf, cmp)
79-
80-
i = 0
81-
j = 0
82-
k = 0
83-
84-
while i < len(lefthalf) and j < len(righthalf):
85-
if cmp(lefthalf[i], righthalf[j]) <= 0:
86-
a[k] = lefthalf[i]
87-
i = i + 1
88-
else:
89-
a[k] = righthalf[j]
90-
j = j + 1
91-
k = k + 1
92-
93-
while i < len(lefthalf):
94-
a[k] = lefthalf[i]
95-
i = i + 1
96-
k = k + 1
97-
98-
while j < len(righthalf):
99-
a[k] = righthalf[j]
100-
j = j + 1
101-
k = k + 1
102-
103-
10456
class TreeModifier:
10557
"""A utility class providing methods to alter the underlying cache in a list-like fashion.
10658
@@ -131,7 +83,7 @@ def set_done(self) -> "TreeModifier":
13183
13284
:return self:
13385
"""
134-
merge_sort(self._cache, git_cmp)
86+
self._cache.sort(key=lambda x: (x[2] + "/") if x[1] == Tree.tree_id << 12 else x[2])
13587
return self
13688

13789
# } END interface

test/test_tree.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from git.objects import Tree, Blob
99
from test.lib import TestBase
1010

11+
import os
1112
import os.path as osp
13+
import subprocess
1214

1315

1416
class TestTree(TestBase):
@@ -40,6 +42,62 @@ def test_serializable(self):
4042
testtree._deserialize(stream)
4143
# END for each item in tree
4244

45+
def test_tree_modifier_ordering(self):
46+
def setup_git_repository_and_get_ordered_files():
47+
os.mkdir("tmp")
48+
os.chdir("tmp")
49+
subprocess.run(["git", "init", "-q"], check=True)
50+
os.mkdir("file")
51+
for filename in [
52+
"bin",
53+
"bin.d",
54+
"file.to",
55+
"file.toml",
56+
"file.toml.bin",
57+
"file0",
58+
"file/a",
59+
]:
60+
open(filename, "a").close()
61+
62+
subprocess.run(["git", "add", "."], check=True)
63+
subprocess.run(["git", "commit", "-m", "c1"], check=True)
64+
tree_hash = subprocess.check_output(["git", "rev-parse", "HEAD^{tree}"]).decode().strip()
65+
cat_file_output = subprocess.check_output(["git", "cat-file", "-p", tree_hash]).decode()
66+
return [line.split()[-1] for line in cat_file_output.split("\n") if line]
67+
68+
hexsha = "6c1faef799095f3990e9970bc2cb10aa0221cf9c"
69+
roottree = self.rorepo.tree(hexsha)
70+
blob_mode = Tree.blob_id << 12
71+
tree_mode = Tree.tree_id << 12
72+
73+
files_in_desired_order = [
74+
(blob_mode, "bin"),
75+
(blob_mode, "bin.d"),
76+
(blob_mode, "file.to"),
77+
(blob_mode, "file.toml"),
78+
(blob_mode, "file.toml.bin"),
79+
(blob_mode, "file0"),
80+
(tree_mode, "file"),
81+
]
82+
mod = roottree.cache
83+
for file_mode, file_name in files_in_desired_order:
84+
mod.add(hexsha, file_mode, file_name)
85+
# end for each file
86+
87+
def file_names_in_order():
88+
return [t[1] for t in files_in_desired_order]
89+
90+
def names_in_mod_cache():
91+
a = [t[2] for t in mod._cache]
92+
here = file_names_in_order()
93+
return [e for e in a if e in here]
94+
95+
git_file_names_in_order = setup_git_repository_and_get_ordered_files()
96+
os.chdir("..")
97+
98+
mod.set_done()
99+
assert names_in_mod_cache() == git_file_names_in_order, "set_done() performs git-sorting"
100+
43101
def test_traverse(self):
44102
root = self.rorepo.tree("0.1.6")
45103
num_recursive = 0

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy