[PATCH 2 of 7 v2] merge: change priority / ordering of merge actions
Mads Kiilerich
mads at kiilerich.com
Fri May 9 00:06:06 UTC 2014
# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1398985754 -7200
# Fri May 02 01:09:14 2014 +0200
# Node ID 8b9f6a2e0d19791662c8c8544594a74c0d0d4276
# Parent b987a7a84823bf808939e4ac1838a5c963f510cd
merge: change priority / ordering of merge actions
The ordering of actions matters. Normal file system semantics is that files
have to be removed before a directory with the same name can be created.
Before the first ordering key was to have 'r' and 'f' actions come first,
secondary key was the filename.
Because of future refactorings we want to consistently have all action types
(with a sensible priority) as separate first keys. Grouped by action type, we
sort by filename.
Not processing in strict filename order could give worse performance,
especially on spinning disks. That is however primarily an issue in the cases
where "all" actions are of the same kind and will be grouped together anyway.
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -551,8 +551,11 @@ def manifestmerge(repo, wctx, p2, pa, br
return actions
+actionpriority = dict((m, p) for p, m in enumerate(
+ ['r', 'g', 'f', 'a', 'k', 'm', 'dm', 'dg', 'dr', 'cd', 'dc', 'rd', 'e']))
+
def actionkey(a):
- return a[1] in "rf" and -1 or 0, a
+ return actionpriority[a[1]], a
def getremove(repo, mctx, overwrite, args):
"""apply usually-non-interactive updates to the working directory
@@ -828,16 +831,16 @@ def recordupdates(repo, actions, branchm
for a in actions:
f, m, args, msg = a
- if m == "r": # remove
+ if m == "r": # remove (must come first)
if branchmerge:
repo.dirstate.remove(f)
else:
repo.dirstate.drop(f)
+ elif m == "f": # forget (must come first)
+ repo.dirstate.drop(f)
elif m == "a": # re-add
if not branchmerge:
repo.dirstate.add(f)
- elif m == "f": # forget
- repo.dirstate.drop(f)
elif m == "e": # exec change
repo.dirstate.normallookup(f)
elif m == "k": # keep
diff --git a/tests/test-graft.t b/tests/test-graft.t
--- a/tests/test-graft.t
+++ b/tests/test-graft.t
@@ -150,8 +150,8 @@ Graft out of order, skipping a merge and
resolving manifests
branchmerge: True, force: True, partial: False
ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
+ e: remote is newer -> g
b: keep -> k
- e: remote is newer -> g
getting e
updating: e 1/1 files (100.00%)
e
@@ -160,8 +160,8 @@ Graft out of order, skipping a merge and
resolving manifests
branchmerge: True, force: True, partial: False
ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
+ d: remote is newer -> g
b: keep -> k
- d: remote is newer -> g
e: versions differ -> m
preserving e for resolve of e
getting d
diff --git a/tests/test-merge-criss-cross.t b/tests/test-merge-criss-cross.t
--- a/tests/test-merge-criss-cross.t
+++ b/tests/test-merge-criss-cross.t
@@ -196,8 +196,8 @@ The other way around:
f2: picking 'get' action
end of auction
+ f2: remote is newer -> g
f1: keep -> k
- f2: remote is newer -> g
getting f2
updating: f2 1/1 files (100.00%)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
diff --git a/tests/test-rename-merge1.t b/tests/test-rename-merge1.t
--- a/tests/test-rename-merge1.t
+++ b/tests/test-rename-merge1.t
@@ -36,22 +36,22 @@
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
- a2: divergent renames -> dr
+ b2: remote created -> g
b: remote moved from a -> m
preserving a for resolve of b
- b2: remote created -> g
+ a2: divergent renames -> dr
removing a
getting b2
updating: b2 1/3 files (33.33%)
- updating: a2 2/3 files (66.67%)
- note: possible conflict - a2 was renamed multiple times to:
- c2
- b2
- updating: b 3/3 files (100.00%)
+ updating: b 2/3 files (66.67%)
picked tool 'internal:merge' for b (binary False symlink False)
merging a and b to b
my b at 044f8520aeeb+ other b at 85c198ef2f6c ancestor a at af1939970a1c
premerge successful
+ updating: a2 3/3 files (100.00%)
+ note: possible conflict - a2 was renamed multiple times to:
+ c2
+ b2
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
@@ -181,8 +181,8 @@ Check for issue3074
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
+ newfile: remote created -> g
file: rename and delete -> rd
- newfile: remote created -> g
getting newfile
updating: newfile 1/2 files (50.00%)
updating: file 2/2 files (100.00%)
diff --git a/tests/test-rename-merge2.t b/tests/test-rename-merge2.t
--- a/tests/test-rename-merge2.t
+++ b/tests/test-rename-merge2.t
@@ -379,20 +379,20 @@ m "um a c" "um x c" " " "10 do merg
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
- a: divergent renames -> dr
c: remote created -> g
rev: versions differ -> m
preserving rev for resolve of rev
+ a: divergent renames -> dr
getting c
updating: c 1/3 files (33.33%)
- updating: a 2/3 files (66.67%)
+ updating: rev 2/3 files (66.67%)
+ picked tool 'python ../merge' for rev (binary False symlink False)
+ merging rev
+ my rev at 02963e448370+ other rev at fe905ef2c33e ancestor rev at 924404dff337
+ updating: a 3/3 files (100.00%)
note: possible conflict - a was renamed multiple times to:
b
c
- updating: rev 3/3 files (100.00%)
- picked tool 'python ../merge' for rev (binary False symlink False)
- merging rev
- my rev at 02963e448370+ other rev at fe905ef2c33e ancestor rev at 924404dff337
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
--------------
@@ -746,9 +746,9 @@ m "nm a b" "um x a" " " "22 get a,
resolving manifests
branchmerge: True, force: False, partial: False
ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
+ c: remote created -> g
b: local copied/moved from a -> m
preserving b for resolve of b
- c: remote created -> g
rev: versions differ -> m
preserving rev for resolve of rev
getting c
@@ -836,6 +836,7 @@ 8 f (f) f f "remote differs from
ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
remote changed 8/f which local deleted
use (c)hanged version or leave (d)eleted? c
+ 8/f: prompt recreating -> g
0/f: versions differ -> m
preserving 0/f for resolve of 0/f
1/g: versions differ -> m
@@ -856,7 +857,6 @@ 8 f (f) f f "remote differs from
preserving 6/g for resolve of 6/g
7/f: remote differs from untracked local -> m
preserving 7/f for resolve of 7/f
- 8/f: prompt recreating -> g
removing 4/f
getting 8/f
$ hg mani
diff --git a/tests/test-up-local-change.t b/tests/test-up-local-change.t
--- a/tests/test-up-local-change.t
+++ b/tests/test-up-local-change.t
@@ -46,9 +46,9 @@
resolving manifests
branchmerge: False, force: False, partial: False
ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
+ b: remote created -> g
a: versions differ -> m
preserving a for resolve of a
- b: remote created -> g
getting b
updating: b 1/2 files (50.00%)
updating: a 2/2 files (100.00%)
@@ -100,9 +100,9 @@
resolving manifests
branchmerge: False, force: False, partial: False
ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
+ b: remote created -> g
a: versions differ -> m
preserving a for resolve of a
- b: remote created -> g
getting b
updating: b 1/2 files (50.00%)
updating: a 2/2 files (100.00%)
More information about the Mercurial-devel
mailing list