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