[Updated] D12170: dirstate-v2: fix infinite loop in pure packer
Alphare (Raphaël Gomès)
phabricator at mercurial-scm.org
Tue Feb 15 15:17:48 UTC 2022
Closed by commit rHG46d12f7762e4: dirstate-v2: fix infinite loop in pure packer (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D12170?vs=32150&id=32211
CHANGES SINCE LAST ACTION
https://phab.mercurial-scm.org/D12170/new/
REVISION DETAIL
https://phab.mercurial-scm.org/D12170
AFFECTED FILES
mercurial/dirstateutils/v2.py
tests/test-dirstate.t
tests/test-doctest.py
CHANGE DETAILS
diff --git a/tests/test-doctest.py b/tests/test-doctest.py
--- a/tests/test-doctest.py
+++ b/tests/test-doctest.py
@@ -132,6 +132,7 @@
('mercurial.cmdutil', '{}'),
('mercurial.color', '{}'),
('mercurial.dagparser', "{'optionflags': 4}"),
+ ('mercurial.dirstateutils.v2', '{}'),
('mercurial.encoding', '{}'),
('mercurial.fancyopts', '{}'),
('mercurial.formatter', '{}'),
diff --git a/tests/test-dirstate.t b/tests/test-dirstate.t
--- a/tests/test-dirstate.t
+++ b/tests/test-dirstate.t
@@ -103,3 +103,21 @@
1
$ hg status
? a
+
+#if dirstate-v2
+Check that folders that are prefixes of others do not throw the packer into an
+infinite loop.
+
+ $ cd ..
+ $ hg init infinite-loop
+ $ cd infinite-loop
+ $ mkdir hgext3rd hgext
+ $ touch hgext3rd/__init__.py hgext/zeroconf.py
+ $ hg commit -Aqm0
+
+ $ hg st -c
+ C hgext/zeroconf.py
+ C hgext3rd/__init__.py
+
+ $ cd ..
+#endif
diff --git a/mercurial/dirstateutils/v2.py b/mercurial/dirstateutils/v2.py
--- a/mercurial/dirstateutils/v2.py
+++ b/mercurial/dirstateutils/v2.py
@@ -316,17 +316,17 @@
# Determine if the next entry is in the same sub-tree, if so don't
# pack yet
next_path = sorted_map[index][0]
- should_pack = not get_folder(next_path).startswith(current_folder)
+ should_pack = not is_ancestor(next_path, current_folder)
if should_pack:
pack_directory_children(current_node, copy_map, data, stack)
while stack and current_node.path != b"":
# Go up the tree and write until we reach the folder of the next
# entry (if any, otherwise the root)
parent = current_node.parent
- in_parent_folder_of_next_entry = next_path is not None and (
- get_folder(next_path).startswith(get_folder(stack[-1].path))
+ in_ancestor_of_next_path = next_path is not None and (
+ is_ancestor(next_path, get_folder(stack[-1].path))
)
- if parent is None or in_parent_folder_of_next_entry:
+ if parent is None or in_ancestor_of_next_path:
break
pack_directory_children(parent, copy_map, data, stack)
current_node = parent
@@ -357,13 +357,34 @@
return path.rsplit(b'/', 1)[0] if b'/' in path else b''
+def is_ancestor(path, maybe_ancestor):
+ """Returns whether `maybe_ancestor` is an ancestor of `path`.
+
+ >>> is_ancestor(b"a", b"")
+ True
+ >>> is_ancestor(b"a/b/c", b"a/b/c")
+ False
+ >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext")
+ False
+ >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext3rd")
+ True
+ """
+ if maybe_ancestor == b"":
+ return True
+ if path <= maybe_ancestor:
+ return False
+ path_components = path.split(b"/")
+ ancestor_components = maybe_ancestor.split(b"/")
+ return all(c == o for c, o in zip(path_components, ancestor_components))
+
+
def move_to_correct_node_in_tree(target_folder, current_node, stack):
"""
Move inside the dirstate node tree to the node corresponding to
`target_folder`, creating the missing nodes along the way if needed.
"""
while target_folder != current_node.path:
- if target_folder.startswith(current_node.path):
+ if is_ancestor(target_folder, current_node.path):
# We need to go down a folder
prefix = target_folder[len(current_node.path) :].lstrip(b'/')
subfolder_name = prefix.split(b'/', 1)[0]
To: Alphare, #hg-reviewers, SimonSapin
Cc: mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20220215/90cfa98f/attachment-0002.html>
More information about the Mercurial-patches
mailing list