Mercurial > hg > mercurial-crew-with-dirclash
annotate mercurial/merge.py @ 4307:c8919eb0f315
purge: abort with missing files avoiding problems with name-mangling fs
In a name mangling filesystem (e.g. a case insensitive one)
dirstate.walk() can yield filenames different from the ones
stored in the dirstate. This already confuses the status and
add commands, but with purge this may cause data loss.
To prevent this purge refuses to work if there are missing
files and has a 'force' option if the user knows it is safe.
Even with the force option purge checks if any of the missing
files is still available in the working dir: if so there
may be some problem with the underlying filesystem, so it
unconditionally aborts.
author | Emanuele Aina <em@nerd.ocracy.org> |
---|---|
date | Wed, 28 Mar 2007 21:34:12 +0200 |
parents | 0d51eb296fb9 |
children | 09c5f734ff6a |
rev | line source |
---|---|
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # merge.py - directory-level update/merge handling for Mercurial |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
8 from node import * |
3893 | 9 from i18n import _ |
3886
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
3885
diff
changeset
|
10 import errno, util, os, tempfile |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
11 |
3315
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
12 def filemerge(repo, fw, fo, wctx, mctx): |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
13 """perform a 3-way merge in the working directory |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
14 |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
15 fw = filename in the working directory |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
16 fo = filename in other parent |
3303
69b9471f26bb
merge: pass contexts to applyupdates
Matt Mackall <mpm@selenic.com>
parents:
3302
diff
changeset
|
17 wctx, mctx = working and merge changecontexts |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
18 """ |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
19 |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
20 def temp(prefix, ctx): |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
21 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 (fd, name) = tempfile.mkstemp(prefix=pre) |
4005
656e06eebda7
replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents:
3893
diff
changeset
|
23 data = repo.wwritedata(ctx.path(), ctx.data()) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
24 f = os.fdopen(fd, "wb") |
4005
656e06eebda7
replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents:
3893
diff
changeset
|
25 f.write(data) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 f.close() |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
27 return name |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
28 |
3305
e7abcf3a7c5f
filemerge: use contexts rather than my and other
Matt Mackall <mpm@selenic.com>
parents:
3303
diff
changeset
|
29 fcm = wctx.filectx(fw) |
e7abcf3a7c5f
filemerge: use contexts rather than my and other
Matt Mackall <mpm@selenic.com>
parents:
3303
diff
changeset
|
30 fco = mctx.filectx(fo) |
3317
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
31 |
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
32 if not fco.cmp(fcm.data()): # files identical? |
3407
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
33 return None |
3317
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
34 |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
35 fca = fcm.ancestor(fco) |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
36 if not fca: |
3578
3b4e00cba57a
Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3442
diff
changeset
|
37 fca = repo.filectx(fw, fileid=nullrev) |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
38 a = repo.wjoin(fw) |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
39 b = temp("base", fca) |
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
40 c = temp("other", fco) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
41 |
3317
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
42 if fw != fo: |
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
43 repo.ui.status(_("merging %s and %s\n") % (fw, fo)) |
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
44 else: |
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
45 repo.ui.status(_("merging %s\n") % fw) |
966632304dde
merge: shortcircuit filemerge for identical files
Matt Mackall <mpm@selenic.com>
parents:
3315
diff
changeset
|
46 |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
47 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca)) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
48 |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
49 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge") |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
50 or "hgmerge") |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
51 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root, |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
52 environ={'HG_FILE': fw, |
3303
69b9471f26bb
merge: pass contexts to applyupdates
Matt Mackall <mpm@selenic.com>
parents:
3302
diff
changeset
|
53 'HG_MY_NODE': str(wctx.parents()[0]), |
69b9471f26bb
merge: pass contexts to applyupdates
Matt Mackall <mpm@selenic.com>
parents:
3302
diff
changeset
|
54 'HG_OTHER_NODE': str(mctx)}) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
55 if r: |
3233
3fd098e0902d
merge: extend file merge function for renames
Matt Mackall <mpm@selenic.com>
parents:
3202
diff
changeset
|
56 repo.ui.warn(_("merging %s failed!\n") % fw) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
57 |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
58 os.unlink(b) |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
59 os.unlink(c) |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
60 return r |
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
61 |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
62 def checkunknown(wctx, mctx): |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
63 "check for collisions between unknown files and files in mctx" |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
64 man = mctx.manifest() |
3240
8d4855fd9d7b
merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents:
3234
diff
changeset
|
65 for f in wctx.unknown(): |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
66 if f in man: |
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
67 if mctx.filectx(f).cmp(wctx.filectx(f).data()): |
3620
3109f012c305
Clarify untracked file merge message
Matt Mackall <mpm@selenic.com>
parents:
3593
diff
changeset
|
68 raise util.Abort(_("untracked local file '%s' differs"\ |
3109f012c305
Clarify untracked file merge message
Matt Mackall <mpm@selenic.com>
parents:
3593
diff
changeset
|
69 " from remote version") % f) |
3108
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
70 |
3786 | 71 def checkcollision(mctx): |
72 "check for case folding collisions in the destination context" | |
73 folded = {} | |
74 for fn in mctx.manifest(): | |
75 fold = fn.lower() | |
76 if fold in folded: | |
77 raise util.Abort(_("case-folding collision between %s and %s") | |
78 % (fn, folded[fold])) | |
79 folded[fold] = fn | |
80 | |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
81 def forgetremoved(wctx, mctx): |
3108
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
82 """ |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
83 Forget removed files |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
84 |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
85 If we're jumping between revisions (as opposed to merging), and if |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
86 neither the working directory nor the target rev has the file, |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
87 then we need to remove it from the dirstate, to prevent the |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
88 dirstate from listing the file when it is no longer in the |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
89 manifest. |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
90 """ |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
91 |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
92 action = [] |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
93 man = mctx.manifest() |
3240
8d4855fd9d7b
merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents:
3234
diff
changeset
|
94 for f in wctx.deleted() + wctx.removed(): |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
95 if f not in man: |
3108
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
96 action.append((f, "f")) |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
97 |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
98 return action |
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
99 |
3377
8c36b33a27c7
merge: turn followcopies on by default
Matt Mackall <mpm@selenic.com>
parents:
3323
diff
changeset
|
100 def findcopies(repo, m1, m2, ma, limit): |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
101 """ |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
102 Find moves and copies between m1 and m2 back to limit linkrev |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
103 """ |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
104 |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
105 def findold(fctx): |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
106 "find files that path was copied from, back to linkrev limit" |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
107 old = {} |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
108 orig = fctx.path() |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
109 visit = [fctx] |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
110 while visit: |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
111 fc = visit.pop() |
3881
c0a12e6441a5
Fix copy detection corner case
Matt Mackall <mpm@selenic.com>
parents:
3862
diff
changeset
|
112 if fc.path() != orig and fc.path() not in old: |
c0a12e6441a5
Fix copy detection corner case
Matt Mackall <mpm@selenic.com>
parents:
3862
diff
changeset
|
113 old[fc.path()] = 1 |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
114 if fc.rev() < limit: |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
115 continue |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
116 visit += fc.parents() |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
117 |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
118 old = old.keys() |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
119 old.sort() |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
120 return old |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
121 |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
122 def nonoverlap(d1, d2, d3): |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
123 "Return list of elements in d1 not in d2 or d3" |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
124 l = [d for d in d1 if d not in d3 and d not in d2] |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
125 l.sort() |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
126 return l |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
127 |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
128 def checkcopies(c, man): |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
129 '''check possible copies for filectx c''' |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
130 for of in findold(c): |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
131 if of not in man: |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
132 return |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
133 c2 = ctx(of, man[of]) |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
134 ca = c.ancestor(c2) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
135 if not ca: # unrelated |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
136 return |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
137 if ca.path() == c.path() or ca.path() == c2.path(): |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
138 fullcopy[c.path()] = of |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
139 if c == ca or c2 == ca: # no merge needed, ignore copy |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
140 return |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
141 copy[c.path()] = of |
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
142 |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
143 def dirs(files): |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
144 d = {} |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
145 for f in files: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
146 d[os.path.dirname(f)] = True |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
147 return d |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
148 |
3377
8c36b33a27c7
merge: turn followcopies on by default
Matt Mackall <mpm@selenic.com>
parents:
3323
diff
changeset
|
149 if not repo.ui.configbool("merge", "followcopies", True): |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
150 return {} |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
151 |
3161
1839e6e91c3a
findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents:
3157
diff
changeset
|
152 # avoid silly behavior for update from empty dir |
3731
b4af5f92e04b
merge: move check for empty ancestor into findcopies
Matt Mackall <mpm@selenic.com>
parents:
3730
diff
changeset
|
153 if not m1 or not m2 or not ma: |
3161
1839e6e91c3a
findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents:
3157
diff
changeset
|
154 return {} |
1839e6e91c3a
findcopies: shortcut for empty working dir
Matt Mackall <mpm@selenic.com>
parents:
3157
diff
changeset
|
155 |
3157
56c59ba7aa76
findcopies: use dirstate rename information
Matt Mackall <mpm@selenic.com>
parents:
3155
diff
changeset
|
156 dcopies = repo.dirstate.copies() |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
157 copy = {} |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
158 fullcopy = {} |
3377
8c36b33a27c7
merge: turn followcopies on by default
Matt Mackall <mpm@selenic.com>
parents:
3323
diff
changeset
|
159 u1 = nonoverlap(m1, m2, ma) |
8c36b33a27c7
merge: turn followcopies on by default
Matt Mackall <mpm@selenic.com>
parents:
3323
diff
changeset
|
160 u2 = nonoverlap(m2, m1, ma) |
3673
eb0b4a2d70a9
white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3620
diff
changeset
|
161 ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
162 |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
163 for f in u1: |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
164 checkcopies(ctx(dcopies.get(f, f), m1[f]), m2) |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
165 |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
166 for f in u2: |
3732
ffe9fef84801
merge: pull findcopies helpers inside, refactor checkpair to checkcopies
Matt Mackall <mpm@selenic.com>
parents:
3731
diff
changeset
|
167 checkcopies(ctx(f, m2[f]), m1) |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
168 |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
169 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
170 return copy |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
171 |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
172 # generate a directory move map |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
173 d1, d2 = dirs(m1), dirs(m2) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
174 invalid = {} |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
175 dirmove = {} |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
176 |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
177 for dst, src in fullcopy.items(): |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
178 dsrc, ddst = os.path.dirname(src), os.path.dirname(dst) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
179 if dsrc in invalid: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
180 continue |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
181 elif (dsrc in d1 and ddst in d1) or (dsrc in d2 and ddst in d2): |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
182 invalid[dsrc] = True |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
183 elif dsrc in dirmove and dirmove[dsrc] != ddst: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
184 invalid[dsrc] = True |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
185 del dirmove[dsrc] |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
186 else: |
4117
c95060a5391a
merge: fix renaming of subdirectories under renamed directories
Matt Mackall <mpm@selenic.com>
parents:
3881
diff
changeset
|
187 dirmove[dsrc + "/"] = ddst + "/" |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
188 |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
189 del d1, d2, invalid |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
190 |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
191 if not dirmove: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
192 return copy |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
193 |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
194 # check unaccounted nonoverlapping files |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
195 for f in u1 + u2: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
196 if f not in fullcopy: |
4117
c95060a5391a
merge: fix renaming of subdirectories under renamed directories
Matt Mackall <mpm@selenic.com>
parents:
3881
diff
changeset
|
197 for d in dirmove: |
c95060a5391a
merge: fix renaming of subdirectories under renamed directories
Matt Mackall <mpm@selenic.com>
parents:
3881
diff
changeset
|
198 if f.startswith(d): |
c95060a5391a
merge: fix renaming of subdirectories under renamed directories
Matt Mackall <mpm@selenic.com>
parents:
3881
diff
changeset
|
199 copy[f] = dirmove[d] + f[len(d):] |
c95060a5391a
merge: fix renaming of subdirectories under renamed directories
Matt Mackall <mpm@selenic.com>
parents:
3881
diff
changeset
|
200 break |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
201 |
3155
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
202 return copy |
c82ea81d6850
Add core copy detection algorithm
Matt Mackall <mpm@selenic.com>
parents:
3122
diff
changeset
|
203 |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
204 def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
205 """ |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
206 Merge p1 and p2 with ancestor ma and generate merge action list |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
207 |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
208 overwrite = whether we clobber working files |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
209 partial = function to filter file lists |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
210 """ |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
211 |
3320 | 212 repo.ui.note(_("resolving manifests\n")) |
213 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial))) | |
214 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2)) | |
215 | |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
216 m1 = p1.manifest() |
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
217 m2 = p2.manifest() |
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
218 ma = pa.manifest() |
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
219 backwards = (pa == p2) |
3320 | 220 action = [] |
221 copy = {} | |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
222 |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
223 def fmerge(f, f2=None, fa=None): |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
224 """merge flags""" |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
225 if not f2: |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
226 f2 = f |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
227 fa = f |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
228 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
229 if ((a^b) | (a^c)) ^ a: |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
230 return 'x' |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
231 a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2) |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
232 if ((a^b) | (a^c)) ^ a: |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
233 return 'l' |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
234 return '' |
3119
5644a05a608c
merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents:
3118
diff
changeset
|
235 |
3313
f009a6f12a59
merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents:
3312
diff
changeset
|
236 def act(msg, m, f, *args): |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
237 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) |
3122
2ef0b3aae186
merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents:
3121
diff
changeset
|
238 action.append((f, m) + args) |
2ef0b3aae186
merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents:
3121
diff
changeset
|
239 |
3731
b4af5f92e04b
merge: move check for empty ancestor into findcopies
Matt Mackall <mpm@selenic.com>
parents:
3730
diff
changeset
|
240 if not (backwards or overwrite): |
3377
8c36b33a27c7
merge: turn followcopies on by default
Matt Mackall <mpm@selenic.com>
parents:
3323
diff
changeset
|
241 copy = findcopies(repo, m1, m2, ma, pa.rev()) |
3730
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
242 copied = dict.fromkeys(copy.values()) |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
243 |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
244 # Compare manifests |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
245 for f, n in m1.iteritems(): |
3254
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
246 if partial and not partial(f): |
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
247 continue |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
248 if f in m2: |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
249 # are files different? |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
250 if n != m2[f]: |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
251 a = ma.get(f, nullid) |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
252 # are both different from the ancestor? |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
253 if not overwrite and n != a and m2[f] != a: |
3314
ecc1bf27378c
merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents:
3313
diff
changeset
|
254 act("versions differ", "m", f, f, f, fmerge(f), False) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
255 # are we clobbering? |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
256 # is remote's version newer? |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
257 # or are we going back in time and clean? |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
258 elif overwrite or m2[f] != a or (backwards and not n[20:]): |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
259 act("remote is newer", "g", f, m2.flags(f)) |
3114
d1d1cd5b9484
merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents:
3113
diff
changeset
|
260 # local is newer, not overwrite, check mode bits |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
261 elif fmerge(f) != m1.flags(f): |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
262 act("update permissions", "e", f, m2.flags(f)) |
3114
d1d1cd5b9484
merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents:
3113
diff
changeset
|
263 # contents same, check mode bits |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
264 elif m1.flags(f) != m2.flags(f): |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
265 if overwrite or fmerge(f) != m1.flags(f): |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
266 act("update permissions", "e", f, m2.flags(f)) |
3730
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
267 elif f in copied: |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
268 continue |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
269 elif f in copy: |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
270 f2 = copy[f] |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
271 if f2 not in m2: # directory rename |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
272 act("remote renamed directory to " + f2, "d", |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
273 f, None, f2, m1.flags(f)) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
274 elif f2 in m1: # case 2 A,B/B/B |
3730
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
275 act("local copied to " + f2, "m", |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
276 f, f2, f, fmerge(f, f2, f2), False) |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
277 else: # case 4,21 A/B/B |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
278 act("local moved to " + f2, "m", |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
279 f, f2, f, fmerge(f, f2, f2), False) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
280 elif f in ma: |
3118
7a635ef25132
merge: simplify tests for local changed/remote deleted
Matt Mackall <mpm@selenic.com>
parents:
3117
diff
changeset
|
281 if n != ma[f] and not overwrite: |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
282 if repo.ui.prompt( |
3118
7a635ef25132
merge: simplify tests for local changed/remote deleted
Matt Mackall <mpm@selenic.com>
parents:
3117
diff
changeset
|
283 (_(" local changed %s which remote deleted\n") % f) + |
3120
b1de36a4b4df
merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents:
3119
diff
changeset
|
284 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"): |
3313
f009a6f12a59
merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents:
3312
diff
changeset
|
285 act("prompt delete", "r", f) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
286 else: |
3313
f009a6f12a59
merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents:
3312
diff
changeset
|
287 act("other deleted", "r", f) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
288 else: |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
289 # file is created on branch or in working directory |
3121
1c1e59aac82a
merge: simplify local created logic
Matt Mackall <mpm@selenic.com>
parents:
3120
diff
changeset
|
290 if (overwrite and n[20:] != "u") or (backwards and not n[20:]): |
3313
f009a6f12a59
merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents:
3312
diff
changeset
|
291 act("remote deleted", "r", f) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
292 |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
293 for f, n in m2.iteritems(): |
3254
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
294 if partial and not partial(f): |
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
295 continue |
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
296 if f in m1: |
751840e739a1
merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents:
3248
diff
changeset
|
297 continue |
3729
581d20773326
merge: add copied hash to simplify copy logic
Matt Mackall <mpm@selenic.com>
parents:
3728
diff
changeset
|
298 if f in copied: |
581d20773326
merge: add copied hash to simplify copy logic
Matt Mackall <mpm@selenic.com>
parents:
3728
diff
changeset
|
299 continue |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
300 if f in copy: |
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
301 f2 = copy[f] |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
302 if f2 not in m1: # directory rename |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
303 act("local renamed directory to " + f2, "d", |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
304 None, f, f2, m2.flags(f)) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
305 elif f2 in m2: # rename case 1, A/A,B/A |
3730
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
306 act("remote copied to " + f, "m", |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
307 f2, f, f, fmerge(f2, f, f2), False) |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
308 else: # case 3,20 A/B/A |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
309 act("remote moved to " + f, "m", |
d377f8d25662
merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents:
3729
diff
changeset
|
310 f2, f, f, fmerge(f2, f, f2), True) |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
311 elif f in ma: |
3117
920f54a2249e
merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents:
3116
diff
changeset
|
312 if overwrite or backwards: |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
313 act("recreating", "g", f, m2.flags(f)) |
3117
920f54a2249e
merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents:
3116
diff
changeset
|
314 elif n != ma[f]: |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
315 if repo.ui.prompt( |
3117
920f54a2249e
merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents:
3116
diff
changeset
|
316 (_("remote changed %s which local deleted\n") % f) + |
3120
b1de36a4b4df
merge: simplify prompt code
Matt Mackall <mpm@selenic.com>
parents:
3119
diff
changeset
|
317 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"): |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
318 act("prompt recreating", "g", f, m2.flags(f)) |
3116
bb74f809bc95
merge: reorder tests on m2 items in manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3115
diff
changeset
|
319 else: |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
320 act("remote created", "g", f, m2.flags(f)) |
3106
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
321 |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
322 return action |
7c7469d41ade
merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents:
3105
diff
changeset
|
323 |
3303
69b9471f26bb
merge: pass contexts to applyupdates
Matt Mackall <mpm@selenic.com>
parents:
3302
diff
changeset
|
324 def applyupdates(repo, action, wctx, mctx): |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
325 "apply the merge action list to the working directory" |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
326 |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
327 updated, merged, removed, unresolved = 0, 0, 0, 0 |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
328 action.sort() |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
329 for a in action: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
330 f, m = a[:2] |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
331 if f and f[0] == "/": |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
332 continue |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
333 if m == "r": # remove |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
334 repo.ui.note(_("removing %s\n") % f) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
335 util.audit_path(f) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
336 try: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
337 util.unlink(repo.wjoin(f)) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
338 except OSError, inst: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
339 if inst.errno != errno.ENOENT: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
340 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
341 (f, inst.strerror)) |
3673
eb0b4a2d70a9
white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3620
diff
changeset
|
342 removed += 1 |
3314
ecc1bf27378c
merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents:
3313
diff
changeset
|
343 elif m == "m": # merge |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
344 f2, fd, flags, move = a[2:] |
3407
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
345 r = filemerge(repo, f, f2, wctx, mctx) |
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
346 if r > 0: |
3255
f05c182430a0
merge: add rename following
Matt Mackall <mpm@selenic.com>
parents:
3254
diff
changeset
|
347 unresolved += 1 |
3315
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
348 else: |
3407
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
349 if r is None: |
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
350 updated += 1 |
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
351 else: |
d2b55e3c4e25
merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents:
3387
diff
changeset
|
352 merged += 1 |
3315
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
353 if f != fd: |
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
354 repo.ui.debug(_("copying %s to %s\n") % (f, fd)) |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
355 repo.wwrite(fd, repo.wread(f), flags) |
3315
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
356 if move: |
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
357 repo.ui.debug(_("removing %s\n") % f) |
e8be5942335d
merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents:
3314
diff
changeset
|
358 os.unlink(repo.wjoin(f)) |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
359 util.set_exec(repo.wjoin(fd), "x" in flags) |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
360 elif m == "g": # get |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
361 flags = a[2] |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
362 repo.ui.note(_("getting %s\n") % f) |
3309
488d3062d225
merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents:
3305
diff
changeset
|
363 t = mctx.filectx(f).data() |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
364 repo.wwrite(f, t, flags) |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
365 updated += 1 |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
366 elif m == "d": # directory rename |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
367 f2, fd, flags = a[2:] |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
368 if f: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
369 repo.ui.note(_("moving %s to %s\n") % (f, fd)) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
370 t = wctx.filectx(f).data() |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
371 repo.wwrite(fd, t, flags) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
372 util.unlink(repo.wjoin(f)) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
373 if f2: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
374 repo.ui.note(_("getting %s to %s\n") % (f2, fd)) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
375 t = mctx.filectx(f2).data() |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
376 repo.wwrite(fd, t, flags) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
377 updated += 1 |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
378 elif m == "e": # exec |
4007
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
379 flags = a[2] |
20da40cc1c73
symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents:
4006
diff
changeset
|
380 util.set_exec(repo.wjoin(f), flags) |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
381 |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
382 return updated, merged, removed, unresolved |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
383 |
3387
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
384 def recordupdates(repo, action, branchmerge): |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
385 "record merge actions to the dirstate" |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
386 |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
387 for a in action: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
388 f, m = a[:2] |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
389 if m == "r": # remove |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
390 if branchmerge: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
391 repo.dirstate.update([f], 'r') |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
392 else: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
393 repo.dirstate.forget([f]) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
394 elif m == "f": # forget |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
395 repo.dirstate.forget([f]) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
396 elif m == "g": # get |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
397 if branchmerge: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
398 repo.dirstate.update([f], 'n', st_mtime=-1) |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
399 else: |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
400 repo.dirstate.update([f], 'n') |
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
401 elif m == "m": # merge |
3309
488d3062d225
merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents:
3305
diff
changeset
|
402 f2, fd, flag, move = a[2:] |
3257
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
403 if branchmerge: |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
404 # We've done a branch merge, mark this file as merged |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
405 # so that we properly record the merger later |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
406 repo.dirstate.update([fd], 'm') |
3387
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
407 if f != f2: # copy/rename |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
408 if move: |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
409 repo.dirstate.update([f], 'r') |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
410 if f != fd: |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
411 repo.dirstate.copy(f, fd) |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
412 else: |
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
413 repo.dirstate.copy(f2, fd) |
3257
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
414 else: |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
415 # We've update-merged a locally modified file, so |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
416 # we set the dirstate to emulate a normal checkout |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
417 # of that file some time in the past. Thus our |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
418 # merge will appear as a normal local file |
c93ce7f10f85
merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents:
3255
diff
changeset
|
419 # modification. |
3387
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
420 repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1) |
3314
ecc1bf27378c
merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents:
3313
diff
changeset
|
421 if move: |
3387
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
422 repo.dirstate.forget([f]) |
3733
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
423 elif m == "d": # directory rename |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
424 f2, fd, flag = a[2:] |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
425 if branchmerge: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
426 repo.dirstate.update([fd], 'a') |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
427 if f: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
428 repo.dirstate.update([f], 'r') |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
429 repo.dirstate.copy(f, fd) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
430 if f2: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
431 repo.dirstate.copy(f2, fd) |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
432 else: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
433 repo.dirstate.update([fd], 'n') |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
434 if f: |
9e67fecbfd16
merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents:
3732
diff
changeset
|
435 repo.dirstate.forget([f]) |
3112
5cc62d99b785
merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3111
diff
changeset
|
436 |
3323
39fd6e82ea38
merge: pull user messages out to hg.py
Matt Mackall <mpm@selenic.com>
parents:
3322
diff
changeset
|
437 def update(repo, node, branchmerge, force, partial, wlock): |
3322
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
438 """ |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
439 Perform a merge between the working directory and the given node |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
440 |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
441 branchmerge = whether to merge between branches |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
442 force = whether to force branch merging or file overwriting |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
443 partial = a function to filter file lists (dirstate not updated) |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
444 wlock = working dir lock, if already held |
38be819a1225
merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents:
3320
diff
changeset
|
445 """ |
2829
4870f795f681
Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents:
2828
diff
changeset
|
446 |
2826
3aeab7bb5adc
Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents:
2825
diff
changeset
|
447 if not wlock: |
3aeab7bb5adc
Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents:
2825
diff
changeset
|
448 wlock = repo.wlock() |
3aeab7bb5adc
Refactor update locking slightly
Matt Mackall <mpm@selenic.com>
parents:
2825
diff
changeset
|
449 |
4177 | 450 wc = repo.workingctx() |
451 if node is None: | |
452 # tip of current branch | |
4232
0d51eb296fb9
Merge with crew-stable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4209
diff
changeset
|
453 try: |
0d51eb296fb9
Merge with crew-stable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4209
diff
changeset
|
454 node = repo.branchtags()[wc.branch()] |
0d51eb296fb9
Merge with crew-stable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4209
diff
changeset
|
455 except KeyError: |
0d51eb296fb9
Merge with crew-stable
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
4209
diff
changeset
|
456 raise util.Abort(_("branch %s not found") % wc.branch()) |
3320 | 457 overwrite = force and not branchmerge |
458 forcemerge = force and branchmerge | |
3240
8d4855fd9d7b
merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents:
3234
diff
changeset
|
459 pl = wc.parents() |
3320 | 460 p1, p2 = pl[0], repo.changectx(node) |
461 pa = p1.ancestor(p2) | |
462 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2) | |
463 | |
464 ### check phase | |
3200
e67c22bc8bba
merge: use repo.parents and parent contexts in update
Matt Mackall <mpm@selenic.com>
parents:
3163
diff
changeset
|
465 if not overwrite and len(pl) > 1: |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
466 raise util.Abort(_("outstanding uncommitted merges")) |
3320 | 467 if pa == p1 or pa == p2: # is there a linear path from p1 to p2? |
3111
40e777bda455
merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents:
3110
diff
changeset
|
468 if branchmerge: |
40e777bda455
merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents:
3110
diff
changeset
|
469 raise util.Abort(_("there is nothing to merge, just use " |
40e777bda455
merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents:
3110
diff
changeset
|
470 "'hg update' or look at 'hg heads'")) |
3592
fffc8a733bf9
Backed out changeset 41989e55fa375de4376e7e64b17e38312e8ec140
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3580
diff
changeset
|
471 elif not (overwrite or branchmerge): |
fffc8a733bf9
Backed out changeset 41989e55fa375de4376e7e64b17e38312e8ec140
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3580
diff
changeset
|
472 raise util.Abort(_("update spans branches, use 'hg merge' " |
fffc8a733bf9
Backed out changeset 41989e55fa375de4376e7e64b17e38312e8ec140
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3580
diff
changeset
|
473 "or 'hg update -C' to lose changes")) |
2828
0f787997e3c2
Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents:
2827
diff
changeset
|
474 if branchmerge and not forcemerge: |
3581
be61bd32046c
use workingcontext.files() to detect if the repo is unclean
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3580
diff
changeset
|
475 if wc.files(): |
2828
0f787997e3c2
Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents:
2827
diff
changeset
|
476 raise util.Abort(_("outstanding uncommitted changes")) |
0f787997e3c2
Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents:
2827
diff
changeset
|
477 |
3320 | 478 ### calculate phase |
3101
87ea5a71f7b9
merge: convert actions to list
Matt Mackall <mpm@selenic.com>
parents:
3097
diff
changeset
|
479 action = [] |
3108
3bd05ad67f45
merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents:
3107
diff
changeset
|
480 if not force: |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
481 checkunknown(wc, p2) |
3786 | 482 if not util.checkfolding(repo.path): |
483 checkcollision(p2) | |
3111
40e777bda455
merge: remove linear variable
Matt Mackall <mpm@selenic.com>
parents:
3110
diff
changeset
|
484 if not branchmerge: |
3318
c5075ad5e3e9
merge: use contexts in checkunknown and forgetremoved
Matt Mackall <mpm@selenic.com>
parents:
3317
diff
changeset
|
485 action += forgetremoved(wc, p2) |
3301
72d1e521da77
merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents:
3295
diff
changeset
|
486 action += manifestmerge(repo, wc, p2, pa, overwrite, partial) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
487 |
2917
dd032b0f02ac
merge: move forgets to the apply stage
Matt Mackall <mpm@selenic.com>
parents:
2916
diff
changeset
|
488 ### apply phase |
3320 | 489 if not branchmerge: # just jump to the new rev |
490 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, '' | |
3302
20087b4bc6f9
merge: don't call hooks for revert
Matt Mackall <mpm@selenic.com>
parents:
3301
diff
changeset
|
491 if not partial: |
20087b4bc6f9
merge: don't call hooks for revert
Matt Mackall <mpm@selenic.com>
parents:
3301
diff
changeset
|
492 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
493 |
3323
39fd6e82ea38
merge: pull user messages out to hg.py
Matt Mackall <mpm@selenic.com>
parents:
3322
diff
changeset
|
494 stats = applyupdates(repo, action, wc, p2) |
2919
8743188f4d2e
merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents:
2918
diff
changeset
|
495 |
2825
1ea086bc2086
Merge: combine choose and moddirstate to partial
Matt Mackall <mpm@selenic.com>
parents:
2824
diff
changeset
|
496 if not partial: |
3387
ba7c74081861
merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents:
3377
diff
changeset
|
497 recordupdates(repo, action, branchmerge) |
3320 | 498 repo.dirstate.setparents(fp1, fp2) |
4207
7e1c8a565a4f
Move branch read/write to dirstate where it belongs
Matt Mackall <mpm@selenic.com>
parents:
4117
diff
changeset
|
499 if not branchmerge: |
7e1c8a565a4f
Move branch read/write to dirstate where it belongs
Matt Mackall <mpm@selenic.com>
parents:
4117
diff
changeset
|
500 repo.dirstate.setbranch(p2.branch()) |
3323
39fd6e82ea38
merge: pull user messages out to hg.py
Matt Mackall <mpm@selenic.com>
parents:
3322
diff
changeset
|
501 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3]) |
3320 | 502 |
3323
39fd6e82ea38
merge: pull user messages out to hg.py
Matt Mackall <mpm@selenic.com>
parents:
3322
diff
changeset
|
503 return stats |
2799
b550cd82f92a
Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
504 |