##// END OF EJS Templates
merge: only store one direction of copies in the copy map...
Matt Mackall -
r3730:d377f8d2 default
parent child Browse files
Show More
@@ -1,418 +1,417 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from node import *
8 from node import *
9 from i18n import gettext as _
9 from i18n import gettext as _
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "errno util os tempfile")
11 demandload(globals(), "errno util os tempfile")
12
12
13 def filemerge(repo, fw, fo, wctx, mctx):
13 def filemerge(repo, fw, fo, wctx, mctx):
14 """perform a 3-way merge in the working directory
14 """perform a 3-way merge in the working directory
15
15
16 fw = filename in the working directory
16 fw = filename in the working directory
17 fo = filename in other parent
17 fo = filename in other parent
18 wctx, mctx = working and merge changecontexts
18 wctx, mctx = working and merge changecontexts
19 """
19 """
20
20
21 def temp(prefix, ctx):
21 def temp(prefix, ctx):
22 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
22 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
23 (fd, name) = tempfile.mkstemp(prefix=pre)
23 (fd, name) = tempfile.mkstemp(prefix=pre)
24 f = os.fdopen(fd, "wb")
24 f = os.fdopen(fd, "wb")
25 repo.wwrite(ctx.path(), ctx.data(), f)
25 repo.wwrite(ctx.path(), ctx.data(), f)
26 f.close()
26 f.close()
27 return name
27 return name
28
28
29 fcm = wctx.filectx(fw)
29 fcm = wctx.filectx(fw)
30 fco = mctx.filectx(fo)
30 fco = mctx.filectx(fo)
31
31
32 if not fco.cmp(fcm.data()): # files identical?
32 if not fco.cmp(fcm.data()): # files identical?
33 return None
33 return None
34
34
35 fca = fcm.ancestor(fco)
35 fca = fcm.ancestor(fco)
36 if not fca:
36 if not fca:
37 fca = repo.filectx(fw, fileid=nullrev)
37 fca = repo.filectx(fw, fileid=nullrev)
38 a = repo.wjoin(fw)
38 a = repo.wjoin(fw)
39 b = temp("base", fca)
39 b = temp("base", fca)
40 c = temp("other", fco)
40 c = temp("other", fco)
41
41
42 if fw != fo:
42 if fw != fo:
43 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
43 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
44 else:
44 else:
45 repo.ui.status(_("merging %s\n") % fw)
45 repo.ui.status(_("merging %s\n") % fw)
46
46
47 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
47 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
48
48
49 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
49 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
50 or "hgmerge")
50 or "hgmerge")
51 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
51 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
52 environ={'HG_FILE': fw,
52 environ={'HG_FILE': fw,
53 'HG_MY_NODE': str(wctx.parents()[0]),
53 'HG_MY_NODE': str(wctx.parents()[0]),
54 'HG_OTHER_NODE': str(mctx)})
54 'HG_OTHER_NODE': str(mctx)})
55 if r:
55 if r:
56 repo.ui.warn(_("merging %s failed!\n") % fw)
56 repo.ui.warn(_("merging %s failed!\n") % fw)
57
57
58 os.unlink(b)
58 os.unlink(b)
59 os.unlink(c)
59 os.unlink(c)
60 return r
60 return r
61
61
62 def checkunknown(wctx, mctx):
62 def checkunknown(wctx, mctx):
63 "check for collisions between unknown files and files in mctx"
63 "check for collisions between unknown files and files in mctx"
64 man = mctx.manifest()
64 man = mctx.manifest()
65 for f in wctx.unknown():
65 for f in wctx.unknown():
66 if f in man:
66 if f in man:
67 if mctx.filectx(f).cmp(wctx.filectx(f).data()):
67 if mctx.filectx(f).cmp(wctx.filectx(f).data()):
68 raise util.Abort(_("untracked local file '%s' differs"\
68 raise util.Abort(_("untracked local file '%s' differs"\
69 " from remote version") % f)
69 " from remote version") % f)
70
70
71 def forgetremoved(wctx, mctx):
71 def forgetremoved(wctx, mctx):
72 """
72 """
73 Forget removed files
73 Forget removed files
74
74
75 If we're jumping between revisions (as opposed to merging), and if
75 If we're jumping between revisions (as opposed to merging), and if
76 neither the working directory nor the target rev has the file,
76 neither the working directory nor the target rev has the file,
77 then we need to remove it from the dirstate, to prevent the
77 then we need to remove it from the dirstate, to prevent the
78 dirstate from listing the file when it is no longer in the
78 dirstate from listing the file when it is no longer in the
79 manifest.
79 manifest.
80 """
80 """
81
81
82 action = []
82 action = []
83 man = mctx.manifest()
83 man = mctx.manifest()
84 for f in wctx.deleted() + wctx.removed():
84 for f in wctx.deleted() + wctx.removed():
85 if f not in man:
85 if f not in man:
86 action.append((f, "f"))
86 action.append((f, "f"))
87
87
88 return action
88 return action
89
89
90 def nonoverlap(d1, d2, d3):
90 def nonoverlap(d1, d2, d3):
91 "Return list of elements in d1 not in d2 or d3"
91 "Return list of elements in d1 not in d2 or d3"
92
92
93 l = []
93 l = []
94 for d in d1:
94 for d in d1:
95 if d not in d3 and d not in d2:
95 if d not in d3 and d not in d2:
96 l.append(d)
96 l.append(d)
97
97
98 l.sort()
98 l.sort()
99 return l
99 return l
100
100
101 def findold(fctx, limit):
101 def findold(fctx, limit):
102 "find files that path was copied from, back to linkrev limit"
102 "find files that path was copied from, back to linkrev limit"
103
103
104 old = {}
104 old = {}
105 orig = fctx.path()
105 orig = fctx.path()
106 visit = [fctx]
106 visit = [fctx]
107 while visit:
107 while visit:
108 fc = visit.pop()
108 fc = visit.pop()
109 if fc.rev() < limit:
109 if fc.rev() < limit:
110 continue
110 continue
111 if fc.path() != orig and fc.path() not in old:
111 if fc.path() != orig and fc.path() not in old:
112 old[fc.path()] = 1
112 old[fc.path()] = 1
113 visit += fc.parents()
113 visit += fc.parents()
114
114
115 old = old.keys()
115 old = old.keys()
116 old.sort()
116 old.sort()
117 return old
117 return old
118
118
119 def findcopies(repo, m1, m2, ma, limit):
119 def findcopies(repo, m1, m2, ma, limit):
120 """
120 """
121 Find moves and copies between m1 and m2 back to limit linkrev
121 Find moves and copies between m1 and m2 back to limit linkrev
122 """
122 """
123
123
124 if not repo.ui.configbool("merge", "followcopies", True):
124 if not repo.ui.configbool("merge", "followcopies", True):
125 return {}
125 return {}
126
126
127 # avoid silly behavior for update from empty dir
127 # avoid silly behavior for update from empty dir
128 if not m1:
128 if not m1:
129 return {}
129 return {}
130
130
131 dcopies = repo.dirstate.copies()
131 dcopies = repo.dirstate.copies()
132 copy = {}
132 copy = {}
133 u1 = nonoverlap(m1, m2, ma)
133 u1 = nonoverlap(m1, m2, ma)
134 u2 = nonoverlap(m2, m1, ma)
134 u2 = nonoverlap(m2, m1, ma)
135 ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20]))
135 ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20]))
136
136
137 def checkpair(c, f2, man):
137 def checkpair(c, f2, man):
138 ''' check if an apparent pair actually matches '''
138 ''' check if an apparent pair actually matches '''
139 if f2 not in man:
140 return
139 c2 = ctx(f2, man[f2])
141 c2 = ctx(f2, man[f2])
140 ca = c.ancestor(c2)
142 ca = c.ancestor(c2)
141 if not ca or c == ca or c2 == ca:
143 if not ca or c == ca or c2 == ca:
142 return
144 return
143 if ca.path() == c.path() or ca.path() == c2.path():
145 if ca.path() == c.path() or ca.path() == c2.path():
144 copy[c.path()] = f2
146 copy[c.path()] = f2
145 copy[f2] = c.path()
146
147
147 for f in u1:
148 for f in u1:
148 c = ctx(dcopies.get(f, f), m1[f])
149 c = ctx(dcopies.get(f, f), m1[f])
149 for of in findold(c, limit):
150 for of in findold(c, limit):
150 if of in m2:
151 checkpair(c, of, m2)
151 checkpair(c, of, m2)
152
152
153 for f in u2:
153 for f in u2:
154 c = ctx(f, m2[f])
154 c = ctx(f, m2[f])
155 for of in findold(c, limit):
155 for of in findold(c, limit):
156 if of in m1:
156 checkpair(c, of, m1)
157 checkpair(c, of, m1)
158
157
159 return copy
158 return copy
160
159
161 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
160 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
162 """
161 """
163 Merge p1 and p2 with ancestor ma and generate merge action list
162 Merge p1 and p2 with ancestor ma and generate merge action list
164
163
165 overwrite = whether we clobber working files
164 overwrite = whether we clobber working files
166 partial = function to filter file lists
165 partial = function to filter file lists
167 """
166 """
168
167
169 repo.ui.note(_("resolving manifests\n"))
168 repo.ui.note(_("resolving manifests\n"))
170 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
169 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
171 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
170 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
172
171
173 m1 = p1.manifest()
172 m1 = p1.manifest()
174 m2 = p2.manifest()
173 m2 = p2.manifest()
175 ma = pa.manifest()
174 ma = pa.manifest()
176 backwards = (pa == p2)
175 backwards = (pa == p2)
177 action = []
176 action = []
178 copy = {}
177 copy = {}
179 copied = {}
180
178
181 def fmerge(f, f2=None, fa=None):
179 def fmerge(f, f2=None, fa=None):
182 """merge executable flags"""
180 """merge executable flags"""
183 if not f2:
181 if not f2:
184 f2 = f
182 f2 = f
185 fa = f
183 fa = f
186 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
184 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2)
187 return ((a^b) | (a^c)) ^ a
185 return ((a^b) | (a^c)) ^ a
188
186
189 def act(msg, m, f, *args):
187 def act(msg, m, f, *args):
190 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
188 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
191 action.append((f, m) + args)
189 action.append((f, m) + args)
192
190
193 if pa and not (backwards or overwrite):
191 if pa and not (backwards or overwrite):
194 copy = findcopies(repo, m1, m2, ma, pa.rev())
192 copy = findcopies(repo, m1, m2, ma, pa.rev())
193 copied = dict.fromkeys(copy.values())
195
194
196 # Compare manifests
195 # Compare manifests
197 for f, n in m1.iteritems():
196 for f, n in m1.iteritems():
198 if partial and not partial(f):
197 if partial and not partial(f):
199 continue
198 continue
200 if f in m2:
199 if f in m2:
201 # are files different?
200 # are files different?
202 if n != m2[f]:
201 if n != m2[f]:
203 a = ma.get(f, nullid)
202 a = ma.get(f, nullid)
204 # are both different from the ancestor?
203 # are both different from the ancestor?
205 if not overwrite and n != a and m2[f] != a:
204 if not overwrite and n != a and m2[f] != a:
206 act("versions differ", "m", f, f, f, fmerge(f), False)
205 act("versions differ", "m", f, f, f, fmerge(f), False)
207 # are we clobbering?
206 # are we clobbering?
208 # is remote's version newer?
207 # is remote's version newer?
209 # or are we going back in time and clean?
208 # or are we going back in time and clean?
210 elif overwrite or m2[f] != a or (backwards and not n[20:]):
209 elif overwrite or m2[f] != a or (backwards and not n[20:]):
211 act("remote is newer", "g", f, m2.execf(f))
210 act("remote is newer", "g", f, m2.execf(f))
212 # local is newer, not overwrite, check mode bits
211 # local is newer, not overwrite, check mode bits
213 elif fmerge(f) != m1.execf(f):
212 elif fmerge(f) != m1.execf(f):
214 act("update permissions", "e", f, m2.execf(f))
213 act("update permissions", "e", f, m2.execf(f))
215 # contents same, check mode bits
214 # contents same, check mode bits
216 elif m1.execf(f) != m2.execf(f):
215 elif m1.execf(f) != m2.execf(f):
217 if overwrite or fmerge(f) != m1.execf(f):
216 if overwrite or fmerge(f) != m1.execf(f):
218 act("update permissions", "e", f, m2.execf(f))
217 act("update permissions", "e", f, m2.execf(f))
218 elif f in copied:
219 continue
219 elif f in copy:
220 elif f in copy:
220 f2 = copy[f]
221 f2 = copy[f]
221 copied[f2] = True
222 if f2 in m1: # case 2 A,B/B/B
222 if f in ma: # case 3,20 A/B/A
223 act("local copied to " + f2, "m",
223 act("remote moved to " + f2, "m",
224 f, f2, f, fmerge(f, f2, f2), False)
224 f, f2, f2, fmerge(f, f2, f), True)
225 else: # case 4,21 A/B/B
225 else:
226 act("local moved to " + f2, "m",
226 if f2 in m1: # case 2 A,B/B/B
227 f, f2, f, fmerge(f, f2, f2), False)
227 act("local copied to " + f2, "m",
228 f, f2, f, fmerge(f, f2, f2), False)
229 else: # case 4,21 A/B/B
230 act("local moved to " + f2, "m",
231 f, f2, f, fmerge(f, f2, f2), False)
232 elif f in ma:
228 elif f in ma:
233 if n != ma[f] and not overwrite:
229 if n != ma[f] and not overwrite:
234 if repo.ui.prompt(
230 if repo.ui.prompt(
235 (_(" local changed %s which remote deleted\n") % f) +
231 (_(" local changed %s which remote deleted\n") % f) +
236 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
232 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"):
237 act("prompt delete", "r", f)
233 act("prompt delete", "r", f)
238 else:
234 else:
239 act("other deleted", "r", f)
235 act("other deleted", "r", f)
240 else:
236 else:
241 # file is created on branch or in working directory
237 # file is created on branch or in working directory
242 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
238 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
243 act("remote deleted", "r", f)
239 act("remote deleted", "r", f)
244
240
245 for f, n in m2.iteritems():
241 for f, n in m2.iteritems():
246 if partial and not partial(f):
242 if partial and not partial(f):
247 continue
243 continue
248 if f in m1:
244 if f in m1:
249 continue
245 continue
250 if f in copied:
246 if f in copied:
251 continue
247 continue
252 if f in copy:
248 if f in copy:
253 f2 = copy[f]
249 f2 = copy[f]
254 # rename case 1, A/A,B/A
250 if f2 in m2: # rename case 1, A/A,B/A
255 act("remote copied to " + f, "m",
251 act("remote copied to " + f, "m",
256 f2, f, f, fmerge(f2, f, f2), False)
252 f2, f, f, fmerge(f2, f, f2), False)
253 else: # case 3,20 A/B/A
254 act("remote moved to " + f, "m",
255 f2, f, f, fmerge(f2, f, f2), True)
257 elif f in ma:
256 elif f in ma:
258 if overwrite or backwards:
257 if overwrite or backwards:
259 act("recreating", "g", f, m2.execf(f))
258 act("recreating", "g", f, m2.execf(f))
260 elif n != ma[f]:
259 elif n != ma[f]:
261 if repo.ui.prompt(
260 if repo.ui.prompt(
262 (_("remote changed %s which local deleted\n") % f) +
261 (_("remote changed %s which local deleted\n") % f) +
263 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
262 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("k"):
264 act("prompt recreating", "g", f, m2.execf(f))
263 act("prompt recreating", "g", f, m2.execf(f))
265 else:
264 else:
266 act("remote created", "g", f, m2.execf(f))
265 act("remote created", "g", f, m2.execf(f))
267
266
268 return action
267 return action
269
268
270 def applyupdates(repo, action, wctx, mctx):
269 def applyupdates(repo, action, wctx, mctx):
271 "apply the merge action list to the working directory"
270 "apply the merge action list to the working directory"
272
271
273 updated, merged, removed, unresolved = 0, 0, 0, 0
272 updated, merged, removed, unresolved = 0, 0, 0, 0
274 action.sort()
273 action.sort()
275 for a in action:
274 for a in action:
276 f, m = a[:2]
275 f, m = a[:2]
277 if f[0] == "/":
276 if f[0] == "/":
278 continue
277 continue
279 if m == "r": # remove
278 if m == "r": # remove
280 repo.ui.note(_("removing %s\n") % f)
279 repo.ui.note(_("removing %s\n") % f)
281 util.audit_path(f)
280 util.audit_path(f)
282 try:
281 try:
283 util.unlink(repo.wjoin(f))
282 util.unlink(repo.wjoin(f))
284 except OSError, inst:
283 except OSError, inst:
285 if inst.errno != errno.ENOENT:
284 if inst.errno != errno.ENOENT:
286 repo.ui.warn(_("update failed to remove %s: %s!\n") %
285 repo.ui.warn(_("update failed to remove %s: %s!\n") %
287 (f, inst.strerror))
286 (f, inst.strerror))
288 removed += 1
287 removed += 1
289 elif m == "m": # merge
288 elif m == "m": # merge
290 f2, fd, flag, move = a[2:]
289 f2, fd, flag, move = a[2:]
291 r = filemerge(repo, f, f2, wctx, mctx)
290 r = filemerge(repo, f, f2, wctx, mctx)
292 if r > 0:
291 if r > 0:
293 unresolved += 1
292 unresolved += 1
294 else:
293 else:
295 if r is None:
294 if r is None:
296 updated += 1
295 updated += 1
297 else:
296 else:
298 merged += 1
297 merged += 1
299 if f != fd:
298 if f != fd:
300 repo.ui.debug(_("copying %s to %s\n") % (f, fd))
299 repo.ui.debug(_("copying %s to %s\n") % (f, fd))
301 repo.wwrite(fd, repo.wread(f))
300 repo.wwrite(fd, repo.wread(f))
302 if move:
301 if move:
303 repo.ui.debug(_("removing %s\n") % f)
302 repo.ui.debug(_("removing %s\n") % f)
304 os.unlink(repo.wjoin(f))
303 os.unlink(repo.wjoin(f))
305 util.set_exec(repo.wjoin(fd), flag)
304 util.set_exec(repo.wjoin(fd), flag)
306 elif m == "g": # get
305 elif m == "g": # get
307 flag = a[2]
306 flag = a[2]
308 repo.ui.note(_("getting %s\n") % f)
307 repo.ui.note(_("getting %s\n") % f)
309 t = mctx.filectx(f).data()
308 t = mctx.filectx(f).data()
310 repo.wwrite(f, t)
309 repo.wwrite(f, t)
311 util.set_exec(repo.wjoin(f), flag)
310 util.set_exec(repo.wjoin(f), flag)
312 updated += 1
311 updated += 1
313 elif m == "e": # exec
312 elif m == "e": # exec
314 flag = a[2]
313 flag = a[2]
315 util.set_exec(repo.wjoin(f), flag)
314 util.set_exec(repo.wjoin(f), flag)
316
315
317 return updated, merged, removed, unresolved
316 return updated, merged, removed, unresolved
318
317
319 def recordupdates(repo, action, branchmerge):
318 def recordupdates(repo, action, branchmerge):
320 "record merge actions to the dirstate"
319 "record merge actions to the dirstate"
321
320
322 for a in action:
321 for a in action:
323 f, m = a[:2]
322 f, m = a[:2]
324 if m == "r": # remove
323 if m == "r": # remove
325 if branchmerge:
324 if branchmerge:
326 repo.dirstate.update([f], 'r')
325 repo.dirstate.update([f], 'r')
327 else:
326 else:
328 repo.dirstate.forget([f])
327 repo.dirstate.forget([f])
329 elif m == "f": # forget
328 elif m == "f": # forget
330 repo.dirstate.forget([f])
329 repo.dirstate.forget([f])
331 elif m == "g": # get
330 elif m == "g": # get
332 if branchmerge:
331 if branchmerge:
333 repo.dirstate.update([f], 'n', st_mtime=-1)
332 repo.dirstate.update([f], 'n', st_mtime=-1)
334 else:
333 else:
335 repo.dirstate.update([f], 'n')
334 repo.dirstate.update([f], 'n')
336 elif m == "m": # merge
335 elif m == "m": # merge
337 f2, fd, flag, move = a[2:]
336 f2, fd, flag, move = a[2:]
338 if branchmerge:
337 if branchmerge:
339 # We've done a branch merge, mark this file as merged
338 # We've done a branch merge, mark this file as merged
340 # so that we properly record the merger later
339 # so that we properly record the merger later
341 repo.dirstate.update([fd], 'm')
340 repo.dirstate.update([fd], 'm')
342 if f != f2: # copy/rename
341 if f != f2: # copy/rename
343 if move:
342 if move:
344 repo.dirstate.update([f], 'r')
343 repo.dirstate.update([f], 'r')
345 if f != fd:
344 if f != fd:
346 repo.dirstate.copy(f, fd)
345 repo.dirstate.copy(f, fd)
347 else:
346 else:
348 repo.dirstate.copy(f2, fd)
347 repo.dirstate.copy(f2, fd)
349 else:
348 else:
350 # We've update-merged a locally modified file, so
349 # We've update-merged a locally modified file, so
351 # we set the dirstate to emulate a normal checkout
350 # we set the dirstate to emulate a normal checkout
352 # of that file some time in the past. Thus our
351 # of that file some time in the past. Thus our
353 # merge will appear as a normal local file
352 # merge will appear as a normal local file
354 # modification.
353 # modification.
355 repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1)
354 repo.dirstate.update([fd], 'n', st_size=-1, st_mtime=-1)
356 if move:
355 if move:
357 repo.dirstate.forget([f])
356 repo.dirstate.forget([f])
358
357
359 def update(repo, node, branchmerge, force, partial, wlock):
358 def update(repo, node, branchmerge, force, partial, wlock):
360 """
359 """
361 Perform a merge between the working directory and the given node
360 Perform a merge between the working directory and the given node
362
361
363 branchmerge = whether to merge between branches
362 branchmerge = whether to merge between branches
364 force = whether to force branch merging or file overwriting
363 force = whether to force branch merging or file overwriting
365 partial = a function to filter file lists (dirstate not updated)
364 partial = a function to filter file lists (dirstate not updated)
366 wlock = working dir lock, if already held
365 wlock = working dir lock, if already held
367 """
366 """
368
367
369 if not wlock:
368 if not wlock:
370 wlock = repo.wlock()
369 wlock = repo.wlock()
371
370
372 overwrite = force and not branchmerge
371 overwrite = force and not branchmerge
373 forcemerge = force and branchmerge
372 forcemerge = force and branchmerge
374 wc = repo.workingctx()
373 wc = repo.workingctx()
375 pl = wc.parents()
374 pl = wc.parents()
376 p1, p2 = pl[0], repo.changectx(node)
375 p1, p2 = pl[0], repo.changectx(node)
377 pa = p1.ancestor(p2)
376 pa = p1.ancestor(p2)
378 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
377 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
379
378
380 ### check phase
379 ### check phase
381 if not overwrite and len(pl) > 1:
380 if not overwrite and len(pl) > 1:
382 raise util.Abort(_("outstanding uncommitted merges"))
381 raise util.Abort(_("outstanding uncommitted merges"))
383 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
382 if pa == p1 or pa == p2: # is there a linear path from p1 to p2?
384 if branchmerge:
383 if branchmerge:
385 raise util.Abort(_("there is nothing to merge, just use "
384 raise util.Abort(_("there is nothing to merge, just use "
386 "'hg update' or look at 'hg heads'"))
385 "'hg update' or look at 'hg heads'"))
387 elif not (overwrite or branchmerge):
386 elif not (overwrite or branchmerge):
388 raise util.Abort(_("update spans branches, use 'hg merge' "
387 raise util.Abort(_("update spans branches, use 'hg merge' "
389 "or 'hg update -C' to lose changes"))
388 "or 'hg update -C' to lose changes"))
390 if branchmerge and not forcemerge:
389 if branchmerge and not forcemerge:
391 if wc.files():
390 if wc.files():
392 raise util.Abort(_("outstanding uncommitted changes"))
391 raise util.Abort(_("outstanding uncommitted changes"))
393
392
394 ### calculate phase
393 ### calculate phase
395 action = []
394 action = []
396 if not force:
395 if not force:
397 checkunknown(wc, p2)
396 checkunknown(wc, p2)
398 if not branchmerge:
397 if not branchmerge:
399 action += forgetremoved(wc, p2)
398 action += forgetremoved(wc, p2)
400 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
399 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
401
400
402 ### apply phase
401 ### apply phase
403 if not branchmerge: # just jump to the new rev
402 if not branchmerge: # just jump to the new rev
404 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
403 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
405 if not partial:
404 if not partial:
406 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
405 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
407
406
408 stats = applyupdates(repo, action, wc, p2)
407 stats = applyupdates(repo, action, wc, p2)
409
408
410 if not partial:
409 if not partial:
411 recordupdates(repo, action, branchmerge)
410 recordupdates(repo, action, branchmerge)
412 repo.dirstate.setparents(fp1, fp2)
411 repo.dirstate.setparents(fp1, fp2)
413 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
412 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
414 if not branchmerge:
413 if not branchmerge:
415 repo.opener("branch", "w").write(p2.branch() + "\n")
414 repo.opener("branch", "w").write(p2.branch() + "\n")
416
415
417 return stats
416 return stats
418
417
@@ -1,409 +1,409 b''
1 --------------
1 --------------
2 test L:up a R:nc a b W: - 1 get local a to b
2 test L:up a R:nc a b W: - 1 get local a to b
3 --------------
3 --------------
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
6 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
7 rev: versions differ -> m
7 rev: versions differ -> m
8 a: remote copied to b -> m
8 a: remote copied to b -> m
9 merging a and b
9 merging a and b
10 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
10 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
11 copying a to b
11 copying a to b
12 merging rev
12 merging rev
13 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
13 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
14 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
14 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
15 (branch merge, don't forget to commit)
15 (branch merge, don't forget to commit)
16 --------------
16 --------------
17 M a
17 M a
18 M b
18 M b
19 a
19 a
20 --------------
20 --------------
21
21
22 --------------
22 --------------
23 test L:nc a b R:up a W: - 2 get rem change to a and b
23 test L:nc a b R:up a W: - 2 get rem change to a and b
24 --------------
24 --------------
25 resolving manifests
25 resolving manifests
26 overwrite None partial False
26 overwrite None partial False
27 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
27 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
28 a: remote is newer -> g
28 a: remote is newer -> g
29 b: local copied to a -> m
29 b: local copied to a -> m
30 rev: versions differ -> m
30 rev: versions differ -> m
31 getting a
31 getting a
32 merging b and a
32 merging b and a
33 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
33 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
34 merging rev
34 merging rev
35 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
35 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
36 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
36 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
37 (branch merge, don't forget to commit)
37 (branch merge, don't forget to commit)
38 --------------
38 --------------
39 M a
39 M a
40 M b
40 M b
41 a
41 a
42 --------------
42 --------------
43
43
44 --------------
44 --------------
45 test L:up a R:nm a b W: - 3 get local a change to b, remove a
45 test L:up a R:nm a b W: - 3 get local a change to b, remove a
46 --------------
46 --------------
47 resolving manifests
47 resolving manifests
48 overwrite None partial False
48 overwrite None partial False
49 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
49 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
50 rev: versions differ -> m
50 a: remote moved to b -> m
51 a: remote moved to b -> m
51 rev: versions differ -> m
52 merging a and b
52 merging a and b
53 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
53 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
54 copying a to b
54 copying a to b
55 removing a
55 removing a
56 merging rev
56 merging rev
57 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
57 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
58 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
58 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
59 (branch merge, don't forget to commit)
59 (branch merge, don't forget to commit)
60 --------------
60 --------------
61 M b
61 M b
62 a
62 a
63 --------------
63 --------------
64
64
65 --------------
65 --------------
66 test L:nm a b R:up a W: - 4 get remote change to b
66 test L:nm a b R:up a W: - 4 get remote change to b
67 --------------
67 --------------
68 resolving manifests
68 resolving manifests
69 overwrite None partial False
69 overwrite None partial False
70 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
70 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
71 b: local moved to a -> m
71 b: local moved to a -> m
72 rev: versions differ -> m
72 rev: versions differ -> m
73 merging b and a
73 merging b and a
74 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
74 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
75 merging rev
75 merging rev
76 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
76 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
77 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
77 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
78 (branch merge, don't forget to commit)
78 (branch merge, don't forget to commit)
79 --------------
79 --------------
80 M b
80 M b
81 a
81 a
82 --------------
82 --------------
83
83
84 --------------
84 --------------
85 test L: R:nc a b W: - 5 get b
85 test L: R:nc a b W: - 5 get b
86 --------------
86 --------------
87 resolving manifests
87 resolving manifests
88 overwrite None partial False
88 overwrite None partial False
89 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
89 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
90 rev: versions differ -> m
90 rev: versions differ -> m
91 b: remote created -> g
91 b: remote created -> g
92 getting b
92 getting b
93 merging rev
93 merging rev
94 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
94 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
95 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
95 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
96 (branch merge, don't forget to commit)
96 (branch merge, don't forget to commit)
97 --------------
97 --------------
98 M b
98 M b
99 C a
99 C a
100 --------------
100 --------------
101
101
102 --------------
102 --------------
103 test L:nc a b R: W: - 6 nothing
103 test L:nc a b R: W: - 6 nothing
104 --------------
104 --------------
105 resolving manifests
105 resolving manifests
106 overwrite None partial False
106 overwrite None partial False
107 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
107 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
108 rev: versions differ -> m
108 rev: versions differ -> m
109 merging rev
109 merging rev
110 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
110 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
111 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
111 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
112 (branch merge, don't forget to commit)
112 (branch merge, don't forget to commit)
113 --------------
113 --------------
114 C a
114 C a
115 C b
115 C b
116 --------------
116 --------------
117
117
118 --------------
118 --------------
119 test L: R:nm a b W: - 7 get b
119 test L: R:nm a b W: - 7 get b
120 --------------
120 --------------
121 resolving manifests
121 resolving manifests
122 overwrite None partial False
122 overwrite None partial False
123 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
123 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
124 a: other deleted -> r
124 a: other deleted -> r
125 rev: versions differ -> m
125 rev: versions differ -> m
126 b: remote created -> g
126 b: remote created -> g
127 removing a
127 removing a
128 getting b
128 getting b
129 merging rev
129 merging rev
130 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
130 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
131 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
131 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
132 (branch merge, don't forget to commit)
132 (branch merge, don't forget to commit)
133 --------------
133 --------------
134 M b
134 M b
135 --------------
135 --------------
136
136
137 --------------
137 --------------
138 test L:nm a b R: W: - 8 nothing
138 test L:nm a b R: W: - 8 nothing
139 --------------
139 --------------
140 resolving manifests
140 resolving manifests
141 overwrite None partial False
141 overwrite None partial False
142 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
142 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
143 rev: versions differ -> m
143 rev: versions differ -> m
144 merging rev
144 merging rev
145 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
145 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
146 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
146 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
147 (branch merge, don't forget to commit)
147 (branch merge, don't forget to commit)
148 --------------
148 --------------
149 C b
149 C b
150 --------------
150 --------------
151
151
152 --------------
152 --------------
153 test L:um a b R:um a b W: - 9 do merge with ancestor in a
153 test L:um a b R:um a b W: - 9 do merge with ancestor in a
154 --------------
154 --------------
155 resolving manifests
155 resolving manifests
156 overwrite None partial False
156 overwrite None partial False
157 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
157 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
158 b: versions differ -> m
158 b: versions differ -> m
159 rev: versions differ -> m
159 rev: versions differ -> m
160 merging b
160 merging b
161 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
161 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
162 merging rev
162 merging rev
163 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
163 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
164 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
164 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
165 (branch merge, don't forget to commit)
165 (branch merge, don't forget to commit)
166 --------------
166 --------------
167 M b
167 M b
168 --------------
168 --------------
169
169
170 --------------
170 --------------
171 test L:nm a b R:nm a c W: - 11 get c, keep b
171 test L:nm a b R:nm a c W: - 11 get c, keep b
172 --------------
172 --------------
173 resolving manifests
173 resolving manifests
174 overwrite None partial False
174 overwrite None partial False
175 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
175 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
176 rev: versions differ -> m
176 rev: versions differ -> m
177 c: remote created -> g
177 c: remote created -> g
178 getting c
178 getting c
179 merging rev
179 merging rev
180 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
180 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
181 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
181 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
182 (branch merge, don't forget to commit)
182 (branch merge, don't forget to commit)
183 --------------
183 --------------
184 M c
184 M c
185 C b
185 C b
186 --------------
186 --------------
187
187
188 --------------
188 --------------
189 test L:nc a b R:up b W: - 12 merge b no ancestor
189 test L:nc a b R:up b W: - 12 merge b no ancestor
190 --------------
190 --------------
191 resolving manifests
191 resolving manifests
192 overwrite None partial False
192 overwrite None partial False
193 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
193 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
194 b: versions differ -> m
194 b: versions differ -> m
195 rev: versions differ -> m
195 rev: versions differ -> m
196 merging b
196 merging b
197 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
197 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
198 merging rev
198 merging rev
199 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
199 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
200 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
200 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
201 (branch merge, don't forget to commit)
201 (branch merge, don't forget to commit)
202 --------------
202 --------------
203 M b
203 M b
204 C a
204 C a
205 --------------
205 --------------
206
206
207 --------------
207 --------------
208 test L:up b R:nm a b W: - 13 merge b no ancestor
208 test L:up b R:nm a b W: - 13 merge b no ancestor
209 --------------
209 --------------
210 resolving manifests
210 resolving manifests
211 overwrite None partial False
211 overwrite None partial False
212 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
212 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
213 a: other deleted -> r
213 a: other deleted -> r
214 b: versions differ -> m
214 b: versions differ -> m
215 rev: versions differ -> m
215 rev: versions differ -> m
216 removing a
216 removing a
217 merging b
217 merging b
218 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
218 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
219 merging rev
219 merging rev
220 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
220 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
221 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
221 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
222 (branch merge, don't forget to commit)
222 (branch merge, don't forget to commit)
223 --------------
223 --------------
224 M b
224 M b
225 --------------
225 --------------
226
226
227 --------------
227 --------------
228 test L:nc a b R:up a b W: - 14 merge b no ancestor
228 test L:nc a b R:up a b W: - 14 merge b no ancestor
229 --------------
229 --------------
230 resolving manifests
230 resolving manifests
231 overwrite None partial False
231 overwrite None partial False
232 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
232 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
233 a: remote is newer -> g
233 a: remote is newer -> g
234 b: versions differ -> m
234 b: versions differ -> m
235 rev: versions differ -> m
235 rev: versions differ -> m
236 getting a
236 getting a
237 merging b
237 merging b
238 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
238 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
239 merging rev
239 merging rev
240 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
240 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
241 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
241 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
242 (branch merge, don't forget to commit)
242 (branch merge, don't forget to commit)
243 --------------
243 --------------
244 M a
244 M a
245 M b
245 M b
246 --------------
246 --------------
247
247
248 --------------
248 --------------
249 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
249 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
250 --------------
250 --------------
251 resolving manifests
251 resolving manifests
252 overwrite None partial False
252 overwrite None partial False
253 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
253 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
254 a: other deleted -> r
254 a: other deleted -> r
255 b: versions differ -> m
255 b: versions differ -> m
256 rev: versions differ -> m
256 rev: versions differ -> m
257 removing a
257 removing a
258 merging b
258 merging b
259 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
259 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
260 merging rev
260 merging rev
261 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
261 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
262 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
262 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
263 (branch merge, don't forget to commit)
263 (branch merge, don't forget to commit)
264 --------------
264 --------------
265 M b
265 M b
266 --------------
266 --------------
267
267
268 --------------
268 --------------
269 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
269 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
270 --------------
270 --------------
271 resolving manifests
271 resolving manifests
272 overwrite None partial False
272 overwrite None partial False
273 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
273 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
274 a: remote is newer -> g
274 a: remote is newer -> g
275 b: versions differ -> m
275 b: versions differ -> m
276 rev: versions differ -> m
276 rev: versions differ -> m
277 getting a
277 getting a
278 merging b
278 merging b
279 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
279 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
280 merging rev
280 merging rev
281 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
281 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
282 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
282 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
283 (branch merge, don't forget to commit)
283 (branch merge, don't forget to commit)
284 --------------
284 --------------
285 M a
285 M a
286 M b
286 M b
287 --------------
287 --------------
288
288
289 --------------
289 --------------
290 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
290 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
291 --------------
291 --------------
292 resolving manifests
292 resolving manifests
293 overwrite None partial False
293 overwrite None partial False
294 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
294 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
295 b: versions differ -> m
295 b: versions differ -> m
296 rev: versions differ -> m
296 rev: versions differ -> m
297 merging b
297 merging b
298 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
298 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
299 merging rev
299 merging rev
300 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
300 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
301 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
301 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
302 (branch merge, don't forget to commit)
302 (branch merge, don't forget to commit)
303 --------------
303 --------------
304 M b
304 M b
305 C a
305 C a
306 --------------
306 --------------
307
307
308 --------------
308 --------------
309 test L:nm a b R:up a b W: - 18 merge b no ancestor
309 test L:nm a b R:up a b W: - 18 merge b no ancestor
310 --------------
310 --------------
311 resolving manifests
311 resolving manifests
312 overwrite None partial False
312 overwrite None partial False
313 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
313 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
314 b: versions differ -> m
314 b: versions differ -> m
315 rev: versions differ -> m
315 rev: versions differ -> m
316 a: prompt recreating -> g
316 a: prompt recreating -> g
317 getting a
317 getting a
318 merging b
318 merging b
319 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
319 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
320 merging rev
320 merging rev
321 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
321 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
322 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
322 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
323 (branch merge, don't forget to commit)
323 (branch merge, don't forget to commit)
324 --------------
324 --------------
325 M a
325 M a
326 M b
326 M b
327 --------------
327 --------------
328
328
329 --------------
329 --------------
330 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
330 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
331 --------------
331 --------------
332 resolving manifests
332 resolving manifests
333 overwrite None partial False
333 overwrite None partial False
334 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
334 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
335 b: versions differ -> m
335 b: versions differ -> m
336 rev: versions differ -> m
336 rev: versions differ -> m
337 merging b
337 merging b
338 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
338 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
339 merging rev
339 merging rev
340 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
340 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
341 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
341 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
342 (branch merge, don't forget to commit)
342 (branch merge, don't forget to commit)
343 --------------
343 --------------
344 M b
344 M b
345 C a
345 C a
346 --------------
346 --------------
347
347
348 --------------
348 --------------
349 test L:up a R:um a b W: - 20 merge a and b to b, remove a
349 test L:up a R:um a b W: - 20 merge a and b to b, remove a
350 --------------
350 --------------
351 resolving manifests
351 resolving manifests
352 overwrite None partial False
352 overwrite None partial False
353 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
353 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
354 rev: versions differ -> m
354 a: remote moved to b -> m
355 a: remote moved to b -> m
355 rev: versions differ -> m
356 merging a and b
356 merging a and b
357 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
357 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
358 copying a to b
358 copying a to b
359 removing a
359 removing a
360 merging rev
360 merging rev
361 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
361 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
362 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
362 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
363 (branch merge, don't forget to commit)
363 (branch merge, don't forget to commit)
364 --------------
364 --------------
365 M b
365 M b
366 a
366 a
367 --------------
367 --------------
368
368
369 --------------
369 --------------
370 test L:um a b R:up a W: - 21 merge a and b to b
370 test L:um a b R:up a W: - 21 merge a and b to b
371 --------------
371 --------------
372 resolving manifests
372 resolving manifests
373 overwrite None partial False
373 overwrite None partial False
374 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
374 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
375 b: local moved to a -> m
375 b: local moved to a -> m
376 rev: versions differ -> m
376 rev: versions differ -> m
377 merging b and a
377 merging b and a
378 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
378 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
379 merging rev
379 merging rev
380 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
380 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
381 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
381 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
382 (branch merge, don't forget to commit)
382 (branch merge, don't forget to commit)
383 --------------
383 --------------
384 M b
384 M b
385 a
385 a
386 --------------
386 --------------
387
387
388 --------------
388 --------------
389 test L:nm a b R:up a c W: - 23 get c, keep b
389 test L:nm a b R:up a c W: - 23 get c, keep b
390 --------------
390 --------------
391 resolving manifests
391 resolving manifests
392 overwrite None partial False
392 overwrite None partial False
393 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
393 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
394 b: local moved to a -> m
394 b: local moved to a -> m
395 rev: versions differ -> m
395 rev: versions differ -> m
396 c: remote created -> g
396 c: remote created -> g
397 merging b and a
397 merging b and a
398 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
398 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
399 getting c
399 getting c
400 merging rev
400 merging rev
401 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
401 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
402 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
402 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
403 (branch merge, don't forget to commit)
403 (branch merge, don't forget to commit)
404 --------------
404 --------------
405 M b
405 M b
406 a
406 a
407 M c
407 M c
408 --------------
408 --------------
409
409
General Comments 0
You need to be logged in to leave comments. Login now