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

Appearance settings

Commit d344abf

Browse filesBrowse files
committed
Fix traverse_trees_recursive()
1 parent fe5fef9 commit d344abf
Copy full SHA for d344abf

2 files changed

+73-83Lines changed: 73 additions & 83 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎git/index/fun.py‎

Copy file name to clipboardExpand all lines: git/index/fun.py
+69-79Lines changed: 69 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
S_IFREG,
1414
S_IXUSR,
1515
)
16-
1716
import subprocess
1817

1918
from git.cmd import PROC_CREATIONFLAGS, handle_process_output
@@ -58,11 +57,7 @@
5857

5958
if TYPE_CHECKING:
6059
from .base import IndexFile
61-
from git.objects.fun import EntryTupOrNone
62-
63-
64-
def is_three_entry_list(inp) -> TypeGuard[List['EntryTupOrNone']]:
65-
return isinstance(inp, (tuple, list)) and len(inp) == 3
60+
# from git.objects.fun import EntryTupOrNone
6661

6762
# ------------------------------------------------------------------------------------
6863

@@ -192,16 +187,16 @@ def entry_key(*entry: Union[BaseIndexEntry, PathLike, int]) -> Tuple[PathLike, i
192187
""":return: Key suitable to be used for the index.entries dictionary
193188
:param entry: One instance of type BaseIndexEntry or the path and the stage"""
194189

195-
def is_entry_tuple(entry: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
196-
return isinstance(entry, tuple) and len(entry) == 2
190+
def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
191+
return isinstance(entry_key, tuple) and len(entry_key) == 2
197192

198193
if len(entry) == 1:
199194
entry_first = entry[0]
200195
assert isinstance(entry_first, BaseIndexEntry)
201196
return (entry_first.path, entry_first.stage)
202197
else:
203198
# entry = tuple(entry)
204-
assert is_entry_tuple(entry)
199+
assert is_entry_key_tup(entry)
205200
return entry
206201
# END handle entry
207202

@@ -340,79 +335,74 @@ def aggressive_tree_merge(odb, tree_shas: Sequence[bytes]) -> List[BaseIndexEntr
340335
raise ValueError("Cannot handle %i trees at once" % len(tree_shas))
341336

342337
# three trees
343-
entries = traverse_trees_recursive(odb, tree_shas, '')
344-
base = entries[0]
345-
ours = entries[1]
346-
theirs = entries[2]
347-
assert is_three_entry_list(entries), f"{type(entries)=} and {len(entries)=}" # type:ignore
348-
349-
if base is not None:
350-
# base version exists
351-
if ours is not None:
352-
# ours exists
353-
if theirs is not None:
354-
# it exists in all branches, if it was changed in both
355-
# its a conflict, otherwise we take the changed version
356-
# This should be the most common branch, so it comes first
357-
if(base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or \
358-
(base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]):
359-
# changed by both
360-
out.append(_tree_entry_to_baseindexentry(base, 1))
361-
out.append(_tree_entry_to_baseindexentry(ours, 2))
362-
out.append(_tree_entry_to_baseindexentry(theirs, 3))
363-
elif base[0] != ours[0] or base[1] != ours[1]:
364-
# only we changed it
365-
out.append(_tree_entry_to_baseindexentry(ours, 0))
338+
for base, ours, theirs in traverse_trees_recursive(odb, tree_shas, ''):
339+
if base is not None:
340+
# base version exists
341+
if ours is not None:
342+
# ours exists
343+
if theirs is not None:
344+
# it exists in all branches, if it was changed in both
345+
# its a conflict, otherwise we take the changed version
346+
# This should be the most common branch, so it comes first
347+
if(base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or \
348+
(base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]):
349+
# changed by both
350+
out.append(_tree_entry_to_baseindexentry(base, 1))
351+
out.append(_tree_entry_to_baseindexentry(ours, 2))
352+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
353+
elif base[0] != ours[0] or base[1] != ours[1]:
354+
# only we changed it
355+
out.append(_tree_entry_to_baseindexentry(ours, 0))
356+
else:
357+
# either nobody changed it, or they did. In either
358+
# case, use theirs
359+
out.append(_tree_entry_to_baseindexentry(theirs, 0))
360+
# END handle modification
366361
else:
367-
# either nobody changed it, or they did. In either
368-
# case, use theirs
369-
out.append(_tree_entry_to_baseindexentry(theirs, 0))
370-
# END handle modification
371-
else:
372362

373-
if ours[0] != base[0] or ours[1] != base[1]:
374-
# they deleted it, we changed it, conflict
375-
out.append(_tree_entry_to_baseindexentry(base, 1))
376-
out.append(_tree_entry_to_baseindexentry(ours, 2))
377-
# else:
378-
# we didn't change it, ignore
379-
# pass
380-
# END handle our change
381-
# END handle theirs
382-
else:
383-
if theirs is None:
384-
# deleted in both, its fine - its out
385-
pass
363+
if ours[0] != base[0] or ours[1] != base[1]:
364+
# they deleted it, we changed it, conflict
365+
out.append(_tree_entry_to_baseindexentry(base, 1))
366+
out.append(_tree_entry_to_baseindexentry(ours, 2))
367+
# else:
368+
# we didn't change it, ignore
369+
# pass
370+
# END handle our change
371+
# END handle theirs
386372
else:
387-
if theirs[0] != base[0] or theirs[1] != base[1]:
388-
# deleted in ours, changed theirs, conflict
389-
out.append(_tree_entry_to_baseindexentry(base, 1))
390-
out.append(_tree_entry_to_baseindexentry(theirs, 3))
391-
# END theirs changed
392-
# else:
393-
# theirs didn't change
394-
# pass
395-
# END handle theirs
396-
# END handle ours
397-
else:
398-
# all three can't be None
399-
if ours is None and theirs is not None:
400-
# added in their branch
401-
out.append(_tree_entry_to_baseindexentry(theirs, 0))
402-
elif theirs is None and ours is not None:
403-
# added in our branch
404-
out.append(_tree_entry_to_baseindexentry(ours, 0))
405-
elif ours is not None and theirs is not None:
406-
# both have it, except for the base, see whether it changed
407-
if ours[0] != theirs[0] or ours[1] != theirs[1]:
408-
out.append(_tree_entry_to_baseindexentry(ours, 2))
409-
out.append(_tree_entry_to_baseindexentry(theirs, 3))
410-
else:
411-
# it was added the same in both
373+
if theirs is None:
374+
# deleted in both, its fine - its out
375+
pass
376+
else:
377+
if theirs[0] != base[0] or theirs[1] != base[1]:
378+
# deleted in ours, changed theirs, conflict
379+
out.append(_tree_entry_to_baseindexentry(base, 1))
380+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
381+
# END theirs changed
382+
# else:
383+
# theirs didn't change
384+
# pass
385+
# END handle theirs
386+
# END handle ours
387+
else:
388+
# all three can't be None
389+
if ours is None and theirs is not None:
390+
# added in their branch
391+
out.append(_tree_entry_to_baseindexentry(theirs, 0))
392+
elif theirs is None and ours is not None:
393+
# added in our branch
412394
out.append(_tree_entry_to_baseindexentry(ours, 0))
413-
# END handle two items
414-
# END handle heads
415-
# END handle base exists
416-
# END for each entries tuple
395+
elif ours is not None and theirs is not None:
396+
# both have it, except for the base, see whether it changed
397+
if ours[0] != theirs[0] or ours[1] != theirs[1]:
398+
out.append(_tree_entry_to_baseindexentry(ours, 2))
399+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
400+
else:
401+
# it was added the same in both
402+
out.append(_tree_entry_to_baseindexentry(ours, 0))
403+
# END handle two items
404+
# END handle heads
405+
# END handle base exists
406+
# END for each entries tuple
417407

418408
return out
Collapse file

‎git/objects/fun.py‎

Copy file name to clipboardExpand all lines: git/objects/fun.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ def _to_full_path(item: EntryTupOrNone, path_prefix: str) -> EntryTupOrNone:
144144

145145

146146
def traverse_trees_recursive(odb: 'GitCmdObjectDB', tree_shas: Sequence[Union[bytes, None]],
147-
path_prefix: str) -> List[EntryTupOrNone]:
147+
path_prefix: str) -> List[List[EntryTupOrNone]]:
148148
"""
149-
:return: list with entries according to the given binary tree-shas.
149+
:return: list of list with entries according to the given binary tree-shas.
150150
The result is encoded in a list
151151
of n tuple|None per blob/commit, (n == len(tree_shas)), where
152152
* [0] == 20 byte sha
@@ -170,7 +170,7 @@ def traverse_trees_recursive(odb: 'GitCmdObjectDB', tree_shas: Sequence[Union[by
170170
trees_data.append(data)
171171
# END for each sha to get data for
172172

173-
out = []
173+
out: List[List[EntryTupOrNone]] = []
174174

175175
# find all matching entries and recursively process them together if the match
176176
# is a tree. If the match is a non-tree item, put it into the result.
@@ -201,7 +201,7 @@ def traverse_trees_recursive(odb: 'GitCmdObjectDB', tree_shas: Sequence[Union[by
201201
out.extend(traverse_trees_recursive(
202202
odb, [((ei and ei[0]) or None) for ei in entries], path_prefix + name + '/'))
203203
else:
204-
out.extend([_to_full_path(e, path_prefix) for e in entries])
204+
out.append([_to_full_path(e, path_prefix) for e in entries])
205205

206206
# END handle recursion
207207
# finally mark it done

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.