##// END OF EJS Templates
merge: make 'diverging renames' diagnostic a more helpful note....
Dan Villiom Podlaski Christiansen -
r12757:62c8f769 default
parent child Browse files
Show More
@@ -1,543 +1,544 b''
1 1 # merge.py - directory-level update/merge handling for Mercurial
2 2 #
3 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from node import nullid, nullrev, hex, bin
9 9 from i18n import _
10 10 import util, filemerge, copies, subrepo
11 11 import errno, os, shutil
12 12
13 13 class mergestate(object):
14 14 '''track 3-way merge state of individual files'''
15 15 def __init__(self, repo):
16 16 self._repo = repo
17 17 self._dirty = False
18 18 self._read()
19 19 def reset(self, node=None):
20 20 self._state = {}
21 21 if node:
22 22 self._local = node
23 23 shutil.rmtree(self._repo.join("merge"), True)
24 24 self._dirty = False
25 25 def _read(self):
26 26 self._state = {}
27 27 try:
28 28 f = self._repo.opener("merge/state")
29 29 for i, l in enumerate(f):
30 30 if i == 0:
31 31 self._local = bin(l[:-1])
32 32 else:
33 33 bits = l[:-1].split("\0")
34 34 self._state[bits[0]] = bits[1:]
35 35 except IOError, err:
36 36 if err.errno != errno.ENOENT:
37 37 raise
38 38 self._dirty = False
39 39 def commit(self):
40 40 if self._dirty:
41 41 f = self._repo.opener("merge/state", "w")
42 42 f.write(hex(self._local) + "\n")
43 43 for d, v in self._state.iteritems():
44 44 f.write("\0".join([d] + v) + "\n")
45 45 self._dirty = False
46 46 def add(self, fcl, fco, fca, fd, flags):
47 47 hash = util.sha1(fcl.path()).hexdigest()
48 48 self._repo.opener("merge/" + hash, "w").write(fcl.data())
49 49 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
50 50 hex(fca.filenode()), fco.path(), flags]
51 51 self._dirty = True
52 52 def __contains__(self, dfile):
53 53 return dfile in self._state
54 54 def __getitem__(self, dfile):
55 55 return self._state[dfile][0]
56 56 def __iter__(self):
57 57 l = self._state.keys()
58 58 l.sort()
59 59 for f in l:
60 60 yield f
61 61 def mark(self, dfile, state):
62 62 self._state[dfile][0] = state
63 63 self._dirty = True
64 64 def resolve(self, dfile, wctx, octx):
65 65 if self[dfile] == 'r':
66 66 return 0
67 67 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
68 68 f = self._repo.opener("merge/" + hash)
69 69 self._repo.wwrite(dfile, f.read(), flags)
70 70 fcd = wctx[dfile]
71 71 fco = octx[ofile]
72 72 fca = self._repo.filectx(afile, fileid=anode)
73 73 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
74 74 if not r:
75 75 self.mark(dfile, 'r')
76 76 return r
77 77
78 78 def _checkunknown(wctx, mctx):
79 79 "check for collisions between unknown files and files in mctx"
80 80 for f in wctx.unknown():
81 81 if f in mctx and mctx[f].cmp(wctx[f]):
82 82 raise util.Abort(_("untracked file in working directory differs"
83 83 " from file in requested revision: '%s'") % f)
84 84
85 85 def _checkcollision(mctx):
86 86 "check for case folding collisions in the destination context"
87 87 folded = {}
88 88 for fn in mctx:
89 89 fold = fn.lower()
90 90 if fold in folded:
91 91 raise util.Abort(_("case-folding collision between %s and %s")
92 92 % (fn, folded[fold]))
93 93 folded[fold] = fn
94 94
95 95 def _forgetremoved(wctx, mctx, branchmerge):
96 96 """
97 97 Forget removed files
98 98
99 99 If we're jumping between revisions (as opposed to merging), and if
100 100 neither the working directory nor the target rev has the file,
101 101 then we need to remove it from the dirstate, to prevent the
102 102 dirstate from listing the file when it is no longer in the
103 103 manifest.
104 104
105 105 If we're merging, and the other revision has removed a file
106 106 that is not present in the working directory, we need to mark it
107 107 as removed.
108 108 """
109 109
110 110 action = []
111 111 state = branchmerge and 'r' or 'f'
112 112 for f in wctx.deleted():
113 113 if f not in mctx:
114 114 action.append((f, state))
115 115
116 116 if not branchmerge:
117 117 for f in wctx.removed():
118 118 if f not in mctx:
119 119 action.append((f, "f"))
120 120
121 121 return action
122 122
123 123 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
124 124 """
125 125 Merge p1 and p2 with ancestor pa and generate merge action list
126 126
127 127 overwrite = whether we clobber working files
128 128 partial = function to filter file lists
129 129 """
130 130
131 131 def fmerge(f, f2, fa):
132 132 """merge flags"""
133 133 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
134 134 if m == n: # flags agree
135 135 return m # unchanged
136 136 if m and n and not a: # flags set, don't agree, differ from parent
137 137 r = repo.ui.promptchoice(
138 138 _(" conflicting flags for %s\n"
139 139 "(n)one, e(x)ec or sym(l)ink?") % f,
140 140 (_("&None"), _("E&xec"), _("Sym&link")), 0)
141 141 if r == 1:
142 142 return "x" # Exec
143 143 if r == 2:
144 144 return "l" # Symlink
145 145 return ""
146 146 if m and m != a: # changed from a to m
147 147 return m
148 148 if n and n != a: # changed from a to n
149 149 return n
150 150 return '' # flag was cleared
151 151
152 152 def act(msg, m, f, *args):
153 153 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
154 154 action.append((f, m) + args)
155 155
156 156 action, copy = [], {}
157 157
158 158 if overwrite:
159 159 pa = p1
160 160 elif pa == p2: # backwards
161 161 pa = p1.p1()
162 162 elif pa and repo.ui.configbool("merge", "followcopies", True):
163 163 dirs = repo.ui.configbool("merge", "followdirs", True)
164 164 copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
165 165 for of, fl in diverge.iteritems():
166 166 act("divergent renames", "dr", of, fl)
167 167
168 168 repo.ui.note(_("resolving manifests\n"))
169 169 repo.ui.debug(" overwrite %s partial %s\n" % (overwrite, bool(partial)))
170 170 repo.ui.debug(" ancestor %s local %s remote %s\n" % (pa, p1, p2))
171 171
172 172 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
173 173 copied = set(copy.values())
174 174
175 175 if '.hgsubstate' in m1:
176 176 # check whether sub state is modified
177 177 for s in p1.substate:
178 178 if p1.sub(s).dirty():
179 179 m1['.hgsubstate'] += "+"
180 180 break
181 181
182 182 # Compare manifests
183 183 for f, n in m1.iteritems():
184 184 if partial and not partial(f):
185 185 continue
186 186 if f in m2:
187 187 rflags = fmerge(f, f, f)
188 188 a = ma.get(f, nullid)
189 189 if n == m2[f] or m2[f] == a: # same or local newer
190 190 # is file locally modified or flags need changing?
191 191 # dirstate flags may need to be made current
192 192 if m1.flags(f) != rflags or n[20:]:
193 193 act("update permissions", "e", f, rflags)
194 194 elif n == a: # remote newer
195 195 act("remote is newer", "g", f, rflags)
196 196 else: # both changed
197 197 act("versions differ", "m", f, f, f, rflags, False)
198 198 elif f in copied: # files we'll deal with on m2 side
199 199 pass
200 200 elif f in copy:
201 201 f2 = copy[f]
202 202 if f2 not in m2: # directory rename
203 203 act("remote renamed directory to " + f2, "d",
204 204 f, None, f2, m1.flags(f))
205 205 else: # case 2 A,B/B/B or case 4,21 A/B/B
206 206 act("local copied/moved to " + f2, "m",
207 207 f, f2, f, fmerge(f, f2, f2), False)
208 208 elif f in ma: # clean, a different, no remote
209 209 if n != ma[f]:
210 210 if repo.ui.promptchoice(
211 211 _(" local changed %s which remote deleted\n"
212 212 "use (c)hanged version or (d)elete?") % f,
213 213 (_("&Changed"), _("&Delete")), 0):
214 214 act("prompt delete", "r", f)
215 215 else:
216 216 act("prompt keep", "a", f)
217 217 elif n[20:] == "a": # added, no remote
218 218 act("remote deleted", "f", f)
219 219 elif n[20:] != "u":
220 220 act("other deleted", "r", f)
221 221
222 222 for f, n in m2.iteritems():
223 223 if partial and not partial(f):
224 224 continue
225 225 if f in m1 or f in copied: # files already visited
226 226 continue
227 227 if f in copy:
228 228 f2 = copy[f]
229 229 if f2 not in m1: # directory rename
230 230 act("local renamed directory to " + f2, "d",
231 231 None, f, f2, m2.flags(f))
232 232 elif f2 in m2: # rename case 1, A/A,B/A
233 233 act("remote copied to " + f, "m",
234 234 f2, f, f, fmerge(f2, f, f2), False)
235 235 else: # case 3,20 A/B/A
236 236 act("remote moved to " + f, "m",
237 237 f2, f, f, fmerge(f2, f, f2), True)
238 238 elif f not in ma:
239 239 act("remote created", "g", f, m2.flags(f))
240 240 elif n != ma[f]:
241 241 if repo.ui.promptchoice(
242 242 _("remote changed %s which local deleted\n"
243 243 "use (c)hanged version or leave (d)eleted?") % f,
244 244 (_("&Changed"), _("&Deleted")), 0) == 0:
245 245 act("prompt recreating", "g", f, m2.flags(f))
246 246
247 247 return action
248 248
249 249 def actionkey(a):
250 250 return a[1] == 'r' and -1 or 0, a
251 251
252 252 def applyupdates(repo, action, wctx, mctx, actx):
253 253 """apply the merge action list to the working directory
254 254
255 255 wctx is the working copy context
256 256 mctx is the context to be merged into the working copy
257 257 actx is the context of the common ancestor
258 258 """
259 259
260 260 updated, merged, removed, unresolved = 0, 0, 0, 0
261 261 ms = mergestate(repo)
262 262 ms.reset(wctx.parents()[0].node())
263 263 moves = []
264 264 action.sort(key=actionkey)
265 265 substate = wctx.substate # prime
266 266
267 267 # prescan for merges
268 268 u = repo.ui
269 269 for a in action:
270 270 f, m = a[:2]
271 271 if m == 'm': # merge
272 272 f2, fd, flags, move = a[2:]
273 273 if f == '.hgsubstate': # merged internally
274 274 continue
275 275 repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
276 276 fcl = wctx[f]
277 277 fco = mctx[f2]
278 278 if mctx == actx: # backwards, use working dir parent as ancestor
279 279 if fcl.parents():
280 280 fca = fcl.parents()[0]
281 281 else:
282 282 fca = repo.filectx(f, fileid=nullrev)
283 283 else:
284 284 fca = fcl.ancestor(fco, actx)
285 285 if not fca:
286 286 fca = repo.filectx(f, fileid=nullrev)
287 287 ms.add(fcl, fco, fca, fd, flags)
288 288 if f != fd and move:
289 289 moves.append(f)
290 290
291 291 # remove renamed files after safely stored
292 292 for f in moves:
293 293 if os.path.lexists(repo.wjoin(f)):
294 294 repo.ui.debug("removing %s\n" % f)
295 295 os.unlink(repo.wjoin(f))
296 296
297 297 audit_path = util.path_auditor(repo.root)
298 298
299 299 numupdates = len(action)
300 300 for i, a in enumerate(action):
301 301 f, m = a[:2]
302 302 u.progress(_('updating'), i + 1, item=f, total=numupdates,
303 303 unit=_('files'))
304 304 if f and f[0] == "/":
305 305 continue
306 306 if m == "r": # remove
307 307 repo.ui.note(_("removing %s\n") % f)
308 308 audit_path(f)
309 309 if f == '.hgsubstate': # subrepo states need updating
310 310 subrepo.submerge(repo, wctx, mctx, wctx)
311 311 try:
312 312 util.unlink(repo.wjoin(f))
313 313 except OSError, inst:
314 314 if inst.errno != errno.ENOENT:
315 315 repo.ui.warn(_("update failed to remove %s: %s!\n") %
316 316 (f, inst.strerror))
317 317 removed += 1
318 318 elif m == "m": # merge
319 319 if f == '.hgsubstate': # subrepo states need updating
320 320 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx))
321 321 continue
322 322 f2, fd, flags, move = a[2:]
323 323 r = ms.resolve(fd, wctx, mctx)
324 324 if r is not None and r > 0:
325 325 unresolved += 1
326 326 else:
327 327 if r is None:
328 328 updated += 1
329 329 else:
330 330 merged += 1
331 331 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
332 332 if f != fd and move and os.path.lexists(repo.wjoin(f)):
333 333 repo.ui.debug("removing %s\n" % f)
334 334 os.unlink(repo.wjoin(f))
335 335 elif m == "g": # get
336 336 flags = a[2]
337 337 repo.ui.note(_("getting %s\n") % f)
338 338 t = mctx.filectx(f).data()
339 339 repo.wwrite(f, t, flags)
340 340 t = None
341 341 updated += 1
342 342 if f == '.hgsubstate': # subrepo states need updating
343 343 subrepo.submerge(repo, wctx, mctx, wctx)
344 344 elif m == "d": # directory rename
345 345 f2, fd, flags = a[2:]
346 346 if f:
347 347 repo.ui.note(_("moving %s to %s\n") % (f, fd))
348 348 t = wctx.filectx(f).data()
349 349 repo.wwrite(fd, t, flags)
350 350 util.unlink(repo.wjoin(f))
351 351 if f2:
352 352 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
353 353 t = mctx.filectx(f2).data()
354 354 repo.wwrite(fd, t, flags)
355 355 updated += 1
356 356 elif m == "dr": # divergent renames
357 357 fl = a[2]
358 repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
358 repo.ui.warn(_("note: possible conflict - %s was renamed "
359 "multiple times to:\n") % f)
359 360 for nf in fl:
360 361 repo.ui.warn(" %s\n" % nf)
361 362 elif m == "e": # exec
362 363 flags = a[2]
363 364 util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
364 365 ms.commit()
365 366 u.progress(_('updating'), None, total=numupdates, unit=_('files'))
366 367
367 368 return updated, merged, removed, unresolved
368 369
369 370 def recordupdates(repo, action, branchmerge):
370 371 "record merge actions to the dirstate"
371 372
372 373 for a in action:
373 374 f, m = a[:2]
374 375 if m == "r": # remove
375 376 if branchmerge:
376 377 repo.dirstate.remove(f)
377 378 else:
378 379 repo.dirstate.forget(f)
379 380 elif m == "a": # re-add
380 381 if not branchmerge:
381 382 repo.dirstate.add(f)
382 383 elif m == "f": # forget
383 384 repo.dirstate.forget(f)
384 385 elif m == "e": # exec change
385 386 repo.dirstate.normallookup(f)
386 387 elif m == "g": # get
387 388 if branchmerge:
388 389 repo.dirstate.otherparent(f)
389 390 else:
390 391 repo.dirstate.normal(f)
391 392 elif m == "m": # merge
392 393 f2, fd, flag, move = a[2:]
393 394 if branchmerge:
394 395 # We've done a branch merge, mark this file as merged
395 396 # so that we properly record the merger later
396 397 repo.dirstate.merge(fd)
397 398 if f != f2: # copy/rename
398 399 if move:
399 400 repo.dirstate.remove(f)
400 401 if f != fd:
401 402 repo.dirstate.copy(f, fd)
402 403 else:
403 404 repo.dirstate.copy(f2, fd)
404 405 else:
405 406 # We've update-merged a locally modified file, so
406 407 # we set the dirstate to emulate a normal checkout
407 408 # of that file some time in the past. Thus our
408 409 # merge will appear as a normal local file
409 410 # modification.
410 411 if f2 == fd: # file not locally copied/moved
411 412 repo.dirstate.normallookup(fd)
412 413 if move:
413 414 repo.dirstate.forget(f)
414 415 elif m == "d": # directory rename
415 416 f2, fd, flag = a[2:]
416 417 if not f2 and f not in repo.dirstate:
417 418 # untracked file moved
418 419 continue
419 420 if branchmerge:
420 421 repo.dirstate.add(fd)
421 422 if f:
422 423 repo.dirstate.remove(f)
423 424 repo.dirstate.copy(f, fd)
424 425 if f2:
425 426 repo.dirstate.copy(f2, fd)
426 427 else:
427 428 repo.dirstate.normal(fd)
428 429 if f:
429 430 repo.dirstate.forget(f)
430 431
431 432 def update(repo, node, branchmerge, force, partial):
432 433 """
433 434 Perform a merge between the working directory and the given node
434 435
435 436 node = the node to update to, or None if unspecified
436 437 branchmerge = whether to merge between branches
437 438 force = whether to force branch merging or file overwriting
438 439 partial = a function to filter file lists (dirstate not updated)
439 440
440 441 The table below shows all the behaviors of the update command
441 442 given the -c and -C or no options, whether the working directory
442 443 is dirty, whether a revision is specified, and the relationship of
443 444 the parent rev to the target rev (linear, on the same named
444 445 branch, or on another named branch).
445 446
446 447 This logic is tested by test-update-branches.t.
447 448
448 449 -c -C dirty rev | linear same cross
449 450 n n n n | ok (1) x
450 451 n n n y | ok ok ok
451 452 n n y * | merge (2) (2)
452 453 n y * * | --- discard ---
453 454 y n y * | --- (3) ---
454 455 y n n * | --- ok ---
455 456 y y * * | --- (4) ---
456 457
457 458 x = can't happen
458 459 * = don't-care
459 460 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
460 461 2 = abort: crosses branches (use 'hg merge' to merge or
461 462 use 'hg update -C' to discard changes)
462 463 3 = abort: uncommitted local changes
463 464 4 = incompatible options (checked in commands.py)
464 465 """
465 466
466 467 onode = node
467 468 wlock = repo.wlock()
468 469 try:
469 470 wc = repo[None]
470 471 if node is None:
471 472 # tip of current branch
472 473 try:
473 474 node = repo.branchtags()[wc.branch()]
474 475 except KeyError:
475 476 if wc.branch() == "default": # no default branch!
476 477 node = repo.lookup("tip") # update to tip
477 478 else:
478 479 raise util.Abort(_("branch %s not found") % wc.branch())
479 480 overwrite = force and not branchmerge
480 481 pl = wc.parents()
481 482 p1, p2 = pl[0], repo[node]
482 483 pa = p1.ancestor(p2)
483 484 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
484 485 fastforward = False
485 486
486 487 ### check phase
487 488 if not overwrite and len(pl) > 1:
488 489 raise util.Abort(_("outstanding uncommitted merges"))
489 490 if branchmerge:
490 491 if pa == p2:
491 492 raise util.Abort(_("merging with a working directory ancestor"
492 493 " has no effect"))
493 494 elif pa == p1:
494 495 if p1.branch() != p2.branch():
495 496 fastforward = True
496 497 else:
497 498 raise util.Abort(_("nothing to merge (use 'hg update'"
498 499 " or check 'hg heads')"))
499 500 if not force and (wc.files() or wc.deleted()):
500 501 raise util.Abort(_("outstanding uncommitted changes "
501 502 "(use 'hg status' to list changes)"))
502 503 elif not overwrite:
503 504 if pa == p1 or pa == p2: # linear
504 505 pass # all good
505 506 elif wc.files() or wc.deleted():
506 507 raise util.Abort(_("crosses branches (merge branches or use"
507 508 " --clean to discard changes)"))
508 509 elif onode is None:
509 510 raise util.Abort(_("crosses branches (merge branches or use"
510 511 " --check to force update)"))
511 512 else:
512 513 # Allow jumping branches if clean and specific rev given
513 514 overwrite = True
514 515
515 516 ### calculate phase
516 517 action = []
517 518 wc.status(unknown=True) # prime cache
518 519 if not force:
519 520 _checkunknown(wc, p2)
520 521 if not util.checkcase(repo.path):
521 522 _checkcollision(p2)
522 523 action += _forgetremoved(wc, p2, branchmerge)
523 524 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
524 525
525 526 ### apply phase
526 527 if not branchmerge: # just jump to the new rev
527 528 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
528 529 if not partial:
529 530 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
530 531
531 532 stats = applyupdates(repo, action, wc, p2, pa)
532 533
533 534 if not partial:
534 535 repo.dirstate.setparents(fp1, fp2)
535 536 recordupdates(repo, action, branchmerge)
536 537 if not branchmerge and not fastforward:
537 538 repo.dirstate.setbranch(p2.branch())
538 539 finally:
539 540 wlock.release()
540 541
541 542 if not partial:
542 543 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
543 544 return stats
@@ -1,372 +1,372 b''
1 1 $ hg init test
2 2 $ cd test
3 3 $ echo "0" >> afile
4 4 $ hg add afile
5 5 $ hg commit -m "0.0"
6 6 $ echo "1" >> afile
7 7 $ hg commit -m "0.1"
8 8 $ echo "2" >> afile
9 9 $ hg commit -m "0.2"
10 10 $ echo "3" >> afile
11 11 $ hg commit -m "0.3"
12 12 $ hg update -C 0
13 13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 14 $ echo "1" >> afile
15 15 $ hg commit -m "1.1"
16 16 created new head
17 17 $ echo "2" >> afile
18 18 $ hg commit -m "1.2"
19 19 $ echo "a line" > fred
20 20 $ echo "3" >> afile
21 21 $ hg add fred
22 22 $ hg commit -m "1.3"
23 23 $ hg mv afile adifferentfile
24 24 $ hg commit -m "1.3m"
25 25 $ hg update -C 3
26 26 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
27 27 $ hg mv afile anotherfile
28 28 $ hg commit -m "0.3m"
29 29 $ hg debugindex .hg/store/data/afile.i
30 30 rev offset length base linkrev nodeid p1 p2
31 31 0 0 3 0 0 362fef284ce2 000000000000 000000000000
32 32 1 3 5 1 1 125144f7e028 362fef284ce2 000000000000
33 33 2 8 7 2 2 4c982badb186 125144f7e028 000000000000
34 34 3 15 9 3 3 19b1fc555737 4c982badb186 000000000000
35 35 $ hg debugindex .hg/store/data/adifferentfile.i
36 36 rev offset length base linkrev nodeid p1 p2
37 37 0 0 75 0 7 2565f3199a74 000000000000 000000000000
38 38 $ hg debugindex .hg/store/data/anotherfile.i
39 39 rev offset length base linkrev nodeid p1 p2
40 40 0 0 75 0 8 2565f3199a74 000000000000 000000000000
41 41 $ hg debugindex .hg/store/data/fred.i
42 42 rev offset length base linkrev nodeid p1 p2
43 43 0 0 8 0 6 12ab3bcc5ea4 000000000000 000000000000
44 44 $ hg debugindex .hg/store/00manifest.i
45 45 rev offset length base linkrev nodeid p1 p2
46 46 0 0 48 0 0 43eadb1d2d06 000000000000 000000000000
47 47 1 48 48 1 1 8b89697eba2c 43eadb1d2d06 000000000000
48 48 2 96 48 2 2 626a32663c2f 8b89697eba2c 000000000000
49 49 3 144 48 3 3 f54c32f13478 626a32663c2f 000000000000
50 50 4 192 58 3 6 de68e904d169 626a32663c2f 000000000000
51 51 5 250 68 3 7 09bb521d218d de68e904d169 000000000000
52 52 6 318 54 6 8 1fde233dfb0f f54c32f13478 000000000000
53 53 $ hg verify
54 54 checking changesets
55 55 checking manifests
56 56 crosschecking files in changesets and manifests
57 57 checking files
58 58 4 files, 9 changesets, 7 total revisions
59 59 $ cd ..
60 60 $ for i in 0 1 2 3 4 5 6 7 8; do
61 61 > mkdir test-"$i"
62 62 > hg --cwd test-"$i" init
63 63 > hg -R test bundle -r "$i" test-"$i".hg test-"$i"
64 64 > cd test-"$i"
65 65 > hg unbundle ../test-"$i".hg
66 66 > hg verify
67 67 > hg tip -q
68 68 > cd ..
69 69 > done
70 70 searching for changes
71 71 1 changesets found
72 72 adding changesets
73 73 adding manifests
74 74 adding file changes
75 75 added 1 changesets with 1 changes to 1 files
76 76 (run 'hg update' to get a working copy)
77 77 checking changesets
78 78 checking manifests
79 79 crosschecking files in changesets and manifests
80 80 checking files
81 81 1 files, 1 changesets, 1 total revisions
82 82 0:f9ee2f85a263
83 83 searching for changes
84 84 2 changesets found
85 85 adding changesets
86 86 adding manifests
87 87 adding file changes
88 88 added 2 changesets with 2 changes to 1 files
89 89 (run 'hg update' to get a working copy)
90 90 checking changesets
91 91 checking manifests
92 92 crosschecking files in changesets and manifests
93 93 checking files
94 94 1 files, 2 changesets, 2 total revisions
95 95 1:34c2bf6b0626
96 96 searching for changes
97 97 3 changesets found
98 98 adding changesets
99 99 adding manifests
100 100 adding file changes
101 101 added 3 changesets with 3 changes to 1 files
102 102 (run 'hg update' to get a working copy)
103 103 checking changesets
104 104 checking manifests
105 105 crosschecking files in changesets and manifests
106 106 checking files
107 107 1 files, 3 changesets, 3 total revisions
108 108 2:e38ba6f5b7e0
109 109 searching for changes
110 110 4 changesets found
111 111 adding changesets
112 112 adding manifests
113 113 adding file changes
114 114 added 4 changesets with 4 changes to 1 files
115 115 (run 'hg update' to get a working copy)
116 116 checking changesets
117 117 checking manifests
118 118 crosschecking files in changesets and manifests
119 119 checking files
120 120 1 files, 4 changesets, 4 total revisions
121 121 3:eebf5a27f8ca
122 122 searching for changes
123 123 2 changesets found
124 124 adding changesets
125 125 adding manifests
126 126 adding file changes
127 127 added 2 changesets with 2 changes to 1 files
128 128 (run 'hg update' to get a working copy)
129 129 checking changesets
130 130 checking manifests
131 131 crosschecking files in changesets and manifests
132 132 checking files
133 133 1 files, 2 changesets, 2 total revisions
134 134 1:095197eb4973
135 135 searching for changes
136 136 3 changesets found
137 137 adding changesets
138 138 adding manifests
139 139 adding file changes
140 140 added 3 changesets with 3 changes to 1 files
141 141 (run 'hg update' to get a working copy)
142 142 checking changesets
143 143 checking manifests
144 144 crosschecking files in changesets and manifests
145 145 checking files
146 146 1 files, 3 changesets, 3 total revisions
147 147 2:1bb50a9436a7
148 148 searching for changes
149 149 4 changesets found
150 150 adding changesets
151 151 adding manifests
152 152 adding file changes
153 153 added 4 changesets with 5 changes to 2 files
154 154 (run 'hg update' to get a working copy)
155 155 checking changesets
156 156 checking manifests
157 157 crosschecking files in changesets and manifests
158 158 checking files
159 159 2 files, 4 changesets, 5 total revisions
160 160 3:7373c1169842
161 161 searching for changes
162 162 5 changesets found
163 163 adding changesets
164 164 adding manifests
165 165 adding file changes
166 166 added 5 changesets with 6 changes to 3 files
167 167 (run 'hg update' to get a working copy)
168 168 checking changesets
169 169 checking manifests
170 170 crosschecking files in changesets and manifests
171 171 checking files
172 172 3 files, 5 changesets, 6 total revisions
173 173 4:a6a34bfa0076
174 174 searching for changes
175 175 5 changesets found
176 176 adding changesets
177 177 adding manifests
178 178 adding file changes
179 179 added 5 changesets with 5 changes to 2 files
180 180 (run 'hg update' to get a working copy)
181 181 checking changesets
182 182 checking manifests
183 183 crosschecking files in changesets and manifests
184 184 checking files
185 185 2 files, 5 changesets, 5 total revisions
186 186 4:aa35859c02ea
187 187 $ cd test-8
188 188 $ hg pull ../test-7
189 189 pulling from ../test-7
190 190 searching for changes
191 191 adding changesets
192 192 adding manifests
193 193 adding file changes
194 194 added 4 changesets with 2 changes to 3 files (+1 heads)
195 195 (run 'hg heads' to see heads, 'hg merge' to merge)
196 196 $ hg verify
197 197 checking changesets
198 198 checking manifests
199 199 crosschecking files in changesets and manifests
200 200 checking files
201 201 4 files, 9 changesets, 7 total revisions
202 202 $ hg rollback
203 203 rolling back to revision 4 (undo pull)
204 204 $ cd ..
205 205
206 206 should fail
207 207
208 208 $ hg -R test bundle --base 2 -r tip test-bundle-branch1.hg test-3
209 209 abort: --base is incompatible with specifying a destination
210 210 [255]
211 211 $ hg -R test bundle -r tip test-bundle-branch1.hg
212 212 abort: repository default-push not found!
213 213 [255]
214 214
215 215 $ hg -R test bundle --base 2 -r tip test-bundle-branch1.hg
216 216 2 changesets found
217 217 $ hg -R test bundle --base 2 -r 7 test-bundle-branch2.hg
218 218 4 changesets found
219 219 $ hg -R test bundle --base 2 test-bundle-all.hg
220 220 6 changesets found
221 221 $ hg -R test bundle --base 3 -r tip test-bundle-should-fail.hg
222 222 1 changesets found
223 223
224 224 empty bundle
225 225
226 226 $ hg -R test bundle --base 7 --base 8 test-bundle-empty.hg
227 227 no changes found
228 228 [1]
229 229
230 230 issue76 msg2163
231 231
232 232 $ hg -R test bundle --base 3 -r 3 -r 3 test-bundle-cset-3.hg
233 233 1 changesets found
234 234
235 235 Issue1910: 'hg bundle --base $head' does not exclude $head from
236 236 result
237 237
238 238 $ hg -R test bundle --base 7 test-bundle-cset-7.hg
239 239 4 changesets found
240 240
241 241 $ hg clone test-2 test-9
242 242 updating to branch default
243 243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 244 $ cd test-9
245 245
246 246 revision 2
247 247
248 248 $ hg tip -q
249 249 2:e38ba6f5b7e0
250 250 $ hg unbundle ../test-bundle-should-fail.hg
251 251 adding changesets
252 252 transaction abort!
253 253 rollback completed
254 254 abort: 00changelog.i@eebf5a27f8ca: unknown parent!
255 255 [255]
256 256
257 257 revision 2
258 258
259 259 $ hg tip -q
260 260 2:e38ba6f5b7e0
261 261 $ hg unbundle ../test-bundle-all.hg
262 262 adding changesets
263 263 adding manifests
264 264 adding file changes
265 265 added 6 changesets with 4 changes to 4 files (+1 heads)
266 266 (run 'hg heads' to see heads, 'hg merge' to merge)
267 267
268 268 revision 8
269 269
270 270 $ hg tip -q
271 271 8:aa35859c02ea
272 272 $ hg verify
273 273 checking changesets
274 274 checking manifests
275 275 crosschecking files in changesets and manifests
276 276 checking files
277 277 4 files, 9 changesets, 7 total revisions
278 278 $ hg rollback
279 279 rolling back to revision 2 (undo unbundle)
280 280
281 281 revision 2
282 282
283 283 $ hg tip -q
284 284 2:e38ba6f5b7e0
285 285 $ hg unbundle ../test-bundle-branch1.hg
286 286 adding changesets
287 287 adding manifests
288 288 adding file changes
289 289 added 2 changesets with 2 changes to 2 files
290 290 (run 'hg update' to get a working copy)
291 291
292 292 revision 4
293 293
294 294 $ hg tip -q
295 295 4:aa35859c02ea
296 296 $ hg verify
297 297 checking changesets
298 298 checking manifests
299 299 crosschecking files in changesets and manifests
300 300 checking files
301 301 2 files, 5 changesets, 5 total revisions
302 302 $ hg rollback
303 303 rolling back to revision 2 (undo unbundle)
304 304 $ hg unbundle ../test-bundle-branch2.hg
305 305 adding changesets
306 306 adding manifests
307 307 adding file changes
308 308 added 4 changesets with 3 changes to 3 files (+1 heads)
309 309 (run 'hg heads' to see heads, 'hg merge' to merge)
310 310
311 311 revision 6
312 312
313 313 $ hg tip -q
314 314 6:a6a34bfa0076
315 315 $ hg verify
316 316 checking changesets
317 317 checking manifests
318 318 crosschecking files in changesets and manifests
319 319 checking files
320 320 3 files, 7 changesets, 6 total revisions
321 321 $ hg rollback
322 322 rolling back to revision 2 (undo unbundle)
323 323 $ hg unbundle ../test-bundle-cset-7.hg
324 324 adding changesets
325 325 adding manifests
326 326 adding file changes
327 327 added 2 changesets with 2 changes to 2 files
328 328 (run 'hg update' to get a working copy)
329 329
330 330 revision 4
331 331
332 332 $ hg tip -q
333 333 4:aa35859c02ea
334 334 $ hg verify
335 335 checking changesets
336 336 checking manifests
337 337 crosschecking files in changesets and manifests
338 338 checking files
339 339 2 files, 5 changesets, 5 total revisions
340 340
341 341 $ cd ../test
342 342 $ hg merge 7
343 warning: detected divergent renames of afile to:
343 note: possible conflict - afile was renamed multiple times to:
344 344 anotherfile
345 345 adifferentfile
346 346 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
347 347 (branch merge, don't forget to commit)
348 348 $ hg ci -m merge
349 349 $ cd ..
350 350 $ hg -R test bundle --base 2 test-bundle-head.hg
351 351 7 changesets found
352 352 $ hg clone test-2 test-10
353 353 updating to branch default
354 354 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
355 355 $ cd test-10
356 356 $ hg unbundle ../test-bundle-head.hg
357 357 adding changesets
358 358 adding manifests
359 359 adding file changes
360 360 added 7 changesets with 4 changes to 4 files
361 361 (run 'hg update' to get a working copy)
362 362
363 363 revision 9
364 364
365 365 $ hg tip -q
366 366 9:905597b0d5d4
367 367 $ hg verify
368 368 checking changesets
369 369 checking manifests
370 370 crosschecking files in changesets and manifests
371 371 checking files
372 372 4 files, 10 changesets, 7 total revisions
@@ -1,53 +1,53 b''
1 1 http://mercurial.selenic.com/bts/issue1175
2 2
3 3 $ hg init
4 4 $ touch a
5 5 $ hg ci -Am0
6 6 adding a
7 7
8 8 $ hg mv a a1
9 9 $ hg ci -m1
10 10
11 11 $ hg co 0
12 12 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
13 13
14 14 $ hg mv a a2
15 15 $ hg up
16 warning: detected divergent renames of a to:
16 note: possible conflict - a was renamed multiple times to:
17 17 a2
18 18 a1
19 19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 20
21 21 $ hg ci -m2
22 22
23 23 $ touch a
24 24 $ hg ci -Am3
25 25 adding a
26 26
27 27 $ hg mv a b
28 28 $ hg ci -Am4 a
29 29
30 30 $ hg ci --debug --traceback -Am5 b
31 31 b
32 32 b: searching for copy revision for a
33 33 b: copy a:b80de5d138758541c5f05265ad144ab9fa86d1db
34 34 committed changeset 5:89e8e4be0de296fa3d6dd7825ccc44d7dc0f1f3b
35 35
36 36 $ hg verify
37 37 checking changesets
38 38 checking manifests
39 39 crosschecking files in changesets and manifests
40 40 checking files
41 41 4 files, 6 changesets, 4 total revisions
42 42
43 43 $ hg export --git tip
44 44 # HG changeset patch
45 45 # User test
46 46 # Date 0 0
47 47 # Node ID 89e8e4be0de296fa3d6dd7825ccc44d7dc0f1f3b
48 48 # Parent 7fc86ba705e717a721dbc361bf8c9bc05a18ca2f
49 49 5
50 50
51 51 diff --git a/b b/b
52 52 new file mode 100644
53 53
@@ -1,101 +1,101 b''
1 1 $ hg init
2 2
3 3 $ echo "[merge]" >> .hg/hgrc
4 4 $ echo "followcopies = 1" >> .hg/hgrc
5 5
6 6 $ echo foo > a
7 7 $ echo foo > a2
8 8 $ hg add a a2
9 9 $ hg ci -m "start"
10 10
11 11 $ hg mv a b
12 12 $ hg mv a2 b2
13 13 $ hg ci -m "rename"
14 14
15 15 $ hg co 0
16 16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
17 17
18 18 $ echo blahblah > a
19 19 $ echo blahblah > a2
20 20 $ hg mv a2 c2
21 21 $ hg ci -m "modify"
22 22 created new head
23 23
24 24 $ hg merge -y --debug
25 25 searching for copies back to rev 1
26 26 unmatched files in local:
27 27 c2
28 28 unmatched files in other:
29 29 b
30 30 b2
31 31 all copies found (* = to merge, ! = divergent):
32 32 c2 -> a2 !
33 33 b -> a *
34 34 b2 -> a2 !
35 35 checking for directory renames
36 36 a2: divergent renames -> dr
37 37 resolving manifests
38 38 overwrite None partial False
39 39 ancestor af1939970a1c local 044f8520aeeb+ remote 85c198ef2f6c
40 40 a: remote moved to b -> m
41 41 b2: remote created -> g
42 42 preserving a for resolve of b
43 43 removing a
44 44 updating: a 1/3 files (33.33%)
45 45 picked tool 'internal:merge' for b (binary False symlink False)
46 46 merging a and b to b
47 47 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
48 48 premerge successful
49 49 updating: a2 2/3 files (66.67%)
50 warning: detected divergent renames of a2 to:
50 note: possible conflict - a2 was renamed multiple times to:
51 51 c2
52 52 b2
53 53 updating: b2 3/3 files (100.00%)
54 54 getting b2
55 55 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
56 56 (branch merge, don't forget to commit)
57 57
58 58 $ hg status -AC
59 59 M b
60 60 a
61 61 M b2
62 62 R a
63 63 C c2
64 64
65 65 $ cat b
66 66 blahblah
67 67
68 68 $ hg ci -m "merge"
69 69
70 70 $ hg debugindex .hg/store/data/b.i
71 71 rev offset length base linkrev nodeid p1 p2
72 72 0 0 67 0 1 57eacc201a7f 000000000000 000000000000
73 73 1 67 72 1 3 4727ba907962 000000000000 57eacc201a7f
74 74
75 75 $ hg debugrename b
76 76 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
77 77
78 78 This used to trigger a "divergent renames" warning, despite no renames
79 79
80 80 $ hg cp b b3
81 81 $ hg cp b b4
82 82 $ hg ci -A -m 'copy b twice'
83 83 $ hg up eb92d88a9712
84 84 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
85 85 $ hg up
86 86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 87 $ hg rm b3 b4
88 88 $ hg ci -m 'clean up a bit of our mess'
89 89
90 90 We'd rather not warn on divergent renames done in the same changeset (issue2113)
91 91
92 92 $ hg cp b b3
93 93 $ hg mv b b4
94 94 $ hg ci -A -m 'divergent renames in same changeset'
95 95 $ hg up c761c6948de0
96 96 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
97 97 $ hg up
98 warning: detected divergent renames of b to:
98 note: possible conflict - b was renamed multiple times to:
99 99 b3
100 100 b4
101 101 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -1,754 +1,754 b''
1 1
2 2 $ mkdir -p t
3 3 $ cd t
4 4 $ cat <<EOF > merge
5 5 > import sys, os
6 6 > f = open(sys.argv[1], "wb")
7 7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 8 > f.close()
9 9 > EOF
10 10 $ HGMERGE="python ../merge"; export HGMERGE
11 11
12 12 perform a test merge with possible renaming
13 13 args:
14 14 $1 = action in local branch
15 15 $2 = action in remote branch
16 16 $3 = action in working dir
17 17 $4 = expected result
18 18
19 19 $ tm()
20 20 > {
21 21 > mkdir t
22 22 > cd t
23 23 > hg init
24 24 > echo "[merge]" >> .hg/hgrc
25 25 > echo "followcopies = 1" >> .hg/hgrc
26 26 >
27 27 > # base
28 28 > echo base > a
29 29 > echo base > rev # used to force commits
30 30 > hg add a rev
31 31 > hg ci -m "base"
32 32 >
33 33 > # remote
34 34 > echo remote > rev
35 35 > if [ "$2" != "" ] ; then $2 ; fi
36 36 > hg ci -m "remote"
37 37 >
38 38 > # local
39 39 > hg co -q 0
40 40 > echo local > rev
41 41 > if [ "$1" != "" ] ; then $1 ; fi
42 42 > hg ci -m "local"
43 43 >
44 44 > # working dir
45 45 > echo local > rev
46 46 > if [ "$3" != "" ] ; then $3 ; fi
47 47 >
48 48 > # merge
49 49 > echo "--------------"
50 50 > echo "test L:$1 R:$2 W:$3 - $4"
51 51 > echo "--------------"
52 52 > hg merge -y --debug --traceback
53 53 >
54 54 > echo "--------------"
55 55 > hg status -camC -X rev
56 56 >
57 57 > hg ci -m "merge"
58 58 >
59 59 > echo "--------------"
60 60 > echo
61 61 >
62 62 > cd ..
63 63 > rm -r t
64 64 > }
65 65 $ up() {
66 66 > cp rev $1
67 67 > hg add $1 2> /dev/null
68 68 > if [ "$2" != "" ] ; then
69 69 > cp rev $2
70 70 > hg add $2 2> /dev/null
71 71 > fi
72 72 > }
73 73 $ uc() { up $1; hg cp $1 $2; } # update + copy
74 74 $ um() { up $1; hg mv $1 $2; }
75 75 $ nc() { hg cp $1 $2; } # just copy
76 76 $ nm() { hg mv $1 $2; } # just move
77 77 $ tm "up a " "nc a b" " " "1 get local a to b"
78 78 created new head
79 79 --------------
80 80 test L:up a R:nc a b W: - 1 get local a to b
81 81 --------------
82 82 searching for copies back to rev 1
83 83 unmatched files in other:
84 84 b
85 85 all copies found (* = to merge, ! = divergent):
86 86 b -> a *
87 87 checking for directory renames
88 88 resolving manifests
89 89 overwrite None partial False
90 90 ancestor 924404dff337 local e300d1c794ec+ remote 4ce40f5aca24
91 91 rev: versions differ -> m
92 92 a: remote copied to b -> m
93 93 preserving a for resolve of b
94 94 preserving rev for resolve of rev
95 95 updating: a 1/2 files (50.00%)
96 96 picked tool 'python ../merge' for b (binary False symlink False)
97 97 merging a and b to b
98 98 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
99 99 premerge successful
100 100 updating: rev 2/2 files (100.00%)
101 101 picked tool 'python ../merge' for rev (binary False symlink False)
102 102 merging rev
103 103 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
104 104 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
105 105 (branch merge, don't forget to commit)
106 106 --------------
107 107 M b
108 108 a
109 109 C a
110 110 --------------
111 111
112 112 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
113 113 created new head
114 114 --------------
115 115 test L:nc a b R:up a W: - 2 get rem change to a and b
116 116 --------------
117 117 searching for copies back to rev 1
118 118 unmatched files in local:
119 119 b
120 120 all copies found (* = to merge, ! = divergent):
121 121 b -> a *
122 122 checking for directory renames
123 123 resolving manifests
124 124 overwrite None partial False
125 125 ancestor 924404dff337 local 86a2aa42fc76+ remote f4db7e329e71
126 126 a: remote is newer -> g
127 127 b: local copied/moved to a -> m
128 128 rev: versions differ -> m
129 129 preserving b for resolve of b
130 130 preserving rev for resolve of rev
131 131 updating: a 1/3 files (33.33%)
132 132 getting a
133 133 updating: b 2/3 files (66.67%)
134 134 picked tool 'python ../merge' for b (binary False symlink False)
135 135 merging b and a to b
136 136 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
137 137 premerge successful
138 138 updating: rev 3/3 files (100.00%)
139 139 picked tool 'python ../merge' for rev (binary False symlink False)
140 140 merging rev
141 141 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
142 142 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
143 143 (branch merge, don't forget to commit)
144 144 --------------
145 145 M a
146 146 M b
147 147 a
148 148 --------------
149 149
150 150 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
151 151 created new head
152 152 --------------
153 153 test L:up a R:nm a b W: - 3 get local a change to b, remove a
154 154 --------------
155 155 searching for copies back to rev 1
156 156 unmatched files in other:
157 157 b
158 158 all copies found (* = to merge, ! = divergent):
159 159 b -> a *
160 160 checking for directory renames
161 161 resolving manifests
162 162 overwrite None partial False
163 163 ancestor 924404dff337 local e300d1c794ec+ remote bdb19105162a
164 164 rev: versions differ -> m
165 165 a: remote moved to b -> m
166 166 preserving a for resolve of b
167 167 preserving rev for resolve of rev
168 168 removing a
169 169 updating: a 1/2 files (50.00%)
170 170 picked tool 'python ../merge' for b (binary False symlink False)
171 171 merging a and b to b
172 172 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
173 173 premerge successful
174 174 updating: rev 2/2 files (100.00%)
175 175 picked tool 'python ../merge' for rev (binary False symlink False)
176 176 merging rev
177 177 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
178 178 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
179 179 (branch merge, don't forget to commit)
180 180 --------------
181 181 M b
182 182 a
183 183 --------------
184 184
185 185 $ tm "nm a b" "up a " " " "4 get remote change to b"
186 186 created new head
187 187 --------------
188 188 test L:nm a b R:up a W: - 4 get remote change to b
189 189 --------------
190 190 searching for copies back to rev 1
191 191 unmatched files in local:
192 192 b
193 193 all copies found (* = to merge, ! = divergent):
194 194 b -> a *
195 195 checking for directory renames
196 196 resolving manifests
197 197 overwrite None partial False
198 198 ancestor 924404dff337 local 02963e448370+ remote f4db7e329e71
199 199 b: local copied/moved to a -> m
200 200 rev: versions differ -> m
201 201 preserving b for resolve of b
202 202 preserving rev for resolve of rev
203 203 updating: b 1/2 files (50.00%)
204 204 picked tool 'python ../merge' for b (binary False symlink False)
205 205 merging b and a to b
206 206 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
207 207 premerge successful
208 208 updating: rev 2/2 files (100.00%)
209 209 picked tool 'python ../merge' for rev (binary False symlink False)
210 210 merging rev
211 211 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
212 212 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
213 213 (branch merge, don't forget to commit)
214 214 --------------
215 215 M b
216 216 a
217 217 --------------
218 218
219 219 $ tm " " "nc a b" " " "5 get b"
220 220 created new head
221 221 --------------
222 222 test L: R:nc a b W: - 5 get b
223 223 --------------
224 224 searching for copies back to rev 1
225 225 unmatched files in other:
226 226 b
227 227 all copies found (* = to merge, ! = divergent):
228 228 b -> a
229 229 checking for directory renames
230 230 resolving manifests
231 231 overwrite None partial False
232 232 ancestor 924404dff337 local 94b33a1b7f2d+ remote 4ce40f5aca24
233 233 rev: versions differ -> m
234 234 b: remote created -> g
235 235 preserving rev for resolve of rev
236 236 updating: b 1/2 files (50.00%)
237 237 getting b
238 238 updating: rev 2/2 files (100.00%)
239 239 picked tool 'python ../merge' for rev (binary False symlink False)
240 240 merging rev
241 241 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
242 242 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
243 243 (branch merge, don't forget to commit)
244 244 --------------
245 245 M b
246 246 C a
247 247 --------------
248 248
249 249 $ tm "nc a b" " " " " "6 nothing"
250 250 created new head
251 251 --------------
252 252 test L:nc a b R: W: - 6 nothing
253 253 --------------
254 254 searching for copies back to rev 1
255 255 unmatched files in local:
256 256 b
257 257 all copies found (* = to merge, ! = divergent):
258 258 b -> a
259 259 checking for directory renames
260 260 resolving manifests
261 261 overwrite None partial False
262 262 ancestor 924404dff337 local 86a2aa42fc76+ remote 97c705ade336
263 263 rev: versions differ -> m
264 264 preserving rev for resolve of rev
265 265 updating: rev 1/1 files (100.00%)
266 266 picked tool 'python ../merge' for rev (binary False symlink False)
267 267 merging rev
268 268 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
269 269 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
270 270 (branch merge, don't forget to commit)
271 271 --------------
272 272 C a
273 273 C b
274 274 --------------
275 275
276 276 $ tm " " "nm a b" " " "7 get b"
277 277 created new head
278 278 --------------
279 279 test L: R:nm a b W: - 7 get b
280 280 --------------
281 281 searching for copies back to rev 1
282 282 unmatched files in other:
283 283 b
284 284 all copies found (* = to merge, ! = divergent):
285 285 b -> a
286 286 checking for directory renames
287 287 resolving manifests
288 288 overwrite None partial False
289 289 ancestor 924404dff337 local 94b33a1b7f2d+ remote bdb19105162a
290 290 a: other deleted -> r
291 291 rev: versions differ -> m
292 292 b: remote created -> g
293 293 preserving rev for resolve of rev
294 294 updating: a 1/3 files (33.33%)
295 295 removing a
296 296 updating: b 2/3 files (66.67%)
297 297 getting b
298 298 updating: rev 3/3 files (100.00%)
299 299 picked tool 'python ../merge' for rev (binary False symlink False)
300 300 merging rev
301 301 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
302 302 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
303 303 (branch merge, don't forget to commit)
304 304 --------------
305 305 M b
306 306 --------------
307 307
308 308 $ tm "nm a b" " " " " "8 nothing"
309 309 created new head
310 310 --------------
311 311 test L:nm a b R: W: - 8 nothing
312 312 --------------
313 313 searching for copies back to rev 1
314 314 unmatched files in local:
315 315 b
316 316 all copies found (* = to merge, ! = divergent):
317 317 b -> a
318 318 checking for directory renames
319 319 resolving manifests
320 320 overwrite None partial False
321 321 ancestor 924404dff337 local 02963e448370+ remote 97c705ade336
322 322 rev: versions differ -> m
323 323 preserving rev for resolve of rev
324 324 updating: rev 1/1 files (100.00%)
325 325 picked tool 'python ../merge' for rev (binary False symlink False)
326 326 merging rev
327 327 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
328 328 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
329 329 (branch merge, don't forget to commit)
330 330 --------------
331 331 C b
332 332 --------------
333 333
334 334 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
335 335 created new head
336 336 --------------
337 337 test L:um a b R:um a b W: - 9 do merge with ancestor in a
338 338 --------------
339 339 searching for copies back to rev 1
340 340 resolving manifests
341 341 overwrite None partial False
342 342 ancestor 924404dff337 local 62e7bf090eba+ remote 49b6d8032493
343 343 b: versions differ -> m
344 344 rev: versions differ -> m
345 345 preserving b for resolve of b
346 346 preserving rev for resolve of rev
347 347 updating: b 1/2 files (50.00%)
348 348 picked tool 'python ../merge' for b (binary False symlink False)
349 349 merging b
350 350 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
351 351 updating: rev 2/2 files (100.00%)
352 352 picked tool 'python ../merge' for rev (binary False symlink False)
353 353 merging rev
354 354 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
355 355 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
356 356 (branch merge, don't forget to commit)
357 357 --------------
358 358 M b
359 359 --------------
360 360
361 361
362 362 m "um a c" "um x c" " " "10 do merge with no ancestor"
363 363
364 364 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
365 365 created new head
366 366 --------------
367 367 test L:nm a b R:nm a c W: - 11 get c, keep b
368 368 --------------
369 369 searching for copies back to rev 1
370 370 unmatched files in local:
371 371 b
372 372 unmatched files in other:
373 373 c
374 374 all copies found (* = to merge, ! = divergent):
375 375 c -> a !
376 376 b -> a !
377 377 checking for directory renames
378 378 a: divergent renames -> dr
379 379 resolving manifests
380 380 overwrite None partial False
381 381 ancestor 924404dff337 local 02963e448370+ remote fe905ef2c33e
382 382 rev: versions differ -> m
383 383 c: remote created -> g
384 384 preserving rev for resolve of rev
385 385 updating: a 1/3 files (33.33%)
386 warning: detected divergent renames of a to:
386 note: possible conflict - a was renamed multiple times to:
387 387 b
388 388 c
389 389 updating: c 2/3 files (66.67%)
390 390 getting c
391 391 updating: rev 3/3 files (100.00%)
392 392 picked tool 'python ../merge' for rev (binary False symlink False)
393 393 merging rev
394 394 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
395 395 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
396 396 (branch merge, don't forget to commit)
397 397 --------------
398 398 M c
399 399 C b
400 400 --------------
401 401
402 402 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
403 403 created new head
404 404 --------------
405 405 test L:nc a b R:up b W: - 12 merge b no ancestor
406 406 --------------
407 407 searching for copies back to rev 1
408 408 resolving manifests
409 409 overwrite None partial False
410 410 ancestor 924404dff337 local 86a2aa42fc76+ remote af30c7647fc7
411 411 b: versions differ -> m
412 412 rev: versions differ -> m
413 413 preserving b for resolve of b
414 414 preserving rev for resolve of rev
415 415 updating: b 1/2 files (50.00%)
416 416 picked tool 'python ../merge' for b (binary False symlink False)
417 417 merging b
418 418 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
419 419 updating: rev 2/2 files (100.00%)
420 420 picked tool 'python ../merge' for rev (binary False symlink False)
421 421 merging rev
422 422 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
423 423 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
424 424 (branch merge, don't forget to commit)
425 425 --------------
426 426 M b
427 427 C a
428 428 --------------
429 429
430 430 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
431 431 created new head
432 432 --------------
433 433 test L:up b R:nm a b W: - 13 merge b no ancestor
434 434 --------------
435 435 searching for copies back to rev 1
436 436 resolving manifests
437 437 overwrite None partial False
438 438 ancestor 924404dff337 local 59318016310c+ remote bdb19105162a
439 439 a: other deleted -> r
440 440 b: versions differ -> m
441 441 rev: versions differ -> m
442 442 preserving b for resolve of b
443 443 preserving rev for resolve of rev
444 444 updating: a 1/3 files (33.33%)
445 445 removing a
446 446 updating: b 2/3 files (66.67%)
447 447 picked tool 'python ../merge' for b (binary False symlink False)
448 448 merging b
449 449 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
450 450 updating: rev 3/3 files (100.00%)
451 451 picked tool 'python ../merge' for rev (binary False symlink False)
452 452 merging rev
453 453 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
454 454 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
455 455 (branch merge, don't forget to commit)
456 456 --------------
457 457 M b
458 458 --------------
459 459
460 460 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
461 461 created new head
462 462 --------------
463 463 test L:nc a b R:up a b W: - 14 merge b no ancestor
464 464 --------------
465 465 searching for copies back to rev 1
466 466 resolving manifests
467 467 overwrite None partial False
468 468 ancestor 924404dff337 local 86a2aa42fc76+ remote 8dbce441892a
469 469 a: remote is newer -> g
470 470 b: versions differ -> m
471 471 rev: versions differ -> m
472 472 preserving b for resolve of b
473 473 preserving rev for resolve of rev
474 474 updating: a 1/3 files (33.33%)
475 475 getting a
476 476 updating: b 2/3 files (66.67%)
477 477 picked tool 'python ../merge' for b (binary False symlink False)
478 478 merging b
479 479 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
480 480 updating: rev 3/3 files (100.00%)
481 481 picked tool 'python ../merge' for rev (binary False symlink False)
482 482 merging rev
483 483 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
484 484 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
485 485 (branch merge, don't forget to commit)
486 486 --------------
487 487 M a
488 488 M b
489 489 --------------
490 490
491 491 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
492 492 created new head
493 493 --------------
494 494 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
495 495 --------------
496 496 searching for copies back to rev 1
497 497 resolving manifests
498 498 overwrite None partial False
499 499 ancestor 924404dff337 local 59318016310c+ remote bdb19105162a
500 500 a: other deleted -> r
501 501 b: versions differ -> m
502 502 rev: versions differ -> m
503 503 preserving b for resolve of b
504 504 preserving rev for resolve of rev
505 505 updating: a 1/3 files (33.33%)
506 506 removing a
507 507 updating: b 2/3 files (66.67%)
508 508 picked tool 'python ../merge' for b (binary False symlink False)
509 509 merging b
510 510 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
511 511 updating: rev 3/3 files (100.00%)
512 512 picked tool 'python ../merge' for rev (binary False symlink False)
513 513 merging rev
514 514 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
515 515 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
516 516 (branch merge, don't forget to commit)
517 517 --------------
518 518 M b
519 519 --------------
520 520
521 521 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
522 522 created new head
523 523 --------------
524 524 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
525 525 --------------
526 526 searching for copies back to rev 1
527 527 resolving manifests
528 528 overwrite None partial False
529 529 ancestor 924404dff337 local 86a2aa42fc76+ remote 8dbce441892a
530 530 a: remote is newer -> g
531 531 b: versions differ -> m
532 532 rev: versions differ -> m
533 533 preserving b for resolve of b
534 534 preserving rev for resolve of rev
535 535 updating: a 1/3 files (33.33%)
536 536 getting a
537 537 updating: b 2/3 files (66.67%)
538 538 picked tool 'python ../merge' for b (binary False symlink False)
539 539 merging b
540 540 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
541 541 updating: rev 3/3 files (100.00%)
542 542 picked tool 'python ../merge' for rev (binary False symlink False)
543 543 merging rev
544 544 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
545 545 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
546 546 (branch merge, don't forget to commit)
547 547 --------------
548 548 M a
549 549 M b
550 550 --------------
551 551
552 552 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
553 553 created new head
554 554 --------------
555 555 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
556 556 --------------
557 557 searching for copies back to rev 1
558 558 resolving manifests
559 559 overwrite None partial False
560 560 ancestor 924404dff337 local 0b76e65c8289+ remote 4ce40f5aca24
561 561 b: versions differ -> m
562 562 rev: versions differ -> m
563 563 preserving b for resolve of b
564 564 preserving rev for resolve of rev
565 565 updating: b 1/2 files (50.00%)
566 566 picked tool 'python ../merge' for b (binary False symlink False)
567 567 merging b
568 568 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
569 569 updating: rev 2/2 files (100.00%)
570 570 picked tool 'python ../merge' for rev (binary False symlink False)
571 571 merging rev
572 572 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
573 573 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
574 574 (branch merge, don't forget to commit)
575 575 --------------
576 576 M b
577 577 C a
578 578 --------------
579 579
580 580 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
581 581 created new head
582 582 --------------
583 583 test L:nm a b R:up a b W: - 18 merge b no ancestor
584 584 --------------
585 585 searching for copies back to rev 1
586 586 resolving manifests
587 587 overwrite None partial False
588 588 ancestor 924404dff337 local 02963e448370+ remote 8dbce441892a
589 589 b: versions differ -> m
590 590 rev: versions differ -> m
591 591 remote changed a which local deleted
592 592 use (c)hanged version or leave (d)eleted? c
593 593 a: prompt recreating -> g
594 594 preserving b for resolve of b
595 595 preserving rev for resolve of rev
596 596 updating: a 1/3 files (33.33%)
597 597 getting a
598 598 updating: b 2/3 files (66.67%)
599 599 picked tool 'python ../merge' for b (binary False symlink False)
600 600 merging b
601 601 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
602 602 updating: rev 3/3 files (100.00%)
603 603 picked tool 'python ../merge' for rev (binary False symlink False)
604 604 merging rev
605 605 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
606 606 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
607 607 (branch merge, don't forget to commit)
608 608 --------------
609 609 M a
610 610 M b
611 611 --------------
612 612
613 613 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
614 614 created new head
615 615 --------------
616 616 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
617 617 --------------
618 618 searching for copies back to rev 1
619 619 resolving manifests
620 620 overwrite None partial False
621 621 ancestor 924404dff337 local 0b76e65c8289+ remote bdb19105162a
622 622 local changed a which remote deleted
623 623 use (c)hanged version or (d)elete? c
624 624 a: prompt keep -> a
625 625 b: versions differ -> m
626 626 rev: versions differ -> m
627 627 preserving b for resolve of b
628 628 preserving rev for resolve of rev
629 629 updating: a 1/3 files (33.33%)
630 630 updating: b 2/3 files (66.67%)
631 631 picked tool 'python ../merge' for b (binary False symlink False)
632 632 merging b
633 633 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
634 634 updating: rev 3/3 files (100.00%)
635 635 picked tool 'python ../merge' for rev (binary False symlink False)
636 636 merging rev
637 637 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
638 638 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
639 639 (branch merge, don't forget to commit)
640 640 --------------
641 641 M b
642 642 C a
643 643 --------------
644 644
645 645 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
646 646 created new head
647 647 --------------
648 648 test L:up a R:um a b W: - 20 merge a and b to b, remove a
649 649 --------------
650 650 searching for copies back to rev 1
651 651 unmatched files in other:
652 652 b
653 653 all copies found (* = to merge, ! = divergent):
654 654 b -> a *
655 655 checking for directory renames
656 656 resolving manifests
657 657 overwrite None partial False
658 658 ancestor 924404dff337 local e300d1c794ec+ remote 49b6d8032493
659 659 rev: versions differ -> m
660 660 a: remote moved to b -> m
661 661 preserving a for resolve of b
662 662 preserving rev for resolve of rev
663 663 removing a
664 664 updating: a 1/2 files (50.00%)
665 665 picked tool 'python ../merge' for b (binary False symlink False)
666 666 merging a and b to b
667 667 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
668 668 updating: rev 2/2 files (100.00%)
669 669 picked tool 'python ../merge' for rev (binary False symlink False)
670 670 merging rev
671 671 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
672 672 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
673 673 (branch merge, don't forget to commit)
674 674 --------------
675 675 M b
676 676 a
677 677 --------------
678 678
679 679 $ tm "um a b" "up a " " " "21 merge a and b to b"
680 680 created new head
681 681 --------------
682 682 test L:um a b R:up a W: - 21 merge a and b to b
683 683 --------------
684 684 searching for copies back to rev 1
685 685 unmatched files in local:
686 686 b
687 687 all copies found (* = to merge, ! = divergent):
688 688 b -> a *
689 689 checking for directory renames
690 690 resolving manifests
691 691 overwrite None partial False
692 692 ancestor 924404dff337 local 62e7bf090eba+ remote f4db7e329e71
693 693 b: local copied/moved to a -> m
694 694 rev: versions differ -> m
695 695 preserving b for resolve of b
696 696 preserving rev for resolve of rev
697 697 updating: b 1/2 files (50.00%)
698 698 picked tool 'python ../merge' for b (binary False symlink False)
699 699 merging b and a to b
700 700 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
701 701 updating: rev 2/2 files (100.00%)
702 702 picked tool 'python ../merge' for rev (binary False symlink False)
703 703 merging rev
704 704 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
705 705 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
706 706 (branch merge, don't forget to commit)
707 707 --------------
708 708 M b
709 709 a
710 710 --------------
711 711
712 712
713 713 m "nm a b" "um x a" " " "22 get a, keep b"
714 714
715 715 $ tm "nm a b" "up a c" " " "23 get c, keep b"
716 716 created new head
717 717 --------------
718 718 test L:nm a b R:up a c W: - 23 get c, keep b
719 719 --------------
720 720 searching for copies back to rev 1
721 721 unmatched files in local:
722 722 b
723 723 unmatched files in other:
724 724 c
725 725 all copies found (* = to merge, ! = divergent):
726 726 b -> a *
727 727 checking for directory renames
728 728 resolving manifests
729 729 overwrite None partial False
730 730 ancestor 924404dff337 local 02963e448370+ remote 2b958612230f
731 731 b: local copied/moved to a -> m
732 732 rev: versions differ -> m
733 733 c: remote created -> g
734 734 preserving b for resolve of b
735 735 preserving rev for resolve of rev
736 736 updating: b 1/3 files (33.33%)
737 737 picked tool 'python ../merge' for b (binary False symlink False)
738 738 merging b and a to b
739 739 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
740 740 premerge successful
741 741 updating: c 2/3 files (66.67%)
742 742 getting c
743 743 updating: rev 3/3 files (100.00%)
744 744 picked tool 'python ../merge' for rev (binary False symlink False)
745 745 merging rev
746 746 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
747 747 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
748 748 (branch merge, don't forget to commit)
749 749 --------------
750 750 M b
751 751 a
752 752 M c
753 753 --------------
754 754
General Comments 0
You need to be logged in to leave comments. Login now