Show More
@@ -316,17 +316,17 b' def pack_dirstate(map, copy_map, now):' | |||||
316 | # Determine if the next entry is in the same sub-tree, if so don't |
|
316 | # Determine if the next entry is in the same sub-tree, if so don't | |
317 | # pack yet |
|
317 | # pack yet | |
318 | next_path = sorted_map[index][0] |
|
318 | next_path = sorted_map[index][0] | |
319 |
should_pack = not |
|
319 | should_pack = not is_ancestor(next_path, current_folder) | |
320 | if should_pack: |
|
320 | if should_pack: | |
321 | pack_directory_children(current_node, copy_map, data, stack) |
|
321 | pack_directory_children(current_node, copy_map, data, stack) | |
322 | while stack and current_node.path != b"": |
|
322 | while stack and current_node.path != b"": | |
323 | # Go up the tree and write until we reach the folder of the next |
|
323 | # Go up the tree and write until we reach the folder of the next | |
324 | # entry (if any, otherwise the root) |
|
324 | # entry (if any, otherwise the root) | |
325 | parent = current_node.parent |
|
325 | parent = current_node.parent | |
326 |
in_ |
|
326 | in_ancestor_of_next_path = next_path is not None and ( | |
327 |
|
|
327 | is_ancestor(next_path, get_folder(stack[-1].path)) | |
328 | ) |
|
328 | ) | |
329 |
if parent is None or in_ |
|
329 | if parent is None or in_ancestor_of_next_path: | |
330 | break |
|
330 | break | |
331 | pack_directory_children(parent, copy_map, data, stack) |
|
331 | pack_directory_children(parent, copy_map, data, stack) | |
332 | current_node = parent |
|
332 | current_node = parent | |
@@ -357,13 +357,34 b' def get_folder(path):' | |||||
357 | return path.rsplit(b'/', 1)[0] if b'/' in path else b'' |
|
357 | return path.rsplit(b'/', 1)[0] if b'/' in path else b'' | |
358 |
|
358 | |||
359 |
|
359 | |||
|
360 | def is_ancestor(path, maybe_ancestor): | |||
|
361 | """Returns whether `maybe_ancestor` is an ancestor of `path`. | |||
|
362 | ||||
|
363 | >>> is_ancestor(b"a", b"") | |||
|
364 | True | |||
|
365 | >>> is_ancestor(b"a/b/c", b"a/b/c") | |||
|
366 | False | |||
|
367 | >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext") | |||
|
368 | False | |||
|
369 | >>> is_ancestor(b"hgext3rd/__init__.py", b"hgext3rd") | |||
|
370 | True | |||
|
371 | """ | |||
|
372 | if maybe_ancestor == b"": | |||
|
373 | return True | |||
|
374 | if path <= maybe_ancestor: | |||
|
375 | return False | |||
|
376 | path_components = path.split(b"/") | |||
|
377 | ancestor_components = maybe_ancestor.split(b"/") | |||
|
378 | return all(c == o for c, o in zip(path_components, ancestor_components)) | |||
|
379 | ||||
|
380 | ||||
360 | def move_to_correct_node_in_tree(target_folder, current_node, stack): |
|
381 | def move_to_correct_node_in_tree(target_folder, current_node, stack): | |
361 | """ |
|
382 | """ | |
362 | Move inside the dirstate node tree to the node corresponding to |
|
383 | Move inside the dirstate node tree to the node corresponding to | |
363 | `target_folder`, creating the missing nodes along the way if needed. |
|
384 | `target_folder`, creating the missing nodes along the way if needed. | |
364 | """ |
|
385 | """ | |
365 | while target_folder != current_node.path: |
|
386 | while target_folder != current_node.path: | |
366 |
if target_folder |
|
387 | if is_ancestor(target_folder, current_node.path): | |
367 | # We need to go down a folder |
|
388 | # We need to go down a folder | |
368 | prefix = target_folder[len(current_node.path) :].lstrip(b'/') |
|
389 | prefix = target_folder[len(current_node.path) :].lstrip(b'/') | |
369 | subfolder_name = prefix.split(b'/', 1)[0] |
|
390 | subfolder_name = prefix.split(b'/', 1)[0] |
@@ -103,3 +103,21 b' coherent (issue4353)' | |||||
103 | 1 |
|
103 | 1 | |
104 | $ hg status |
|
104 | $ hg status | |
105 | ? a |
|
105 | ? a | |
|
106 | ||||
|
107 | #if dirstate-v2 | |||
|
108 | Check that folders that are prefixes of others do not throw the packer into an | |||
|
109 | infinite loop. | |||
|
110 | ||||
|
111 | $ cd .. | |||
|
112 | $ hg init infinite-loop | |||
|
113 | $ cd infinite-loop | |||
|
114 | $ mkdir hgext3rd hgext | |||
|
115 | $ touch hgext3rd/__init__.py hgext/zeroconf.py | |||
|
116 | $ hg commit -Aqm0 | |||
|
117 | ||||
|
118 | $ hg st -c | |||
|
119 | C hgext/zeroconf.py | |||
|
120 | C hgext3rd/__init__.py | |||
|
121 | ||||
|
122 | $ cd .. | |||
|
123 | #endif |
@@ -132,6 +132,7 b' expected_mods_tested = set(' | |||||
132 | ('mercurial.cmdutil', '{}'), |
|
132 | ('mercurial.cmdutil', '{}'), | |
133 | ('mercurial.color', '{}'), |
|
133 | ('mercurial.color', '{}'), | |
134 | ('mercurial.dagparser', "{'optionflags': 4}"), |
|
134 | ('mercurial.dagparser', "{'optionflags': 4}"), | |
|
135 | ('mercurial.dirstateutils.v2', '{}'), | |||
135 | ('mercurial.encoding', '{}'), |
|
136 | ('mercurial.encoding', '{}'), | |
136 | ('mercurial.fancyopts', '{}'), |
|
137 | ('mercurial.fancyopts', '{}'), | |
137 | ('mercurial.formatter', '{}'), |
|
138 | ('mercurial.formatter', '{}'), |
General Comments 0
You need to be logged in to leave comments.
Login now