##// END OF EJS Templates
copies: delete debug message about "unmatched files new in both"...
Martin von Zweigbergk -
r42350:a68036b8 default
parent child Browse files
Show More
@@ -1,1021 +1,1018 b''
1 1 # copies.py - copy detection for Mercurial
2 2 #
3 3 # Copyright 2008 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 __future__ import absolute_import
9 9
10 10 import collections
11 11 import heapq
12 12 import os
13 13
14 14 from .i18n import _
15 15
16 16 from . import (
17 17 match as matchmod,
18 18 node,
19 19 pathutil,
20 20 util,
21 21 )
22 22 from .utils import (
23 23 stringutil,
24 24 )
25 25
26 26 def _findlimit(repo, ctxa, ctxb):
27 27 """
28 28 Find the last revision that needs to be checked to ensure that a full
29 29 transitive closure for file copies can be properly calculated.
30 30 Generally, this means finding the earliest revision number that's an
31 31 ancestor of a or b but not both, except when a or b is a direct descendent
32 32 of the other, in which case we can return the minimum revnum of a and b.
33 33 """
34 34
35 35 # basic idea:
36 36 # - mark a and b with different sides
37 37 # - if a parent's children are all on the same side, the parent is
38 38 # on that side, otherwise it is on no side
39 39 # - walk the graph in topological order with the help of a heap;
40 40 # - add unseen parents to side map
41 41 # - clear side of any parent that has children on different sides
42 42 # - track number of interesting revs that might still be on a side
43 43 # - track the lowest interesting rev seen
44 44 # - quit when interesting revs is zero
45 45
46 46 cl = repo.changelog
47 47 wdirparents = None
48 48 a = ctxa.rev()
49 49 b = ctxb.rev()
50 50 if a is None:
51 51 wdirparents = (ctxa.p1(), ctxa.p2())
52 52 a = node.wdirrev
53 53 if b is None:
54 54 assert not wdirparents
55 55 wdirparents = (ctxb.p1(), ctxb.p2())
56 56 b = node.wdirrev
57 57
58 58 side = {a: -1, b: 1}
59 59 visit = [-a, -b]
60 60 heapq.heapify(visit)
61 61 interesting = len(visit)
62 62 limit = node.wdirrev
63 63
64 64 while interesting:
65 65 r = -heapq.heappop(visit)
66 66 if r == node.wdirrev:
67 67 parents = [pctx.rev() for pctx in wdirparents]
68 68 else:
69 69 parents = cl.parentrevs(r)
70 70 if parents[1] == node.nullrev:
71 71 parents = parents[:1]
72 72 for p in parents:
73 73 if p not in side:
74 74 # first time we see p; add it to visit
75 75 side[p] = side[r]
76 76 if side[p]:
77 77 interesting += 1
78 78 heapq.heappush(visit, -p)
79 79 elif side[p] and side[p] != side[r]:
80 80 # p was interesting but now we know better
81 81 side[p] = 0
82 82 interesting -= 1
83 83 if side[r]:
84 84 limit = r # lowest rev visited
85 85 interesting -= 1
86 86
87 87 # Consider the following flow (see test-commit-amend.t under issue4405):
88 88 # 1/ File 'a0' committed
89 89 # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
90 90 # 3/ Move back to first commit
91 91 # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend')
92 92 # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg'
93 93 #
94 94 # During the amend in step five, we will be in this state:
95 95 #
96 96 # @ 3 temporary amend commit for a1-amend
97 97 # |
98 98 # o 2 a1-amend
99 99 # |
100 100 # | o 1 a1
101 101 # |/
102 102 # o 0 a0
103 103 #
104 104 # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2,
105 105 # yet the filelog has the copy information in rev 1 and we will not look
106 106 # back far enough unless we also look at the a and b as candidates.
107 107 # This only occurs when a is a descendent of b or visa-versa.
108 108 return min(limit, a, b)
109 109
110 110 def _chain(src, dst, a, b):
111 111 """chain two sets of copies a->b"""
112 112 t = a.copy()
113 113 for k, v in b.iteritems():
114 114 if v in t:
115 115 # found a chain
116 116 if t[v] != k:
117 117 # file wasn't renamed back to itself
118 118 t[k] = t[v]
119 119 if v not in dst:
120 120 # chain was a rename, not a copy
121 121 del t[v]
122 122 if v in src:
123 123 # file is a copy of an existing file
124 124 t[k] = v
125 125
126 126 for k, v in list(t.items()):
127 127 # remove criss-crossed copies
128 128 if k in src and v in dst:
129 129 del t[k]
130 130 # remove copies to files that were then removed
131 131 elif k not in dst:
132 132 del t[k]
133 133
134 134 return t
135 135
136 136 def _tracefile(fctx, am, limit=node.nullrev):
137 137 """return file context that is the ancestor of fctx present in ancestor
138 138 manifest am, stopping after the first ancestor lower than limit"""
139 139
140 140 for f in fctx.ancestors():
141 141 if am.get(f.path(), None) == f.filenode():
142 142 return f
143 143 if limit >= 0 and not f.isintroducedafter(limit):
144 144 return None
145 145
146 146 def _dirstatecopies(repo, match=None):
147 147 ds = repo.dirstate
148 148 c = ds.copies().copy()
149 149 for k in list(c):
150 150 if ds[k] not in 'anm' or (match and not match(k)):
151 151 del c[k]
152 152 return c
153 153
154 154 def _computeforwardmissing(a, b, match=None):
155 155 """Computes which files are in b but not a.
156 156 This is its own function so extensions can easily wrap this call to see what
157 157 files _forwardcopies is about to process.
158 158 """
159 159 ma = a.manifest()
160 160 mb = b.manifest()
161 161 return mb.filesnotin(ma, match=match)
162 162
163 163 def usechangesetcentricalgo(repo):
164 164 """Checks if we should use changeset-centric copy algorithms"""
165 165 return (repo.ui.config('experimental', 'copies.read-from') in
166 166 ('changeset-only', 'compatibility'))
167 167
168 168 def _committedforwardcopies(a, b, match):
169 169 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
170 170 # files might have to be traced back to the fctx parent of the last
171 171 # one-side-only changeset, but not further back than that
172 172 repo = a._repo
173 173
174 174 if usechangesetcentricalgo(repo):
175 175 return _changesetforwardcopies(a, b, match)
176 176
177 177 debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
178 178 dbg = repo.ui.debug
179 179 if debug:
180 180 dbg('debug.copies: looking into rename from %s to %s\n'
181 181 % (a, b))
182 182 limit = _findlimit(repo, a, b)
183 183 if debug:
184 184 dbg('debug.copies: search limit: %d\n' % limit)
185 185 am = a.manifest()
186 186
187 187 # find where new files came from
188 188 # we currently don't try to find where old files went, too expensive
189 189 # this means we can miss a case like 'hg rm b; hg cp a b'
190 190 cm = {}
191 191
192 192 # Computing the forward missing is quite expensive on large manifests, since
193 193 # it compares the entire manifests. We can optimize it in the common use
194 194 # case of computing what copies are in a commit versus its parent (like
195 195 # during a rebase or histedit). Note, we exclude merge commits from this
196 196 # optimization, since the ctx.files() for a merge commit is not correct for
197 197 # this comparison.
198 198 forwardmissingmatch = match
199 199 if b.p1() == a and b.p2().node() == node.nullid:
200 200 filesmatcher = matchmod.exact(b.files())
201 201 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
202 202 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
203 203
204 204 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
205 205
206 206 if debug:
207 207 dbg('debug.copies: missing file to search: %d\n' % len(missing))
208 208
209 209 for f in missing:
210 210 if debug:
211 211 dbg('debug.copies: tracing file: %s\n' % f)
212 212 fctx = b[f]
213 213 fctx._ancestrycontext = ancestrycontext
214 214
215 215 if debug:
216 216 start = util.timer()
217 217 ofctx = _tracefile(fctx, am, limit)
218 218 if ofctx:
219 219 if debug:
220 220 dbg('debug.copies: rename of: %s\n' % ofctx._path)
221 221 cm[f] = ofctx.path()
222 222 if debug:
223 223 dbg('debug.copies: time: %f seconds\n'
224 224 % (util.timer() - start))
225 225 return cm
226 226
227 227 def _changesetforwardcopies(a, b, match):
228 228 if a.rev() == node.nullrev:
229 229 return {}
230 230
231 231 repo = a.repo()
232 232 children = {}
233 233 cl = repo.changelog
234 234 missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
235 235 for r in missingrevs:
236 236 for p in cl.parentrevs(r):
237 237 if p == node.nullrev:
238 238 continue
239 239 if p not in children:
240 240 children[p] = [r]
241 241 else:
242 242 children[p].append(r)
243 243
244 244 roots = set(children) - set(missingrevs)
245 245 # 'work' contains 3-tuples of a (revision number, parent number, copies).
246 246 # The parent number is only used for knowing which parent the copies dict
247 247 # came from.
248 248 work = [(r, 1, {}) for r in roots]
249 249 heapq.heapify(work)
250 250 while work:
251 251 r, i1, copies1 = heapq.heappop(work)
252 252 if work and work[0][0] == r:
253 253 # We are tracing copies from both parents
254 254 r, i2, copies2 = heapq.heappop(work)
255 255 copies = {}
256 256 ctx = repo[r]
257 257 p1man, p2man = ctx.p1().manifest(), ctx.p2().manifest()
258 258 allcopies = set(copies1) | set(copies2)
259 259 # TODO: perhaps this filtering should be done as long as ctx
260 260 # is merge, whether or not we're tracing from both parent.
261 261 for dst in allcopies:
262 262 if not match(dst):
263 263 continue
264 264 if dst not in copies2:
265 265 # Copied on p1 side: mark as copy from p1 side if it didn't
266 266 # already exist on p2 side
267 267 if dst not in p2man:
268 268 copies[dst] = copies1[dst]
269 269 elif dst not in copies1:
270 270 # Copied on p2 side: mark as copy from p2 side if it didn't
271 271 # already exist on p1 side
272 272 if dst not in p1man:
273 273 copies[dst] = copies2[dst]
274 274 else:
275 275 # Copied on both sides: mark as copy from p1 side
276 276 copies[dst] = copies1[dst]
277 277 else:
278 278 copies = copies1
279 279 if r == b.rev():
280 280 return copies
281 281 for c in children[r]:
282 282 childctx = repo[c]
283 283 if r == childctx.p1().rev():
284 284 parent = 1
285 285 childcopies = childctx.p1copies()
286 286 else:
287 287 assert r == childctx.p2().rev()
288 288 parent = 2
289 289 childcopies = childctx.p2copies()
290 290 if not match.always():
291 291 childcopies = {dst: src for dst, src in childcopies.items()
292 292 if match(dst)}
293 293 childcopies = _chain(a, childctx, copies, childcopies)
294 294 heapq.heappush(work, (c, parent, childcopies))
295 295 assert False
296 296
297 297 def _forwardcopies(a, b, match=None):
298 298 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
299 299
300 300 match = a.repo().narrowmatch(match)
301 301 # check for working copy
302 302 if b.rev() is None:
303 303 if a == b.p1():
304 304 # short-circuit to avoid issues with merge states
305 305 return _dirstatecopies(b._repo, match)
306 306
307 307 cm = _committedforwardcopies(a, b.p1(), match)
308 308 # combine copies from dirstate if necessary
309 309 return _chain(a, b, cm, _dirstatecopies(b._repo, match))
310 310 return _committedforwardcopies(a, b, match)
311 311
312 312 def _backwardrenames(a, b, match):
313 313 if a._repo.ui.config('experimental', 'copytrace') == 'off':
314 314 return {}
315 315
316 316 # Even though we're not taking copies into account, 1:n rename situations
317 317 # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
318 318 # arbitrarily pick one of the renames.
319 319 # We don't want to pass in "match" here, since that would filter
320 320 # the destination by it. Since we're reversing the copies, we want
321 321 # to filter the source instead.
322 322 f = _forwardcopies(b, a)
323 323 r = {}
324 324 for k, v in sorted(f.iteritems()):
325 325 if match and not match(v):
326 326 continue
327 327 # remove copies
328 328 if v in a:
329 329 continue
330 330 r[v] = k
331 331 return r
332 332
333 333 def pathcopies(x, y, match=None):
334 334 """find {dst@y: src@x} copy mapping for directed compare"""
335 335 repo = x._repo
336 336 debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
337 337 if debug:
338 338 repo.ui.debug('debug.copies: searching copies from %s to %s\n'
339 339 % (x, y))
340 340 if x == y or not x or not y:
341 341 return {}
342 342 a = y.ancestor(x)
343 343 if a == x:
344 344 if debug:
345 345 repo.ui.debug('debug.copies: search mode: forward\n')
346 346 return _forwardcopies(x, y, match=match)
347 347 if a == y:
348 348 if debug:
349 349 repo.ui.debug('debug.copies: search mode: backward\n')
350 350 return _backwardrenames(x, y, match=match)
351 351 if debug:
352 352 repo.ui.debug('debug.copies: search mode: combined\n')
353 353 return _chain(x, y, _backwardrenames(x, a, match=match),
354 354 _forwardcopies(a, y, match=match))
355 355
356 356 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, debug=True):
357 357 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1
358 358 and c2. This is its own function so extensions can easily wrap this call
359 359 to see what files mergecopies is about to process.
360 360
361 361 Even though c1 and c2 are not used in this function, they are useful in
362 362 other extensions for being able to read the file nodes of the changed files.
363 363 """
364 364 u1 = sorted(addedinm1 - addedinm2)
365 365 u2 = sorted(addedinm2 - addedinm1)
366 366
367 367 if debug:
368 368 header = " unmatched files in %s"
369 369 if u1:
370 370 repo.ui.debug("%s:\n %s\n" % (header % 'local', "\n ".join(u1)))
371 371 if u2:
372 372 repo.ui.debug("%s:\n %s\n" % (header % 'other', "\n ".join(u2)))
373 373
374 374 return u1, u2
375 375
376 376 def _makegetfctx(ctx):
377 377 """return a 'getfctx' function suitable for _checkcopies usage
378 378
379 379 We have to re-setup the function building 'filectx' for each
380 380 '_checkcopies' to ensure the linkrev adjustment is properly setup for
381 381 each. Linkrev adjustment is important to avoid bug in rename
382 382 detection. Moreover, having a proper '_ancestrycontext' setup ensures
383 383 the performance impact of this adjustment is kept limited. Without it,
384 384 each file could do a full dag traversal making the time complexity of
385 385 the operation explode (see issue4537).
386 386
387 387 This function exists here mostly to limit the impact on stable. Feel
388 388 free to refactor on default.
389 389 """
390 390 rev = ctx.rev()
391 391 repo = ctx._repo
392 392 ac = getattr(ctx, '_ancestrycontext', None)
393 393 if ac is None:
394 394 revs = [rev]
395 395 if rev is None:
396 396 revs = [p.rev() for p in ctx.parents()]
397 397 ac = repo.changelog.ancestors(revs, inclusive=True)
398 398 ctx._ancestrycontext = ac
399 399 def makectx(f, n):
400 400 if n in node.wdirfilenodeids: # in a working context?
401 401 if ctx.rev() is None:
402 402 return ctx.filectx(f)
403 403 return repo[None][f]
404 404 fctx = repo.filectx(f, fileid=n)
405 405 # setup only needed for filectx not create from a changectx
406 406 fctx._ancestrycontext = ac
407 407 fctx._descendantrev = rev
408 408 return fctx
409 409 return util.lrucachefunc(makectx)
410 410
411 411 def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge):
412 412 """combine partial copy paths"""
413 413 remainder = {}
414 414 for f in copyfrom:
415 415 if f in copyto:
416 416 finalcopy[copyto[f]] = copyfrom[f]
417 417 del copyto[f]
418 418 for f in incompletediverge:
419 419 assert f not in diverge
420 420 ic = incompletediverge[f]
421 421 if ic[0] in copyto:
422 422 diverge[f] = [copyto[ic[0]], ic[1]]
423 423 else:
424 424 remainder[f] = ic
425 425 return remainder
426 426
427 427 def mergecopies(repo, c1, c2, base):
428 428 """
429 429 Finds moves and copies between context c1 and c2 that are relevant for
430 430 merging. 'base' will be used as the merge base.
431 431
432 432 Copytracing is used in commands like rebase, merge, unshelve, etc to merge
433 433 files that were moved/ copied in one merge parent and modified in another.
434 434 For example:
435 435
436 436 o ---> 4 another commit
437 437 |
438 438 | o ---> 3 commit that modifies a.txt
439 439 | /
440 440 o / ---> 2 commit that moves a.txt to b.txt
441 441 |/
442 442 o ---> 1 merge base
443 443
444 444 If we try to rebase revision 3 on revision 4, since there is no a.txt in
445 445 revision 4, and if user have copytrace disabled, we prints the following
446 446 message:
447 447
448 448 ```other changed <file> which local deleted```
449 449
450 450 Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
451 451 "dirmove".
452 452
453 453 "copy" is a mapping from destination name -> source name,
454 454 where source is in c1 and destination is in c2 or vice-versa.
455 455
456 456 "movewithdir" is a mapping from source name -> destination name,
457 457 where the file at source present in one context but not the other
458 458 needs to be moved to destination by the merge process, because the
459 459 other context moved the directory it is in.
460 460
461 461 "diverge" is a mapping of source name -> list of destination names
462 462 for divergent renames.
463 463
464 464 "renamedelete" is a mapping of source name -> list of destination
465 465 names for files deleted in c1 that were renamed in c2 or vice-versa.
466 466
467 467 "dirmove" is a mapping of detected source dir -> destination dir renames.
468 468 This is needed for handling changes to new files previously grafted into
469 469 renamed directories.
470 470
471 471 This function calls different copytracing algorithms based on config.
472 472 """
473 473 # avoid silly behavior for update from empty dir
474 474 if not c1 or not c2 or c1 == c2:
475 475 return {}, {}, {}, {}, {}
476 476
477 477 narrowmatch = c1.repo().narrowmatch()
478 478
479 479 # avoid silly behavior for parent -> working dir
480 480 if c2.node() is None and c1.node() == repo.dirstate.p1():
481 481 return _dirstatecopies(repo, narrowmatch), {}, {}, {}, {}
482 482
483 483 copytracing = repo.ui.config('experimental', 'copytrace')
484 484 boolctrace = stringutil.parsebool(copytracing)
485 485
486 486 # Copy trace disabling is explicitly below the node == p1 logic above
487 487 # because the logic above is required for a simple copy to be kept across a
488 488 # rebase.
489 489 if copytracing == 'heuristics':
490 490 # Do full copytracing if only non-public revisions are involved as
491 491 # that will be fast enough and will also cover the copies which could
492 492 # be missed by heuristics
493 493 if _isfullcopytraceable(repo, c1, base):
494 494 return _fullcopytracing(repo, c1, c2, base)
495 495 return _heuristicscopytracing(repo, c1, c2, base)
496 496 elif boolctrace is False:
497 497 # stringutil.parsebool() returns None when it is unable to parse the
498 498 # value, so we should rely on making sure copytracing is on such cases
499 499 return {}, {}, {}, {}, {}
500 500 else:
501 501 return _fullcopytracing(repo, c1, c2, base)
502 502
503 503 def _isfullcopytraceable(repo, c1, base):
504 504 """ Checks that if base, source and destination are all no-public branches,
505 505 if yes let's use the full copytrace algorithm for increased capabilities
506 506 since it will be fast enough.
507 507
508 508 `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
509 509 number of changesets from c1 to base such that if number of changesets are
510 510 more than the limit, full copytracing algorithm won't be used.
511 511 """
512 512 if c1.rev() is None:
513 513 c1 = c1.p1()
514 514 if c1.mutable() and base.mutable():
515 515 sourcecommitlimit = repo.ui.configint('experimental',
516 516 'copytrace.sourcecommitlimit')
517 517 commits = len(repo.revs('%d::%d', base.rev(), c1.rev()))
518 518 return commits < sourcecommitlimit
519 519 return False
520 520
521 521 def _fullcopytracing(repo, c1, c2, base):
522 522 """ The full copytracing algorithm which finds all the new files that were
523 523 added from merge base up to the top commit and for each file it checks if
524 524 this file was copied from another file.
525 525
526 526 This is pretty slow when a lot of changesets are involved but will track all
527 527 the copies.
528 528 """
529 529 # In certain scenarios (e.g. graft, update or rebase), base can be
530 530 # overridden We still need to know a real common ancestor in this case We
531 531 # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
532 532 # can be multiple common ancestors, e.g. in case of bidmerge. Because our
533 533 # caller may not know if the revision passed in lieu of the CA is a genuine
534 534 # common ancestor or not without explicitly checking it, it's better to
535 535 # determine that here.
536 536 #
537 537 # base.isancestorof(wc) is False, work around that
538 538 _c1 = c1.p1() if c1.rev() is None else c1
539 539 _c2 = c2.p1() if c2.rev() is None else c2
540 540 # an endpoint is "dirty" if it isn't a descendant of the merge base
541 541 # if we have a dirty endpoint, we need to trigger graft logic, and also
542 542 # keep track of which endpoint is dirty
543 543 dirtyc1 = not base.isancestorof(_c1)
544 544 dirtyc2 = not base.isancestorof(_c2)
545 545 graft = dirtyc1 or dirtyc2
546 546 tca = base
547 547 if graft:
548 548 tca = _c1.ancestor(_c2)
549 549
550 550 limit = _findlimit(repo, c1, c2)
551 551
552 552 m1 = c1.manifest()
553 553 m2 = c2.manifest()
554 554 mb = base.manifest()
555 555
556 556 # gather data from _checkcopies:
557 557 # - diverge = record all diverges in this dict
558 558 # - copy = record all non-divergent copies in this dict
559 559 # - fullcopy = record all copies in this dict
560 560 # - incomplete = record non-divergent partial copies here
561 561 # - incompletediverge = record divergent partial copies here
562 562 diverge = {} # divergence data is shared
563 563 incompletediverge = {}
564 564 data1 = {'copy': {},
565 565 'fullcopy': {},
566 566 'incomplete': {},
567 567 'diverge': diverge,
568 568 'incompletediverge': incompletediverge,
569 569 }
570 570 data2 = {'copy': {},
571 571 'fullcopy': {},
572 572 'incomplete': {},
573 573 'diverge': diverge,
574 574 'incompletediverge': incompletediverge,
575 575 }
576 576
577 577 # find interesting file sets from manifests
578 578 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
579 579 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
580 580 bothnew = sorted(addedinm1 & addedinm2)
581 581 if tca == base:
582 582 # unmatched file from base
583 583 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
584 584 u1u, u2u = u1r, u2r
585 585 else:
586 586 # unmatched file from base (DAG rotation in the graft case)
587 587 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
588 588 # unmatched file from topological common ancestors (no DAG rotation)
589 589 # need to recompute this for directory move handling when grafting
590 590 mta = tca.manifest()
591 591 u1u, u2u = _computenonoverlap(repo, c1, c2,
592 592 m1.filesnotin(mta, repo.narrowmatch()),
593 593 m2.filesnotin(mta, repo.narrowmatch()),
594 594 debug=False)
595 595
596 596 for f in u1u:
597 597 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
598 598
599 599 for f in u2u:
600 600 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
601 601
602 602 copy = dict(data1['copy'])
603 603 copy.update(data2['copy'])
604 604 fullcopy = dict(data1['fullcopy'])
605 605 fullcopy.update(data2['fullcopy'])
606 606
607 607 if dirtyc1:
608 608 _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
609 609 incompletediverge)
610 610 if dirtyc2:
611 611 _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
612 612 incompletediverge)
613 613
614 614 renamedelete = {}
615 615 renamedeleteset = set()
616 616 divergeset = set()
617 617 for of, fl in list(diverge.items()):
618 618 if len(fl) == 1 or of in c1 or of in c2:
619 619 del diverge[of] # not actually divergent, or not a rename
620 620 if of not in c1 and of not in c2:
621 621 # renamed on one side, deleted on the other side, but filter
622 622 # out files that have been renamed and then deleted
623 623 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
624 624 renamedeleteset.update(fl) # reverse map for below
625 625 else:
626 626 divergeset.update(fl) # reverse map for below
627 627
628 if bothnew:
629 repo.ui.debug(" unmatched files new in both:\n %s\n"
630 % "\n ".join(bothnew))
631 628 bothdiverge = {}
632 629 bothincompletediverge = {}
633 630 remainder = {}
634 631 both1 = {'copy': {},
635 632 'fullcopy': {},
636 633 'incomplete': {},
637 634 'diverge': bothdiverge,
638 635 'incompletediverge': bothincompletediverge
639 636 }
640 637 both2 = {'copy': {},
641 638 'fullcopy': {},
642 639 'incomplete': {},
643 640 'diverge': bothdiverge,
644 641 'incompletediverge': bothincompletediverge
645 642 }
646 643 for f in bothnew:
647 644 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
648 645 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
649 646 if dirtyc1 and dirtyc2:
650 647 remainder = _combinecopies(both2['incomplete'], both1['incomplete'],
651 648 copy, bothdiverge, bothincompletediverge)
652 649 remainder1 = _combinecopies(both1['incomplete'], both2['incomplete'],
653 650 copy, bothdiverge, bothincompletediverge)
654 651 remainder.update(remainder1)
655 652 elif dirtyc1:
656 653 # incomplete copies may only be found on the "dirty" side for bothnew
657 654 assert not both2['incomplete']
658 655 remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,
659 656 bothincompletediverge)
660 657 elif dirtyc2:
661 658 assert not both1['incomplete']
662 659 remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge,
663 660 bothincompletediverge)
664 661 else:
665 662 # incomplete copies and divergences can't happen outside grafts
666 663 assert not both1['incomplete']
667 664 assert not both2['incomplete']
668 665 assert not bothincompletediverge
669 666 for f in remainder:
670 667 assert f not in bothdiverge
671 668 ic = remainder[f]
672 669 if ic[0] in (m1 if dirtyc1 else m2):
673 670 # backed-out rename on one side, but watch out for deleted files
674 671 bothdiverge[f] = ic
675 672 for of, fl in bothdiverge.items():
676 673 if len(fl) == 2 and fl[0] == fl[1]:
677 674 copy[fl[0]] = of # not actually divergent, just matching renames
678 675
679 676 # Sometimes we get invalid copies here (the "and not remotebase" in
680 677 # _checkcopies() seems suspicious). Filter them out.
681 678 for dst, src in fullcopy.copy().items():
682 679 if src not in mb:
683 680 del fullcopy[dst]
684 681 # Sometimes we forget to add entries from "copy" to "fullcopy", so fix
685 682 # that up here
686 683 for dst, src in copy.items():
687 684 fullcopy[dst] = src
688 685 # Sometimes we forget to add entries from "diverge" to "fullcopy", so fix
689 686 # that up here
690 687 for src, dsts in diverge.items():
691 688 for dst in dsts:
692 689 fullcopy[dst] = src
693 690
694 691 if not fullcopy:
695 692 return copy, {}, diverge, renamedelete, {}
696 693
697 694 if repo.ui.debugflag:
698 695 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
699 696 "% = renamed and deleted):\n")
700 697 for f in sorted(fullcopy):
701 698 note = ""
702 699 if f in copy:
703 700 note += "*"
704 701 if f in divergeset:
705 702 note += "!"
706 703 if f in renamedeleteset:
707 704 note += "%"
708 705 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
709 706 note))
710 707 del divergeset
711 708
712 709 repo.ui.debug(" checking for directory renames\n")
713 710
714 711 # generate a directory move map
715 712 d1, d2 = c1.dirs(), c2.dirs()
716 713 # Hack for adding '', which is not otherwise added, to d1 and d2
717 714 d1.addpath('/')
718 715 d2.addpath('/')
719 716 invalid = set()
720 717 dirmove = {}
721 718
722 719 # examine each file copy for a potential directory move, which is
723 720 # when all the files in a directory are moved to a new directory
724 721 for dst, src in fullcopy.iteritems():
725 722 dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
726 723 if dsrc in invalid:
727 724 # already seen to be uninteresting
728 725 continue
729 726 elif dsrc in d1 and ddst in d1:
730 727 # directory wasn't entirely moved locally
731 728 invalid.add(dsrc)
732 729 elif dsrc in d2 and ddst in d2:
733 730 # directory wasn't entirely moved remotely
734 731 invalid.add(dsrc)
735 732 elif dsrc in dirmove and dirmove[dsrc] != ddst:
736 733 # files from the same directory moved to two different places
737 734 invalid.add(dsrc)
738 735 else:
739 736 # looks good so far
740 737 dirmove[dsrc] = ddst
741 738
742 739 for i in invalid:
743 740 if i in dirmove:
744 741 del dirmove[i]
745 742 del d1, d2, invalid
746 743
747 744 if not dirmove:
748 745 return copy, {}, diverge, renamedelete, {}
749 746
750 747 dirmove = {k + "/": v + "/" for k, v in dirmove.iteritems()}
751 748
752 749 for d in dirmove:
753 750 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
754 751 (d, dirmove[d]))
755 752
756 753 movewithdir = {}
757 754 # check unaccounted nonoverlapping files against directory moves
758 755 for f in u1r + u2r:
759 756 if f not in fullcopy:
760 757 for d in dirmove:
761 758 if f.startswith(d):
762 759 # new file added in a directory that was moved, move it
763 760 df = dirmove[d] + f[len(d):]
764 761 if df not in copy:
765 762 movewithdir[f] = df
766 763 repo.ui.debug((" pending file src: '%s' -> "
767 764 "dst: '%s'\n") % (f, df))
768 765 break
769 766
770 767 return copy, movewithdir, diverge, renamedelete, dirmove
771 768
772 769 def _heuristicscopytracing(repo, c1, c2, base):
773 770 """ Fast copytracing using filename heuristics
774 771
775 772 Assumes that moves or renames are of following two types:
776 773
777 774 1) Inside a directory only (same directory name but different filenames)
778 775 2) Move from one directory to another
779 776 (same filenames but different directory names)
780 777
781 778 Works only when there are no merge commits in the "source branch".
782 779 Source branch is commits from base up to c2 not including base.
783 780
784 781 If merge is involved it fallbacks to _fullcopytracing().
785 782
786 783 Can be used by setting the following config:
787 784
788 785 [experimental]
789 786 copytrace = heuristics
790 787
791 788 In some cases the copy/move candidates found by heuristics can be very large
792 789 in number and that will make the algorithm slow. The number of possible
793 790 candidates to check can be limited by using the config
794 791 `experimental.copytrace.movecandidateslimit` which defaults to 100.
795 792 """
796 793
797 794 if c1.rev() is None:
798 795 c1 = c1.p1()
799 796 if c2.rev() is None:
800 797 c2 = c2.p1()
801 798
802 799 copies = {}
803 800
804 801 changedfiles = set()
805 802 m1 = c1.manifest()
806 803 if not repo.revs('%d::%d', base.rev(), c2.rev()):
807 804 # If base is not in c2 branch, we switch to fullcopytracing
808 805 repo.ui.debug("switching to full copytracing as base is not "
809 806 "an ancestor of c2\n")
810 807 return _fullcopytracing(repo, c1, c2, base)
811 808
812 809 ctx = c2
813 810 while ctx != base:
814 811 if len(ctx.parents()) == 2:
815 812 # To keep things simple let's not handle merges
816 813 repo.ui.debug("switching to full copytracing because of merges\n")
817 814 return _fullcopytracing(repo, c1, c2, base)
818 815 changedfiles.update(ctx.files())
819 816 ctx = ctx.p1()
820 817
821 818 cp = _forwardcopies(base, c2)
822 819 for dst, src in cp.iteritems():
823 820 if src in m1:
824 821 copies[dst] = src
825 822
826 823 # file is missing if it isn't present in the destination, but is present in
827 824 # the base and present in the source.
828 825 # Presence in the base is important to exclude added files, presence in the
829 826 # source is important to exclude removed files.
830 827 filt = lambda f: f not in m1 and f in base and f in c2
831 828 missingfiles = [f for f in changedfiles if filt(f)]
832 829
833 830 if missingfiles:
834 831 basenametofilename = collections.defaultdict(list)
835 832 dirnametofilename = collections.defaultdict(list)
836 833
837 834 for f in m1.filesnotin(base.manifest()):
838 835 basename = os.path.basename(f)
839 836 dirname = os.path.dirname(f)
840 837 basenametofilename[basename].append(f)
841 838 dirnametofilename[dirname].append(f)
842 839
843 840 for f in missingfiles:
844 841 basename = os.path.basename(f)
845 842 dirname = os.path.dirname(f)
846 843 samebasename = basenametofilename[basename]
847 844 samedirname = dirnametofilename[dirname]
848 845 movecandidates = samebasename + samedirname
849 846 # f is guaranteed to be present in c2, that's why
850 847 # c2.filectx(f) won't fail
851 848 f2 = c2.filectx(f)
852 849 # we can have a lot of candidates which can slow down the heuristics
853 850 # config value to limit the number of candidates moves to check
854 851 maxcandidates = repo.ui.configint('experimental',
855 852 'copytrace.movecandidateslimit')
856 853
857 854 if len(movecandidates) > maxcandidates:
858 855 repo.ui.status(_("skipping copytracing for '%s', more "
859 856 "candidates than the limit: %d\n")
860 857 % (f, len(movecandidates)))
861 858 continue
862 859
863 860 for candidate in movecandidates:
864 861 f1 = c1.filectx(candidate)
865 862 if _related(f1, f2):
866 863 # if there are a few related copies then we'll merge
867 864 # changes into all of them. This matches the behaviour
868 865 # of upstream copytracing
869 866 copies[candidate] = f
870 867
871 868 return copies, {}, {}, {}, {}
872 869
873 870 def _related(f1, f2):
874 871 """return True if f1 and f2 filectx have a common ancestor
875 872
876 873 Walk back to common ancestor to see if the two files originate
877 874 from the same file. Since workingfilectx's rev() is None it messes
878 875 up the integer comparison logic, hence the pre-step check for
879 876 None (f1 and f2 can only be workingfilectx's initially).
880 877 """
881 878
882 879 if f1 == f2:
883 880 return True # a match
884 881
885 882 g1, g2 = f1.ancestors(), f2.ancestors()
886 883 try:
887 884 f1r, f2r = f1.linkrev(), f2.linkrev()
888 885
889 886 if f1r is None:
890 887 f1 = next(g1)
891 888 if f2r is None:
892 889 f2 = next(g2)
893 890
894 891 while True:
895 892 f1r, f2r = f1.linkrev(), f2.linkrev()
896 893 if f1r > f2r:
897 894 f1 = next(g1)
898 895 elif f2r > f1r:
899 896 f2 = next(g2)
900 897 else: # f1 and f2 point to files in the same linkrev
901 898 return f1 == f2 # true if they point to the same file
902 899 except StopIteration:
903 900 return False
904 901
905 902 def _checkcopies(srcctx, dstctx, f, base, tca, remotebase, limit, data):
906 903 """
907 904 check possible copies of f from msrc to mdst
908 905
909 906 srcctx = starting context for f in msrc
910 907 dstctx = destination context for f in mdst
911 908 f = the filename to check (as in msrc)
912 909 base = the changectx used as a merge base
913 910 tca = topological common ancestor for graft-like scenarios
914 911 remotebase = True if base is outside tca::srcctx, False otherwise
915 912 limit = the rev number to not search beyond
916 913 data = dictionary of dictionary to store copy data. (see mergecopies)
917 914
918 915 note: limit is only an optimization, and provides no guarantee that
919 916 irrelevant revisions will not be visited
920 917 there is no easy way to make this algorithm stop in a guaranteed way
921 918 once it "goes behind a certain revision".
922 919 """
923 920
924 921 msrc = srcctx.manifest()
925 922 mdst = dstctx.manifest()
926 923 mb = base.manifest()
927 924 mta = tca.manifest()
928 925 # Might be true if this call is about finding backward renames,
929 926 # This happens in the case of grafts because the DAG is then rotated.
930 927 # If the file exists in both the base and the source, we are not looking
931 928 # for a rename on the source side, but on the part of the DAG that is
932 929 # traversed backwards.
933 930 #
934 931 # In the case there is both backward and forward renames (before and after
935 932 # the base) this is more complicated as we must detect a divergence.
936 933 # We use 'backwards = False' in that case.
937 934 backwards = not remotebase and base != tca and f in mb
938 935 getsrcfctx = _makegetfctx(srcctx)
939 936 getdstfctx = _makegetfctx(dstctx)
940 937
941 938 if msrc[f] == mb.get(f) and not remotebase:
942 939 # Nothing to merge
943 940 return
944 941
945 942 of = None
946 943 seen = {f}
947 944 for oc in getsrcfctx(f, msrc[f]).ancestors():
948 945 of = oc.path()
949 946 if of in seen:
950 947 # check limit late - grab last rename before
951 948 if oc.linkrev() < limit:
952 949 break
953 950 continue
954 951 seen.add(of)
955 952
956 953 # remember for dir rename detection
957 954 if backwards:
958 955 data['fullcopy'][of] = f # grafting backwards through renames
959 956 else:
960 957 data['fullcopy'][f] = of
961 958 if of not in mdst:
962 959 continue # no match, keep looking
963 960 if mdst[of] == mb.get(of):
964 961 return # no merge needed, quit early
965 962 c2 = getdstfctx(of, mdst[of])
966 963 # c2 might be a plain new file on added on destination side that is
967 964 # unrelated to the droids we are looking for.
968 965 cr = _related(oc, c2)
969 966 if cr and (of == f or of == c2.path()): # non-divergent
970 967 if backwards:
971 968 data['copy'][of] = f
972 969 elif of in mb:
973 970 data['copy'][f] = of
974 971 elif remotebase: # special case: a <- b <- a -> b "ping-pong" rename
975 972 data['copy'][of] = f
976 973 del data['fullcopy'][f]
977 974 data['fullcopy'][of] = f
978 975 else: # divergence w.r.t. graft CA on one side of topological CA
979 976 for sf in seen:
980 977 if sf in mb:
981 978 assert sf not in data['diverge']
982 979 data['diverge'][sf] = [f, of]
983 980 break
984 981 return
985 982
986 983 if of in mta:
987 984 if backwards or remotebase:
988 985 data['incomplete'][of] = f
989 986 else:
990 987 for sf in seen:
991 988 if sf in mb:
992 989 if tca == base:
993 990 data['diverge'].setdefault(sf, []).append(f)
994 991 else:
995 992 data['incompletediverge'][sf] = [of, f]
996 993 return
997 994
998 995 def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
999 996 """reproduce copies from fromrev to rev in the dirstate
1000 997
1001 998 If skiprev is specified, it's a revision that should be used to
1002 999 filter copy records. Any copies that occur between fromrev and
1003 1000 skiprev will not be duplicated, even if they appear in the set of
1004 1001 copies between fromrev and rev.
1005 1002 """
1006 1003 exclude = {}
1007 1004 ctraceconfig = repo.ui.config('experimental', 'copytrace')
1008 1005 bctrace = stringutil.parsebool(ctraceconfig)
1009 1006 if (skiprev is not None and
1010 1007 (ctraceconfig == 'heuristics' or bctrace or bctrace is None)):
1011 1008 # copytrace='off' skips this line, but not the entire function because
1012 1009 # the line below is O(size of the repo) during a rebase, while the rest
1013 1010 # of the function is much faster (and is required for carrying copy
1014 1011 # metadata across the rebase anyway).
1015 1012 exclude = pathcopies(repo[fromrev], repo[skiprev])
1016 1013 for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
1017 1014 # copies.pathcopies returns backward renames, so dst might not
1018 1015 # actually be in the dirstate
1019 1016 if dst in exclude:
1020 1017 continue
1021 1018 wctx[dst].markcopied(src)
@@ -1,2405 +1,2403 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extdiff]
3 3 > # for portability:
4 4 > pdiff = sh "$RUNTESTDIR/pdiff"
5 5 > EOF
6 6
7 7 Create a repo with some stuff in it:
8 8
9 9 $ hg init a
10 10 $ cd a
11 11 $ echo a > a
12 12 $ echo a > d
13 13 $ echo a > e
14 14 $ hg ci -qAm0
15 15 $ echo b > a
16 16 $ hg ci -m1 -u bar
17 17 $ hg mv a b
18 18 $ hg ci -m2
19 19 $ hg cp b c
20 20 $ hg ci -m3 -u baz
21 21 $ echo b > d
22 22 $ echo f > e
23 23 $ hg ci -m4
24 24 $ hg up -q 3
25 25 $ echo b > e
26 26 $ hg branch -q stable
27 27 $ hg ci -m5
28 28 $ hg merge -q default --tool internal:local # for conflicts in e, choose 5 and ignore 4
29 29 $ hg branch -q default
30 30 $ hg ci -m6
31 31 $ hg phase --public 3
32 32 $ hg phase --force --secret 6
33 33
34 34 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
35 35 @ test@6.secret: 6
36 36 |\
37 37 | o test@5.draft: 5
38 38 | |
39 39 o | test@4.draft: 4
40 40 |/
41 41 o baz@3.public: 3
42 42 |
43 43 o test@2.public: 2
44 44 |
45 45 o bar@1.public: 1
46 46 |
47 47 o test@0.public: 0
48 48
49 49 Test --base for grafting the merge of 4 from the perspective of 5, thus only getting the change to d
50 50
51 51 $ hg up -cqr 3
52 52 $ hg graft -r 6 --base 5
53 53 grafting 6:25a2b029d3ae "6" (tip)
54 54 merging e
55 55 $ hg st --change .
56 56 M d
57 57
58 58 $ hg -q strip . --config extensions.strip=
59 59
60 60 Test --base for collapsing changesets 2 and 3, thus getting both b and c
61 61
62 62 $ hg up -cqr 0
63 63 $ hg graft -r 3 --base 1
64 64 grafting 3:4c60f11aa304 "3"
65 65 merging a and b to b
66 66 merging a and c to c
67 67 $ hg st --change .
68 68 A b
69 69 A c
70 70 R a
71 71
72 72 $ hg -q strip . --config extensions.strip=
73 73
74 74 Specifying child as --base revision fails safely (perhaps slightly confusing, but consistent)
75 75
76 76 $ hg graft -r 2 --base 3
77 77 grafting 2:5c095ad7e90f "2"
78 78 note: graft of 2:5c095ad7e90f created no changes to commit
79 79
80 80 Can't continue without starting:
81 81
82 82 $ hg -q up -cr tip
83 83 $ hg rm -q e
84 84 $ hg graft --continue
85 85 abort: no graft in progress
86 86 [255]
87 87 $ hg revert -r . -q e
88 88
89 89 Need to specify a rev:
90 90
91 91 $ hg graft
92 92 abort: no revisions specified
93 93 [255]
94 94
95 95 Can't graft ancestor:
96 96
97 97 $ hg graft 1 2
98 98 skipping ancestor revision 1:5d205f8b35b6
99 99 skipping ancestor revision 2:5c095ad7e90f
100 100 [255]
101 101
102 102 Specify revisions with -r:
103 103
104 104 $ hg graft -r 1 -r 2
105 105 skipping ancestor revision 1:5d205f8b35b6
106 106 skipping ancestor revision 2:5c095ad7e90f
107 107 [255]
108 108
109 109 $ hg graft -r 1 2
110 110 warning: inconsistent use of --rev might give unexpected revision ordering!
111 111 skipping ancestor revision 2:5c095ad7e90f
112 112 skipping ancestor revision 1:5d205f8b35b6
113 113 [255]
114 114
115 115 Conflicting date/user options:
116 116
117 117 $ hg up -q 0
118 118 $ hg graft -U --user foo 2
119 119 abort: --user and --currentuser are mutually exclusive
120 120 [255]
121 121 $ hg graft -D --date '0 0' 2
122 122 abort: --date and --currentdate are mutually exclusive
123 123 [255]
124 124
125 125 Can't graft with dirty wd:
126 126
127 127 $ hg up -q 0
128 128 $ echo foo > a
129 129 $ hg graft 1
130 130 abort: uncommitted changes
131 131 [255]
132 132 $ hg revert a
133 133
134 134 Graft a rename:
135 135 (this also tests that editor is invoked if '--edit' is specified)
136 136
137 137 $ hg status --rev "2^1" --rev 2
138 138 A b
139 139 R a
140 140 $ HGEDITOR=cat hg graft 2 -u foo --edit
141 141 grafting 2:5c095ad7e90f "2"
142 142 merging a and b to b
143 143 2
144 144
145 145
146 146 HG: Enter commit message. Lines beginning with 'HG:' are removed.
147 147 HG: Leave message empty to abort commit.
148 148 HG: --
149 149 HG: user: foo
150 150 HG: branch 'default'
151 151 HG: added b
152 152 HG: removed a
153 153 $ hg export tip --git
154 154 # HG changeset patch
155 155 # User foo
156 156 # Date 0 0
157 157 # Thu Jan 01 00:00:00 1970 +0000
158 158 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
159 159 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
160 160 2
161 161
162 162 diff --git a/a b/b
163 163 rename from a
164 164 rename to b
165 165
166 166 Look for extra:source
167 167
168 168 $ hg log --debug -r tip
169 169 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
170 170 tag: tip
171 171 phase: draft
172 172 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
173 173 parent: -1:0000000000000000000000000000000000000000
174 174 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
175 175 user: foo
176 176 date: Thu Jan 01 00:00:00 1970 +0000
177 177 files+: b
178 178 files-: a
179 179 extra: branch=default
180 180 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
181 181 description:
182 182 2
183 183
184 184
185 185
186 186 Graft out of order, skipping a merge and a duplicate
187 187 (this also tests that editor is not invoked if '--edit' is not specified)
188 188
189 189 $ hg graft 1 5 4 3 'merge()' 2 -n
190 190 skipping ungraftable merge revision 6
191 191 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
192 192 grafting 1:5d205f8b35b6 "1"
193 193 grafting 5:97f8bfe72746 "5"
194 194 grafting 4:9c233e8e184d "4"
195 195 grafting 3:4c60f11aa304 "3"
196 196
197 197 $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug
198 198 skipping ungraftable merge revision 6
199 199 scanning for duplicate grafts
200 200 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
201 201 grafting 1:5d205f8b35b6 "1"
202 202 unmatched files in local:
203 203 b
204 204 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
205 205 src: 'a' -> dst: 'b' *
206 206 checking for directory renames
207 207 resolving manifests
208 208 branchmerge: True, force: True, partial: False
209 209 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
210 210 preserving b for resolve of b
211 211 starting 4 threads for background file closing (?)
212 212 b: local copied/moved from a -> m (premerge)
213 213 picked tool ':merge' for b (binary False symlink False changedelete False)
214 214 merging b and a to b
215 215 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
216 216 premerge successful
217 217 committing files:
218 218 b
219 219 committing manifest
220 220 committing changelog
221 221 updating the branch cache
222 222 grafting 5:97f8bfe72746 "5"
223 223 resolving manifests
224 224 branchmerge: True, force: True, partial: False
225 225 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
226 226 e: remote is newer -> g
227 227 getting e
228 228 committing files:
229 229 e
230 230 committing manifest
231 231 committing changelog
232 232 updating the branch cache
233 233 $ HGEDITOR=cat hg graft 4 3 --log --debug
234 234 scanning for duplicate grafts
235 235 grafting 4:9c233e8e184d "4"
236 236 resolving manifests
237 237 branchmerge: True, force: True, partial: False
238 238 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
239 239 preserving e for resolve of e
240 240 d: remote is newer -> g
241 241 getting d
242 242 e: versions differ -> m (premerge)
243 243 picked tool ':merge' for e (binary False symlink False changedelete False)
244 244 merging e
245 245 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
246 246 e: versions differ -> m (merge)
247 247 picked tool ':merge' for e (binary False symlink False changedelete False)
248 248 my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304
249 249 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
250 250 abort: unresolved conflicts, can't continue
251 251 (use 'hg resolve' and 'hg graft --continue')
252 252 [255]
253 253
254 254 Summary should mention graft:
255 255
256 256 $ hg summary |grep graft
257 257 commit: 2 modified, 2 unknown, 1 unresolved (graft in progress)
258 258
259 259 Using status to get more context
260 260
261 261 $ hg status --verbose
262 262 M d
263 263 M e
264 264 ? a.orig
265 265 ? e.orig
266 266 # The repository is in an unfinished *graft* state.
267 267
268 268 # Unresolved merge conflicts:
269 269 #
270 270 # e
271 271 #
272 272 # To mark files as resolved: hg resolve --mark FILE
273 273
274 274 # To continue: hg graft --continue
275 275 # To abort: hg graft --abort
276 276
277 277
278 278 Commit while interrupted should fail:
279 279
280 280 $ hg ci -m 'commit interrupted graft'
281 281 abort: graft in progress
282 282 (use 'hg graft --continue' or 'hg graft --stop' to stop)
283 283 [255]
284 284
285 285 Abort the graft and try committing:
286 286
287 287 $ hg up -C .
288 288 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 289 $ echo c >> e
290 290 $ hg ci -mtest
291 291
292 292 $ hg strip . --config extensions.strip=
293 293 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 294 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
295 295
296 296 Graft again:
297 297
298 298 $ hg graft 1 5 4 3 'merge()' 2
299 299 skipping ungraftable merge revision 6
300 300 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
301 301 skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e)
302 302 skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec)
303 303 grafting 4:9c233e8e184d "4"
304 304 merging e
305 305 warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
306 306 abort: unresolved conflicts, can't continue
307 307 (use 'hg resolve' and 'hg graft --continue')
308 308 [255]
309 309
310 310 Continue without resolve should fail:
311 311
312 312 $ hg graft -c
313 313 grafting 4:9c233e8e184d "4"
314 314 abort: unresolved merge conflicts (see 'hg help resolve')
315 315 [255]
316 316
317 317 Fix up:
318 318
319 319 $ echo b > e
320 320 $ hg resolve -m e
321 321 (no more unresolved files)
322 322 continue: hg graft --continue
323 323
324 324 Continue with a revision should fail:
325 325
326 326 $ hg graft -c 6
327 327 abort: can't specify --continue and revisions
328 328 [255]
329 329
330 330 $ hg graft -c -r 6
331 331 abort: can't specify --continue and revisions
332 332 [255]
333 333
334 334 Continue for real, clobber usernames
335 335
336 336 $ hg graft -c -U
337 337 grafting 4:9c233e8e184d "4"
338 338 grafting 3:4c60f11aa304 "3"
339 339
340 340 Compare with original:
341 341
342 342 $ hg diff -r 6
343 343 $ hg status --rev 0:. -C
344 344 M d
345 345 M e
346 346 A b
347 347 a
348 348 A c
349 349 a
350 350 R a
351 351
352 352 View graph:
353 353
354 354 $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n'
355 355 @ test@11.draft: 3
356 356 |
357 357 o test@10.draft: 4
358 358 |
359 359 o test@9.draft: 5
360 360 |
361 361 o bar@8.draft: 1
362 362 |
363 363 o foo@7.draft: 2
364 364 |
365 365 | o test@6.secret: 6
366 366 | |\
367 367 | | o test@5.draft: 5
368 368 | | |
369 369 | o | test@4.draft: 4
370 370 | |/
371 371 | o baz@3.public: 3
372 372 | |
373 373 | o test@2.public: 2
374 374 | |
375 375 | o bar@1.public: 1
376 376 |/
377 377 o test@0.public: 0
378 378
379 379 Graft again onto another branch should preserve the original source
380 380 $ hg up -q 0
381 381 $ echo 'g'>g
382 382 $ hg add g
383 383 $ hg ci -m 7
384 384 created new head
385 385 $ hg graft 7
386 386 grafting 7:ef0ef43d49e7 "2"
387 387
388 388 $ hg log -r 7 --template '{rev}:{node}\n'
389 389 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
390 390 $ hg log -r 2 --template '{rev}:{node}\n'
391 391 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
392 392
393 393 $ hg log --debug -r tip
394 394 changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9
395 395 tag: tip
396 396 phase: draft
397 397 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
398 398 parent: -1:0000000000000000000000000000000000000000
399 399 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
400 400 user: foo
401 401 date: Thu Jan 01 00:00:00 1970 +0000
402 402 files+: b
403 403 files-: a
404 404 extra: branch=default
405 405 extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82
406 406 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
407 407 description:
408 408 2
409 409
410 410
411 411 Disallow grafting an already grafted cset onto its original branch
412 412 $ hg up -q 6
413 413 $ hg graft 7
414 414 skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f)
415 415 [255]
416 416
417 417 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13
418 418 --- */hg-5c095ad7e90f.patch * (glob)
419 419 +++ */hg-7a4785234d87.patch * (glob)
420 420 @@ -1,18 +1,18 @@
421 421 # HG changeset patch
422 422 -# User test
423 423 +# User foo
424 424 # Date 0 0
425 425 # Thu Jan 01 00:00:00 1970 +0000
426 426 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
427 427 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
428 428 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
429 429 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
430 430 2
431 431
432 432 -diff -r 5d205f8b35b6 -r 5c095ad7e90f a
433 433 +diff -r b592ea63bb0c -r 7a4785234d87 a
434 434 --- a/a Thu Jan 01 00:00:00 1970 +0000
435 435 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
436 436 @@ -1,1 +0,0 @@
437 437 --b
438 438 -diff -r 5d205f8b35b6 -r 5c095ad7e90f b
439 439 +-a
440 440 +diff -r b592ea63bb0c -r 7a4785234d87 b
441 441 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
442 442 +++ b/b Thu Jan 01 00:00:00 1970 +0000
443 443 @@ -0,0 +1,1 @@
444 444 -+b
445 445 ++a
446 446 [1]
447 447
448 448 $ hg pdiff --config extensions.extdiff= --patch -r 2 -r 13 -X .
449 449 --- */hg-5c095ad7e90f.patch * (glob)
450 450 +++ */hg-7a4785234d87.patch * (glob)
451 451 @@ -1,8 +1,8 @@
452 452 # HG changeset patch
453 453 -# User test
454 454 +# User foo
455 455 # Date 0 0
456 456 # Thu Jan 01 00:00:00 1970 +0000
457 457 -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4
458 458 -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04
459 459 +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9
460 460 +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
461 461 2
462 462
463 463 [1]
464 464
465 465 Disallow grafting already grafted csets with the same origin onto each other
466 466 $ hg up -q 13
467 467 $ hg graft 2
468 468 skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87)
469 469 [255]
470 470 $ hg graft 7
471 471 skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f)
472 472 [255]
473 473
474 474 $ hg up -q 7
475 475 $ hg graft 2
476 476 skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7)
477 477 [255]
478 478 $ hg graft tip
479 479 skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f)
480 480 [255]
481 481
482 482 Graft with --log
483 483
484 484 $ hg up -Cq 1
485 485 $ hg graft 3 --log -u foo
486 486 grafting 3:4c60f11aa304 "3"
487 487 warning: can't find ancestor for 'c' copied from 'b'!
488 488 $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
489 489 14:0c921c65ef1e 1:5d205f8b35b6 3
490 490 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
491 491
492 492 Resolve conflicted graft
493 493 $ hg up -q 0
494 494 $ echo b > a
495 495 $ hg ci -m 8
496 496 created new head
497 497 $ echo c > a
498 498 $ hg ci -m 9
499 499 $ hg graft 1 --tool internal:fail
500 500 grafting 1:5d205f8b35b6 "1"
501 501 abort: unresolved conflicts, can't continue
502 502 (use 'hg resolve' and 'hg graft --continue')
503 503 [255]
504 504 $ hg resolve --all
505 505 merging a
506 506 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
507 507 [1]
508 508 $ cat a
509 509 <<<<<<< local: aaa4406d4f0a - test: 9
510 510 c
511 511 =======
512 512 b
513 513 >>>>>>> graft: 5d205f8b35b6 - bar: 1
514 514 $ echo b > a
515 515 $ hg resolve -m a
516 516 (no more unresolved files)
517 517 continue: hg graft --continue
518 518 $ hg graft -c
519 519 grafting 1:5d205f8b35b6 "1"
520 520 $ hg export tip --git
521 521 # HG changeset patch
522 522 # User bar
523 523 # Date 0 0
524 524 # Thu Jan 01 00:00:00 1970 +0000
525 525 # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be
526 526 # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6
527 527 1
528 528
529 529 diff --git a/a b/a
530 530 --- a/a
531 531 +++ b/a
532 532 @@ -1,1 +1,1 @@
533 533 -c
534 534 +b
535 535
536 536 Resolve conflicted graft with rename
537 537 $ echo c > a
538 538 $ hg ci -m 10
539 539 $ hg graft 2 --tool internal:fail
540 540 grafting 2:5c095ad7e90f "2"
541 541 abort: unresolved conflicts, can't continue
542 542 (use 'hg resolve' and 'hg graft --continue')
543 543 [255]
544 544 $ hg resolve --all
545 545 merging a and b to b
546 546 (no more unresolved files)
547 547 continue: hg graft --continue
548 548 $ hg graft -c
549 549 grafting 2:5c095ad7e90f "2"
550 550 $ hg export tip --git
551 551 # HG changeset patch
552 552 # User test
553 553 # Date 0 0
554 554 # Thu Jan 01 00:00:00 1970 +0000
555 555 # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc
556 556 # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612
557 557 2
558 558
559 559 diff --git a/a b/b
560 560 rename from a
561 561 rename to b
562 562
563 563 Test simple origin(), with and without args
564 564 $ hg log -r 'origin()'
565 565 changeset: 1:5d205f8b35b6
566 566 user: bar
567 567 date: Thu Jan 01 00:00:00 1970 +0000
568 568 summary: 1
569 569
570 570 changeset: 2:5c095ad7e90f
571 571 user: test
572 572 date: Thu Jan 01 00:00:00 1970 +0000
573 573 summary: 2
574 574
575 575 changeset: 3:4c60f11aa304
576 576 user: baz
577 577 date: Thu Jan 01 00:00:00 1970 +0000
578 578 summary: 3
579 579
580 580 changeset: 4:9c233e8e184d
581 581 user: test
582 582 date: Thu Jan 01 00:00:00 1970 +0000
583 583 summary: 4
584 584
585 585 changeset: 5:97f8bfe72746
586 586 branch: stable
587 587 parent: 3:4c60f11aa304
588 588 user: test
589 589 date: Thu Jan 01 00:00:00 1970 +0000
590 590 summary: 5
591 591
592 592 $ hg log -r 'origin(7)'
593 593 changeset: 2:5c095ad7e90f
594 594 user: test
595 595 date: Thu Jan 01 00:00:00 1970 +0000
596 596 summary: 2
597 597
598 598 Now transplant a graft to test following through copies
599 599 $ hg up -q 0
600 600 $ hg branch -q dev
601 601 $ hg ci -qm "dev branch"
602 602 $ hg --config extensions.transplant= transplant -q 7
603 603 $ hg log -r 'origin(.)'
604 604 changeset: 2:5c095ad7e90f
605 605 user: test
606 606 date: Thu Jan 01 00:00:00 1970 +0000
607 607 summary: 2
608 608
609 609 Test that the graft and transplant markers in extra are converted, allowing
610 610 origin() to still work. Note that these recheck the immediately preceeding two
611 611 tests.
612 612 $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted
613 613
614 614 The graft case
615 615 $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n"
616 616 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b
617 617 branch=default
618 618 convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82
619 619 source=e0213322b2c1a5d5d236c74e79666441bee67a7d
620 620 $ hg -R ../converted log -r 'origin(7)'
621 621 changeset: 2:e0213322b2c1
622 622 user: test
623 623 date: Thu Jan 01 00:00:00 1970 +0000
624 624 summary: 2
625 625
626 626 Test that template correctly expands more than one 'extra' (issue4362), and that
627 627 'intermediate-source' is converted.
628 628 $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}"
629 629 Extra: branch=default
630 630 Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9
631 631 Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b
632 632 Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d
633 633
634 634 The transplant case
635 635 $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n"
636 636 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade
637 637 branch=dev
638 638 convert_revision=7e61b508e709a11d28194a5359bc3532d910af21
639 639 transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac\n`h\x9b
640 640 $ hg -R ../converted log -r 'origin(tip)'
641 641 changeset: 2:e0213322b2c1
642 642 user: test
643 643 date: Thu Jan 01 00:00:00 1970 +0000
644 644 summary: 2
645 645
646 646
647 647 Test simple destination
648 648 $ hg log -r 'destination()'
649 649 changeset: 7:ef0ef43d49e7
650 650 parent: 0:68795b066622
651 651 user: foo
652 652 date: Thu Jan 01 00:00:00 1970 +0000
653 653 summary: 2
654 654
655 655 changeset: 8:6b9e5368ca4e
656 656 user: bar
657 657 date: Thu Jan 01 00:00:00 1970 +0000
658 658 summary: 1
659 659
660 660 changeset: 9:1905859650ec
661 661 user: test
662 662 date: Thu Jan 01 00:00:00 1970 +0000
663 663 summary: 5
664 664
665 665 changeset: 10:52dc0b4c6907
666 666 user: test
667 667 date: Thu Jan 01 00:00:00 1970 +0000
668 668 summary: 4
669 669
670 670 changeset: 11:882b35362a6b
671 671 user: test
672 672 date: Thu Jan 01 00:00:00 1970 +0000
673 673 summary: 3
674 674
675 675 changeset: 13:7a4785234d87
676 676 user: foo
677 677 date: Thu Jan 01 00:00:00 1970 +0000
678 678 summary: 2
679 679
680 680 changeset: 14:0c921c65ef1e
681 681 parent: 1:5d205f8b35b6
682 682 user: foo
683 683 date: Thu Jan 01 00:00:00 1970 +0000
684 684 summary: 3
685 685
686 686 changeset: 17:f67661df0c48
687 687 user: bar
688 688 date: Thu Jan 01 00:00:00 1970 +0000
689 689 summary: 1
690 690
691 691 changeset: 19:9627f653b421
692 692 user: test
693 693 date: Thu Jan 01 00:00:00 1970 +0000
694 694 summary: 2
695 695
696 696 changeset: 21:7e61b508e709
697 697 branch: dev
698 698 tag: tip
699 699 user: foo
700 700 date: Thu Jan 01 00:00:00 1970 +0000
701 701 summary: 2
702 702
703 703 $ hg log -r 'destination(2)'
704 704 changeset: 7:ef0ef43d49e7
705 705 parent: 0:68795b066622
706 706 user: foo
707 707 date: Thu Jan 01 00:00:00 1970 +0000
708 708 summary: 2
709 709
710 710 changeset: 13:7a4785234d87
711 711 user: foo
712 712 date: Thu Jan 01 00:00:00 1970 +0000
713 713 summary: 2
714 714
715 715 changeset: 19:9627f653b421
716 716 user: test
717 717 date: Thu Jan 01 00:00:00 1970 +0000
718 718 summary: 2
719 719
720 720 changeset: 21:7e61b508e709
721 721 branch: dev
722 722 tag: tip
723 723 user: foo
724 724 date: Thu Jan 01 00:00:00 1970 +0000
725 725 summary: 2
726 726
727 727 Transplants of grafts can find a destination...
728 728 $ hg log -r 'destination(7)'
729 729 changeset: 21:7e61b508e709
730 730 branch: dev
731 731 tag: tip
732 732 user: foo
733 733 date: Thu Jan 01 00:00:00 1970 +0000
734 734 summary: 2
735 735
736 736 ... grafts of grafts unfortunately can't
737 737 $ hg graft -q 13 --debug
738 738 scanning for duplicate grafts
739 739 grafting 13:7a4785234d87 "2"
740 unmatched files new in both:
741 b
742 740 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
743 741 src: 'a' -> dst: 'b' *
744 742 checking for directory renames
745 743 resolving manifests
746 744 branchmerge: True, force: True, partial: False
747 745 ancestor: b592ea63bb0c, local: 7e61b508e709+, remote: 7a4785234d87
748 746 starting 4 threads for background file closing (?)
749 747 committing files:
750 748 b
751 749 warning: can't find ancestor for 'b' copied from 'a'!
752 750 reusing manifest form p1 (listed files actually unchanged)
753 751 committing changelog
754 752 updating the branch cache
755 753 $ hg log -r 'destination(13)'
756 754 All copies of a cset
757 755 $ hg log -r 'origin(13) or destination(origin(13))'
758 756 changeset: 2:5c095ad7e90f
759 757 user: test
760 758 date: Thu Jan 01 00:00:00 1970 +0000
761 759 summary: 2
762 760
763 761 changeset: 7:ef0ef43d49e7
764 762 parent: 0:68795b066622
765 763 user: foo
766 764 date: Thu Jan 01 00:00:00 1970 +0000
767 765 summary: 2
768 766
769 767 changeset: 13:7a4785234d87
770 768 user: foo
771 769 date: Thu Jan 01 00:00:00 1970 +0000
772 770 summary: 2
773 771
774 772 changeset: 19:9627f653b421
775 773 user: test
776 774 date: Thu Jan 01 00:00:00 1970 +0000
777 775 summary: 2
778 776
779 777 changeset: 21:7e61b508e709
780 778 branch: dev
781 779 user: foo
782 780 date: Thu Jan 01 00:00:00 1970 +0000
783 781 summary: 2
784 782
785 783 changeset: 22:3a4e92d81b97
786 784 branch: dev
787 785 tag: tip
788 786 user: foo
789 787 date: Thu Jan 01 00:00:00 1970 +0000
790 788 summary: 2
791 789
792 790
793 791 graft works on complex revset
794 792
795 793 $ hg graft 'origin(13) or destination(origin(13))'
796 794 skipping ancestor revision 21:7e61b508e709
797 795 skipping ancestor revision 22:3a4e92d81b97
798 796 skipping revision 2:5c095ad7e90f (already grafted to 22:3a4e92d81b97)
799 797 grafting 7:ef0ef43d49e7 "2"
800 798 warning: can't find ancestor for 'b' copied from 'a'!
801 799 grafting 13:7a4785234d87 "2"
802 800 warning: can't find ancestor for 'b' copied from 'a'!
803 801 grafting 19:9627f653b421 "2"
804 802 merging b
805 803 warning: can't find ancestor for 'b' copied from 'a'!
806 804
807 805 graft with --force (still doesn't graft merges)
808 806
809 807 $ hg graft 19 0 6
810 808 skipping ungraftable merge revision 6
811 809 skipping ancestor revision 0:68795b066622
812 810 skipping already grafted revision 19:9627f653b421 (22:3a4e92d81b97 also has origin 2:5c095ad7e90f)
813 811 [255]
814 812 $ hg graft 19 0 6 --force
815 813 skipping ungraftable merge revision 6
816 814 grafting 19:9627f653b421 "2"
817 815 merging b
818 816 warning: can't find ancestor for 'b' copied from 'a'!
819 817 grafting 0:68795b066622 "0"
820 818
821 819 graft --force after backout
822 820
823 821 $ echo abc > a
824 822 $ hg ci -m 28
825 823 $ hg backout 28
826 824 reverting a
827 825 changeset 29:9d95e865b00c backs out changeset 28:cc20d29aec8d
828 826 $ hg graft 28
829 827 skipping ancestor revision 28:cc20d29aec8d
830 828 [255]
831 829 $ hg graft 28 --force
832 830 grafting 28:cc20d29aec8d "28"
833 831 merging a
834 832 $ cat a
835 833 abc
836 834
837 835 graft --continue after --force
838 836
839 837 $ echo def > a
840 838 $ hg ci -m 31
841 839 $ hg graft 28 --force --tool internal:fail
842 840 grafting 28:cc20d29aec8d "28"
843 841 abort: unresolved conflicts, can't continue
844 842 (use 'hg resolve' and 'hg graft --continue')
845 843 [255]
846 844 $ hg resolve --all
847 845 merging a
848 846 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
849 847 [1]
850 848 $ echo abc > a
851 849 $ hg resolve -m a
852 850 (no more unresolved files)
853 851 continue: hg graft --continue
854 852 $ hg graft -c
855 853 grafting 28:cc20d29aec8d "28"
856 854 $ cat a
857 855 abc
858 856
859 857 Continue testing same origin policy, using revision numbers from test above
860 858 but do some destructive editing of the repo:
861 859
862 860 $ hg up -qC 7
863 861 $ hg tag -l -r 13 tmp
864 862 $ hg --config extensions.strip= strip 2
865 863 saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg
866 864 $ hg graft tmp
867 865 skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f)
868 866 [255]
869 867
870 868 Empty graft
871 869
872 870 $ hg up -qr 26
873 871 $ hg tag -f something
874 872 $ hg graft -qr 27
875 873 $ hg graft -f 27
876 874 grafting 27:17d42b8f5d50 "28"
877 875 note: graft of 27:17d42b8f5d50 created no changes to commit
878 876
879 877 $ cd ..
880 878
881 879 Graft to duplicate a commit
882 880
883 881 $ hg init graftsibling
884 882 $ cd graftsibling
885 883 $ touch a
886 884 $ hg commit -qAm a
887 885 $ touch b
888 886 $ hg commit -qAm b
889 887 $ hg log -G -T '{rev}\n'
890 888 @ 1
891 889 |
892 890 o 0
893 891
894 892 $ hg up -q 0
895 893 $ hg graft -r 1
896 894 grafting 1:0e067c57feba "b" (tip)
897 895 $ hg log -G -T '{rev}\n'
898 896 @ 2
899 897 |
900 898 | o 1
901 899 |/
902 900 o 0
903 901
904 902 Graft to duplicate a commit twice
905 903
906 904 $ hg up -q 0
907 905 $ hg graft -r 2
908 906 grafting 2:044ec77f6389 "b" (tip)
909 907 $ hg log -G -T '{rev}\n'
910 908 @ 3
911 909 |
912 910 | o 2
913 911 |/
914 912 | o 1
915 913 |/
916 914 o 0
917 915
918 916 Graft from behind a move or rename
919 917 ==================================
920 918
921 919 NOTE: This is affected by issue5343, and will need updating when it's fixed
922 920
923 921 Consider this topology for a regular graft:
924 922
925 923 o c1
926 924 |
927 925 | o c2
928 926 | |
929 927 | o ca # stands for "common ancestor"
930 928 |/
931 929 o cta # stands for "common topological ancestor"
932 930
933 931 Note that in issue5343, ca==cta.
934 932
935 933 The following table shows the possible cases. Here, "x->y" and, equivalently,
936 934 "y<-x", where x is an ancestor of y, means that some copy happened from x to y.
937 935
938 936 name | c1<-cta | cta<->ca | ca->c2
939 937 A.0 | | |
940 938 A.1 | X | |
941 939 A.2 | | X |
942 940 A.3 | | | X
943 941 A.4 | X | X |
944 942 A.5 | X | | X
945 943 A.6 | | X | X
946 944 A.7 | X | X | X
947 945
948 946 A.0 is trivial, and doesn't need copy tracking.
949 947 For A.1, a forward rename is recorded in the c1 pass, to be followed later.
950 948 In A.2, the rename is recorded in the c2 pass and followed backwards.
951 949 A.3 is recorded in the c2 pass as a forward rename to be duplicated on target.
952 950 In A.4, both passes of checkcopies record incomplete renames, which are
953 951 then joined in mergecopies to record a rename to be followed.
954 952 In A.5 and A.7, the c1 pass records an incomplete rename, while the c2 pass
955 953 records an incomplete divergence. The incomplete rename is then joined to the
956 954 appropriate side of the incomplete divergence, and the result is recorded as a
957 955 divergence. The code doesn't distinguish at all between these two cases, since
958 956 the end result of them is the same: an incomplete divergence joined with an
959 957 incomplete rename into a divergence.
960 958 Finally, A.6 records a divergence entirely in the c2 pass.
961 959
962 960 A.4 has a degenerate case a<-b<-a->a, where checkcopies isn't needed at all.
963 961 A.5 has a special case a<-b<-b->a, which is treated like a<-b->a in a merge.
964 962 A.5 has issue5343 as a special case.
965 963 A.6 has a special case a<-a<-b->a. Here, checkcopies will find a spurious
966 964 incomplete divergence, which is in fact complete. This is handled later in
967 965 mergecopies.
968 966 A.7 has 4 special cases: a<-b<-a->b (the "ping-pong" case), a<-b<-c->b,
969 967 a<-b<-a->c and a<-b<-c->a. Of these, only the "ping-pong" case is interesting,
970 968 the others are fairly trivial (a<-b<-c->b and a<-b<-a->c proceed like the base
971 969 case, a<-b<-c->a is treated the same as a<-b<-b->a).
972 970
973 971 f5a therefore tests the "ping-pong" rename case, where a file is renamed to the
974 972 same name on both branches, then the rename is backed out on one branch, and
975 973 the backout is grafted to the other branch. This creates a challenging rename
976 974 sequence of a<-b<-a->b in the graft target, topological CA, graft CA and graft
977 975 source, respectively. Since rename detection will run on the c1 side for such a
978 976 sequence (as for technical reasons, we split the c1 and c2 sides not at the
979 977 graft CA, but rather at the topological CA), it will pick up a false rename,
980 978 and cause a spurious merge conflict. This false rename is always exactly the
981 979 reverse of the true rename that would be detected on the c2 side, so we can
982 980 correct for it by detecting this condition and reversing as necessary.
983 981
984 982 First, set up the repository with commits to be grafted
985 983
986 984 $ hg init ../graftmove
987 985 $ cd ../graftmove
988 986 $ echo c1a > f1a
989 987 $ echo c2a > f2a
990 988 $ echo c3a > f3a
991 989 $ echo c4a > f4a
992 990 $ echo c5a > f5a
993 991 $ hg ci -qAm A0
994 992 $ hg mv f1a f1b
995 993 $ hg mv f3a f3b
996 994 $ hg mv f5a f5b
997 995 $ hg ci -qAm B0
998 996 $ echo c1c > f1b
999 997 $ hg mv f2a f2c
1000 998 $ hg mv f5b f5a
1001 999 $ echo c5c > f5a
1002 1000 $ hg ci -qAm C0
1003 1001 $ hg mv f3b f3d
1004 1002 $ echo c4d > f4a
1005 1003 $ hg ci -qAm D0
1006 1004 $ hg log -G
1007 1005 @ changeset: 3:b69f5839d2d9
1008 1006 | tag: tip
1009 1007 | user: test
1010 1008 | date: Thu Jan 01 00:00:00 1970 +0000
1011 1009 | summary: D0
1012 1010 |
1013 1011 o changeset: 2:f58c7e2b28fa
1014 1012 | user: test
1015 1013 | date: Thu Jan 01 00:00:00 1970 +0000
1016 1014 | summary: C0
1017 1015 |
1018 1016 o changeset: 1:3d7bba921b5d
1019 1017 | user: test
1020 1018 | date: Thu Jan 01 00:00:00 1970 +0000
1021 1019 | summary: B0
1022 1020 |
1023 1021 o changeset: 0:11f7a1b56675
1024 1022 user: test
1025 1023 date: Thu Jan 01 00:00:00 1970 +0000
1026 1024 summary: A0
1027 1025
1028 1026
1029 1027 Test the cases A.2 (f1x), A.3 (f2x) and a special case of A.6 (f5x) where the
1030 1028 two renames actually converge to the same name (thus no actual divergence).
1031 1029
1032 1030 $ hg up -q 'desc("A0")'
1033 1031 $ HGEDITOR="echo C1 >" hg graft -r 'desc("C0")' --edit
1034 1032 grafting 2:f58c7e2b28fa "C0"
1035 1033 merging f1a and f1b to f1a
1036 1034 merging f5a
1037 1035 warning: can't find ancestor for 'f5a' copied from 'f5b'!
1038 1036 $ hg status --change .
1039 1037 M f1a
1040 1038 M f5a
1041 1039 A f2c
1042 1040 R f2a
1043 1041 $ hg cat f1a
1044 1042 c1c
1045 1043 $ hg cat f1b
1046 1044 f1b: no such file in rev c9763722f9bd
1047 1045 [1]
1048 1046
1049 1047 Test the cases A.0 (f4x) and A.6 (f3x)
1050 1048
1051 1049 $ HGEDITOR="echo D1 >" hg graft -r 'desc("D0")' --edit
1052 1050 grafting 3:b69f5839d2d9 "D0"
1053 1051 note: possible conflict - f3b was renamed multiple times to:
1054 1052 f3a
1055 1053 f3d
1056 1054 warning: can't find ancestor for 'f3d' copied from 'f3b'!
1057 1055
1058 1056 Set up the repository for some further tests
1059 1057
1060 1058 $ hg up -q "min(desc("A0"))"
1061 1059 $ hg mv f1a f1e
1062 1060 $ echo c2e > f2a
1063 1061 $ hg mv f3a f3e
1064 1062 $ hg mv f4a f4e
1065 1063 $ hg mv f5a f5b
1066 1064 $ hg ci -qAm "E0"
1067 1065 $ hg up -q "min(desc("A0"))"
1068 1066 $ hg cp f1a f1f
1069 1067 $ hg ci -qAm "F0"
1070 1068 $ hg up -q "min(desc("A0"))"
1071 1069 $ hg cp f1a f1g
1072 1070 $ echo c1g > f1g
1073 1071 $ hg ci -qAm "G0"
1074 1072 $ hg log -G
1075 1073 @ changeset: 8:ba67f08fb15a
1076 1074 | tag: tip
1077 1075 | parent: 0:11f7a1b56675
1078 1076 | user: test
1079 1077 | date: Thu Jan 01 00:00:00 1970 +0000
1080 1078 | summary: G0
1081 1079 |
1082 1080 | o changeset: 7:d376ab0d7fda
1083 1081 |/ parent: 0:11f7a1b56675
1084 1082 | user: test
1085 1083 | date: Thu Jan 01 00:00:00 1970 +0000
1086 1084 | summary: F0
1087 1085 |
1088 1086 | o changeset: 6:6bd1736cab86
1089 1087 |/ parent: 0:11f7a1b56675
1090 1088 | user: test
1091 1089 | date: Thu Jan 01 00:00:00 1970 +0000
1092 1090 | summary: E0
1093 1091 |
1094 1092 | o changeset: 5:560daee679da
1095 1093 | | user: test
1096 1094 | | date: Thu Jan 01 00:00:00 1970 +0000
1097 1095 | | summary: D1
1098 1096 | |
1099 1097 | o changeset: 4:c9763722f9bd
1100 1098 |/ parent: 0:11f7a1b56675
1101 1099 | user: test
1102 1100 | date: Thu Jan 01 00:00:00 1970 +0000
1103 1101 | summary: C1
1104 1102 |
1105 1103 | o changeset: 3:b69f5839d2d9
1106 1104 | | user: test
1107 1105 | | date: Thu Jan 01 00:00:00 1970 +0000
1108 1106 | | summary: D0
1109 1107 | |
1110 1108 | o changeset: 2:f58c7e2b28fa
1111 1109 | | user: test
1112 1110 | | date: Thu Jan 01 00:00:00 1970 +0000
1113 1111 | | summary: C0
1114 1112 | |
1115 1113 | o changeset: 1:3d7bba921b5d
1116 1114 |/ user: test
1117 1115 | date: Thu Jan 01 00:00:00 1970 +0000
1118 1116 | summary: B0
1119 1117 |
1120 1118 o changeset: 0:11f7a1b56675
1121 1119 user: test
1122 1120 date: Thu Jan 01 00:00:00 1970 +0000
1123 1121 summary: A0
1124 1122
1125 1123
1126 1124 Test the cases A.4 (f1x), the "ping-pong" special case of A.7 (f5x),
1127 1125 and A.3 with a local content change to be preserved (f2x).
1128 1126
1129 1127 $ hg up -q "desc("E0")"
1130 1128 $ HGEDITOR="echo C2 >" hg graft -r 'desc("C0")' --edit
1131 1129 grafting 2:f58c7e2b28fa "C0"
1132 1130 merging f1e and f1b to f1e
1133 1131 merging f2a and f2c to f2c
1134 1132 merging f5b and f5a to f5a
1135 1133
1136 1134 Test the cases A.1 (f4x) and A.7 (f3x).
1137 1135
1138 1136 $ HGEDITOR="echo D2 >" hg graft -r 'desc("D0")' --edit
1139 1137 grafting 3:b69f5839d2d9 "D0"
1140 1138 note: possible conflict - f3b was renamed multiple times to:
1141 1139 f3d
1142 1140 f3e
1143 1141 merging f4e and f4a to f4e
1144 1142 warning: can't find ancestor for 'f3d' copied from 'f3b'!
1145 1143
1146 1144 $ hg cat f2c
1147 1145 c2e
1148 1146
1149 1147 Test the case A.5 (move case, f1x).
1150 1148
1151 1149 $ hg up -q "desc("C0")"
1152 1150 BROKEN: Shouldn't get the warning about missing ancestor
1153 1151 $ HGEDITOR="echo E1 >" hg graft -r 'desc("E0")' --edit
1154 1152 grafting 6:6bd1736cab86 "E0"
1155 1153 note: possible conflict - f1a was renamed multiple times to:
1156 1154 f1b
1157 1155 f1e
1158 1156 note: possible conflict - f3a was renamed multiple times to:
1159 1157 f3b
1160 1158 f3e
1161 1159 merging f2c and f2a to f2c
1162 1160 merging f5a and f5b to f5b
1163 1161 warning: can't find ancestor for 'f1e' copied from 'f1a'!
1164 1162 warning: can't find ancestor for 'f3e' copied from 'f3a'!
1165 1163 $ cat f1e
1166 1164 c1a
1167 1165
1168 1166 Test the case A.5 (copy case, f1x).
1169 1167
1170 1168 $ hg up -q "desc("C0")"
1171 1169 BROKEN: Shouldn't get the warning about missing ancestor
1172 1170 $ HGEDITOR="echo F1 >" hg graft -r 'desc("F0")' --edit
1173 1171 grafting 7:d376ab0d7fda "F0"
1174 1172 warning: can't find ancestor for 'f1f' copied from 'f1a'!
1175 1173 BROKEN: f1f should be marked a copy from f1b
1176 1174 $ hg st --copies --change .
1177 1175 A f1f
1178 1176 BROKEN: f1f should have the new content from f1b (i.e. "c1c")
1179 1177 $ cat f1f
1180 1178 c1a
1181 1179
1182 1180 Test the case A.5 (copy+modify case, f1x).
1183 1181
1184 1182 $ hg up -q "desc("C0")"
1185 1183 BROKEN: We should get a merge conflict from the 3-way merge between f1b in C0
1186 1184 (content "c1c") and f1g in G0 (content "c1g") with f1a in A0 as base (content
1187 1185 "c1a")
1188 1186 $ HGEDITOR="echo G1 >" hg graft -r 'desc("G0")' --edit
1189 1187 grafting 8:ba67f08fb15a "G0"
1190 1188 warning: can't find ancestor for 'f1g' copied from 'f1a'!
1191 1189
1192 1190 Check the results of the grafts tested
1193 1191
1194 1192 $ hg log -CGv --patch --git
1195 1193 @ changeset: 13:ef3adf6c20a4
1196 1194 | tag: tip
1197 1195 | parent: 2:f58c7e2b28fa
1198 1196 | user: test
1199 1197 | date: Thu Jan 01 00:00:00 1970 +0000
1200 1198 | files: f1g
1201 1199 | description:
1202 1200 | G1
1203 1201 |
1204 1202 |
1205 1203 | diff --git a/f1g b/f1g
1206 1204 | new file mode 100644
1207 1205 | --- /dev/null
1208 1206 | +++ b/f1g
1209 1207 | @@ -0,0 +1,1 @@
1210 1208 | +c1g
1211 1209 |
1212 1210 | o changeset: 12:b5542d755b54
1213 1211 |/ parent: 2:f58c7e2b28fa
1214 1212 | user: test
1215 1213 | date: Thu Jan 01 00:00:00 1970 +0000
1216 1214 | files: f1f
1217 1215 | description:
1218 1216 | F1
1219 1217 |
1220 1218 |
1221 1219 | diff --git a/f1f b/f1f
1222 1220 | new file mode 100644
1223 1221 | --- /dev/null
1224 1222 | +++ b/f1f
1225 1223 | @@ -0,0 +1,1 @@
1226 1224 | +c1a
1227 1225 |
1228 1226 | o changeset: 11:f8a162271246
1229 1227 |/ parent: 2:f58c7e2b28fa
1230 1228 | user: test
1231 1229 | date: Thu Jan 01 00:00:00 1970 +0000
1232 1230 | files: f1e f2c f3e f4a f4e f5a f5b
1233 1231 | copies: f4e (f4a) f5b (f5a)
1234 1232 | description:
1235 1233 | E1
1236 1234 |
1237 1235 |
1238 1236 | diff --git a/f1e b/f1e
1239 1237 | new file mode 100644
1240 1238 | --- /dev/null
1241 1239 | +++ b/f1e
1242 1240 | @@ -0,0 +1,1 @@
1243 1241 | +c1a
1244 1242 | diff --git a/f2c b/f2c
1245 1243 | --- a/f2c
1246 1244 | +++ b/f2c
1247 1245 | @@ -1,1 +1,1 @@
1248 1246 | -c2a
1249 1247 | +c2e
1250 1248 | diff --git a/f3e b/f3e
1251 1249 | new file mode 100644
1252 1250 | --- /dev/null
1253 1251 | +++ b/f3e
1254 1252 | @@ -0,0 +1,1 @@
1255 1253 | +c3a
1256 1254 | diff --git a/f4a b/f4e
1257 1255 | rename from f4a
1258 1256 | rename to f4e
1259 1257 | diff --git a/f5a b/f5b
1260 1258 | rename from f5a
1261 1259 | rename to f5b
1262 1260 |
1263 1261 | o changeset: 10:93ee502e8b0a
1264 1262 | | user: test
1265 1263 | | date: Thu Jan 01 00:00:00 1970 +0000
1266 1264 | | files: f3d f4e
1267 1265 | | description:
1268 1266 | | D2
1269 1267 | |
1270 1268 | |
1271 1269 | | diff --git a/f3d b/f3d
1272 1270 | | new file mode 100644
1273 1271 | | --- /dev/null
1274 1272 | | +++ b/f3d
1275 1273 | | @@ -0,0 +1,1 @@
1276 1274 | | +c3a
1277 1275 | | diff --git a/f4e b/f4e
1278 1276 | | --- a/f4e
1279 1277 | | +++ b/f4e
1280 1278 | | @@ -1,1 +1,1 @@
1281 1279 | | -c4a
1282 1280 | | +c4d
1283 1281 | |
1284 1282 | o changeset: 9:539cf145f496
1285 1283 | | parent: 6:6bd1736cab86
1286 1284 | | user: test
1287 1285 | | date: Thu Jan 01 00:00:00 1970 +0000
1288 1286 | | files: f1e f2a f2c f5a f5b
1289 1287 | | copies: f2c (f2a) f5a (f5b)
1290 1288 | | description:
1291 1289 | | C2
1292 1290 | |
1293 1291 | |
1294 1292 | | diff --git a/f1e b/f1e
1295 1293 | | --- a/f1e
1296 1294 | | +++ b/f1e
1297 1295 | | @@ -1,1 +1,1 @@
1298 1296 | | -c1a
1299 1297 | | +c1c
1300 1298 | | diff --git a/f2a b/f2c
1301 1299 | | rename from f2a
1302 1300 | | rename to f2c
1303 1301 | | diff --git a/f5b b/f5a
1304 1302 | | rename from f5b
1305 1303 | | rename to f5a
1306 1304 | | --- a/f5b
1307 1305 | | +++ b/f5a
1308 1306 | | @@ -1,1 +1,1 @@
1309 1307 | | -c5a
1310 1308 | | +c5c
1311 1309 | |
1312 1310 | | o changeset: 8:ba67f08fb15a
1313 1311 | | | parent: 0:11f7a1b56675
1314 1312 | | | user: test
1315 1313 | | | date: Thu Jan 01 00:00:00 1970 +0000
1316 1314 | | | files: f1g
1317 1315 | | | copies: f1g (f1a)
1318 1316 | | | description:
1319 1317 | | | G0
1320 1318 | | |
1321 1319 | | |
1322 1320 | | | diff --git a/f1a b/f1g
1323 1321 | | | copy from f1a
1324 1322 | | | copy to f1g
1325 1323 | | | --- a/f1a
1326 1324 | | | +++ b/f1g
1327 1325 | | | @@ -1,1 +1,1 @@
1328 1326 | | | -c1a
1329 1327 | | | +c1g
1330 1328 | | |
1331 1329 | | | o changeset: 7:d376ab0d7fda
1332 1330 | | |/ parent: 0:11f7a1b56675
1333 1331 | | | user: test
1334 1332 | | | date: Thu Jan 01 00:00:00 1970 +0000
1335 1333 | | | files: f1f
1336 1334 | | | copies: f1f (f1a)
1337 1335 | | | description:
1338 1336 | | | F0
1339 1337 | | |
1340 1338 | | |
1341 1339 | | | diff --git a/f1a b/f1f
1342 1340 | | | copy from f1a
1343 1341 | | | copy to f1f
1344 1342 | | |
1345 1343 | o | changeset: 6:6bd1736cab86
1346 1344 | |/ parent: 0:11f7a1b56675
1347 1345 | | user: test
1348 1346 | | date: Thu Jan 01 00:00:00 1970 +0000
1349 1347 | | files: f1a f1e f2a f3a f3e f4a f4e f5a f5b
1350 1348 | | copies: f1e (f1a) f3e (f3a) f4e (f4a) f5b (f5a)
1351 1349 | | description:
1352 1350 | | E0
1353 1351 | |
1354 1352 | |
1355 1353 | | diff --git a/f1a b/f1e
1356 1354 | | rename from f1a
1357 1355 | | rename to f1e
1358 1356 | | diff --git a/f2a b/f2a
1359 1357 | | --- a/f2a
1360 1358 | | +++ b/f2a
1361 1359 | | @@ -1,1 +1,1 @@
1362 1360 | | -c2a
1363 1361 | | +c2e
1364 1362 | | diff --git a/f3a b/f3e
1365 1363 | | rename from f3a
1366 1364 | | rename to f3e
1367 1365 | | diff --git a/f4a b/f4e
1368 1366 | | rename from f4a
1369 1367 | | rename to f4e
1370 1368 | | diff --git a/f5a b/f5b
1371 1369 | | rename from f5a
1372 1370 | | rename to f5b
1373 1371 | |
1374 1372 | | o changeset: 5:560daee679da
1375 1373 | | | user: test
1376 1374 | | | date: Thu Jan 01 00:00:00 1970 +0000
1377 1375 | | | files: f3d f4a
1378 1376 | | | description:
1379 1377 | | | D1
1380 1378 | | |
1381 1379 | | |
1382 1380 | | | diff --git a/f3d b/f3d
1383 1381 | | | new file mode 100644
1384 1382 | | | --- /dev/null
1385 1383 | | | +++ b/f3d
1386 1384 | | | @@ -0,0 +1,1 @@
1387 1385 | | | +c3a
1388 1386 | | | diff --git a/f4a b/f4a
1389 1387 | | | --- a/f4a
1390 1388 | | | +++ b/f4a
1391 1389 | | | @@ -1,1 +1,1 @@
1392 1390 | | | -c4a
1393 1391 | | | +c4d
1394 1392 | | |
1395 1393 | | o changeset: 4:c9763722f9bd
1396 1394 | |/ parent: 0:11f7a1b56675
1397 1395 | | user: test
1398 1396 | | date: Thu Jan 01 00:00:00 1970 +0000
1399 1397 | | files: f1a f2a f2c f5a
1400 1398 | | copies: f2c (f2a)
1401 1399 | | description:
1402 1400 | | C1
1403 1401 | |
1404 1402 | |
1405 1403 | | diff --git a/f1a b/f1a
1406 1404 | | --- a/f1a
1407 1405 | | +++ b/f1a
1408 1406 | | @@ -1,1 +1,1 @@
1409 1407 | | -c1a
1410 1408 | | +c1c
1411 1409 | | diff --git a/f2a b/f2c
1412 1410 | | rename from f2a
1413 1411 | | rename to f2c
1414 1412 | | diff --git a/f5a b/f5a
1415 1413 | | --- a/f5a
1416 1414 | | +++ b/f5a
1417 1415 | | @@ -1,1 +1,1 @@
1418 1416 | | -c5a
1419 1417 | | +c5c
1420 1418 | |
1421 1419 +---o changeset: 3:b69f5839d2d9
1422 1420 | | user: test
1423 1421 | | date: Thu Jan 01 00:00:00 1970 +0000
1424 1422 | | files: f3b f3d f4a
1425 1423 | | copies: f3d (f3b)
1426 1424 | | description:
1427 1425 | | D0
1428 1426 | |
1429 1427 | |
1430 1428 | | diff --git a/f3b b/f3d
1431 1429 | | rename from f3b
1432 1430 | | rename to f3d
1433 1431 | | diff --git a/f4a b/f4a
1434 1432 | | --- a/f4a
1435 1433 | | +++ b/f4a
1436 1434 | | @@ -1,1 +1,1 @@
1437 1435 | | -c4a
1438 1436 | | +c4d
1439 1437 | |
1440 1438 o | changeset: 2:f58c7e2b28fa
1441 1439 | | user: test
1442 1440 | | date: Thu Jan 01 00:00:00 1970 +0000
1443 1441 | | files: f1b f2a f2c f5a f5b
1444 1442 | | copies: f2c (f2a) f5a (f5b)
1445 1443 | | description:
1446 1444 | | C0
1447 1445 | |
1448 1446 | |
1449 1447 | | diff --git a/f1b b/f1b
1450 1448 | | --- a/f1b
1451 1449 | | +++ b/f1b
1452 1450 | | @@ -1,1 +1,1 @@
1453 1451 | | -c1a
1454 1452 | | +c1c
1455 1453 | | diff --git a/f2a b/f2c
1456 1454 | | rename from f2a
1457 1455 | | rename to f2c
1458 1456 | | diff --git a/f5b b/f5a
1459 1457 | | rename from f5b
1460 1458 | | rename to f5a
1461 1459 | | --- a/f5b
1462 1460 | | +++ b/f5a
1463 1461 | | @@ -1,1 +1,1 @@
1464 1462 | | -c5a
1465 1463 | | +c5c
1466 1464 | |
1467 1465 o | changeset: 1:3d7bba921b5d
1468 1466 |/ user: test
1469 1467 | date: Thu Jan 01 00:00:00 1970 +0000
1470 1468 | files: f1a f1b f3a f3b f5a f5b
1471 1469 | copies: f1b (f1a) f3b (f3a) f5b (f5a)
1472 1470 | description:
1473 1471 | B0
1474 1472 |
1475 1473 |
1476 1474 | diff --git a/f1a b/f1b
1477 1475 | rename from f1a
1478 1476 | rename to f1b
1479 1477 | diff --git a/f3a b/f3b
1480 1478 | rename from f3a
1481 1479 | rename to f3b
1482 1480 | diff --git a/f5a b/f5b
1483 1481 | rename from f5a
1484 1482 | rename to f5b
1485 1483 |
1486 1484 o changeset: 0:11f7a1b56675
1487 1485 user: test
1488 1486 date: Thu Jan 01 00:00:00 1970 +0000
1489 1487 files: f1a f2a f3a f4a f5a
1490 1488 description:
1491 1489 A0
1492 1490
1493 1491
1494 1492 diff --git a/f1a b/f1a
1495 1493 new file mode 100644
1496 1494 --- /dev/null
1497 1495 +++ b/f1a
1498 1496 @@ -0,0 +1,1 @@
1499 1497 +c1a
1500 1498 diff --git a/f2a b/f2a
1501 1499 new file mode 100644
1502 1500 --- /dev/null
1503 1501 +++ b/f2a
1504 1502 @@ -0,0 +1,1 @@
1505 1503 +c2a
1506 1504 diff --git a/f3a b/f3a
1507 1505 new file mode 100644
1508 1506 --- /dev/null
1509 1507 +++ b/f3a
1510 1508 @@ -0,0 +1,1 @@
1511 1509 +c3a
1512 1510 diff --git a/f4a b/f4a
1513 1511 new file mode 100644
1514 1512 --- /dev/null
1515 1513 +++ b/f4a
1516 1514 @@ -0,0 +1,1 @@
1517 1515 +c4a
1518 1516 diff --git a/f5a b/f5a
1519 1517 new file mode 100644
1520 1518 --- /dev/null
1521 1519 +++ b/f5a
1522 1520 @@ -0,0 +1,1 @@
1523 1521 +c5a
1524 1522
1525 1523 Check superfluous filemerge of files renamed in the past but untouched by graft
1526 1524
1527 1525 $ echo a > a
1528 1526 $ hg ci -qAma
1529 1527 $ hg mv a b
1530 1528 $ echo b > b
1531 1529 $ hg ci -qAmb
1532 1530 $ echo c > c
1533 1531 $ hg ci -qAmc
1534 1532 $ hg up -q .~2
1535 1533 $ hg graft tip -qt:fail
1536 1534
1537 1535 $ cd ..
1538 1536
1539 1537 Graft a change into a new file previously grafted into a renamed directory
1540 1538
1541 1539 $ hg init dirmovenewfile
1542 1540 $ cd dirmovenewfile
1543 1541 $ mkdir a
1544 1542 $ echo a > a/a
1545 1543 $ hg ci -qAma
1546 1544 $ echo x > a/x
1547 1545 $ hg ci -qAmx
1548 1546 $ hg up -q 0
1549 1547 $ hg mv -q a b
1550 1548 $ hg ci -qAmb
1551 1549 $ hg graft -q 1 # a/x grafted as b/x, but no copy information recorded
1552 1550 $ hg up -q 1
1553 1551 $ echo y > a/x
1554 1552 $ hg ci -qAmy
1555 1553 $ hg up -q 3
1556 1554 $ hg graft -q 4
1557 1555 $ hg status --change .
1558 1556 M b/x
1559 1557
1560 1558 Prepare for test of skipped changesets and how merges can influence it:
1561 1559
1562 1560 $ hg merge -q -r 1 --tool :local
1563 1561 $ hg ci -m m
1564 1562 $ echo xx >> b/x
1565 1563 $ hg ci -m xx
1566 1564
1567 1565 $ hg log -G -T '{rev} {desc|firstline}'
1568 1566 @ 7 xx
1569 1567 |
1570 1568 o 6 m
1571 1569 |\
1572 1570 | o 5 y
1573 1571 | |
1574 1572 +---o 4 y
1575 1573 | |
1576 1574 | o 3 x
1577 1575 | |
1578 1576 | o 2 b
1579 1577 | |
1580 1578 o | 1 x
1581 1579 |/
1582 1580 o 0 a
1583 1581
1584 1582 Grafting of plain changes correctly detects that 3 and 5 should be skipped:
1585 1583
1586 1584 $ hg up -qCr 4
1587 1585 $ hg graft --tool :local -r 2::5
1588 1586 skipping already grafted revision 3:ca093ca2f1d9 (was grafted from 1:13ec5badbf2a)
1589 1587 skipping already grafted revision 5:43e9eb70dab0 (was grafted from 4:6c9a1289e5f1)
1590 1588 grafting 2:42127f193bcd "b"
1591 1589
1592 1590 Extending the graft range to include a (skipped) merge of 3 will not prevent us from
1593 1591 also detecting that both 3 and 5 should be skipped:
1594 1592
1595 1593 $ hg up -qCr 4
1596 1594 $ hg graft --tool :local -r 2::7
1597 1595 skipping ungraftable merge revision 6
1598 1596 skipping already grafted revision 3:ca093ca2f1d9 (was grafted from 1:13ec5badbf2a)
1599 1597 skipping already grafted revision 5:43e9eb70dab0 (was grafted from 4:6c9a1289e5f1)
1600 1598 grafting 2:42127f193bcd "b"
1601 1599 grafting 7:d3c3f2b38ecc "xx"
1602 1600 note: graft of 7:d3c3f2b38ecc created no changes to commit
1603 1601
1604 1602 $ cd ..
1605 1603
1606 1604 Grafted revision should be warned and skipped only once. (issue6024)
1607 1605
1608 1606 $ mkdir issue6024
1609 1607 $ cd issue6024
1610 1608
1611 1609 $ hg init base
1612 1610 $ cd base
1613 1611 $ touch x
1614 1612 $ hg commit -qAminit
1615 1613 $ echo a > x
1616 1614 $ hg commit -mchange
1617 1615 $ hg update -q 0
1618 1616 $ hg graft -r 1
1619 1617 grafting 1:a0b923c546aa "change" (tip)
1620 1618 $ cd ..
1621 1619
1622 1620 $ hg clone -qr 2 base clone
1623 1621 $ cd clone
1624 1622 $ hg pull -q
1625 1623 $ hg merge -q 2
1626 1624 $ hg commit -mmerge
1627 1625 $ hg update -q 0
1628 1626 $ hg graft -r 1
1629 1627 grafting 1:04fc6d444368 "change"
1630 1628 $ hg update -q 3
1631 1629 $ hg log -G -T '{rev}:{node|shortest} <- {extras.source|shortest}\n'
1632 1630 o 4:4e16 <- a0b9
1633 1631 |
1634 1632 | @ 3:f0ac <-
1635 1633 | |\
1636 1634 +---o 2:a0b9 <-
1637 1635 | |
1638 1636 | o 1:04fc <- a0b9
1639 1637 |/
1640 1638 o 0:7848 <-
1641 1639
1642 1640
1643 1641 the source of rev 4 is an ancestor of the working parent, and was also
1644 1642 grafted as rev 1. it should be stripped from the target revisions only once.
1645 1643
1646 1644 $ hg graft -r 4
1647 1645 skipping already grafted revision 4:4e16bab40c9c (1:04fc6d444368 also has origin 2:a0b923c546aa)
1648 1646 [255]
1649 1647
1650 1648 $ cd ../..
1651 1649
1652 1650 Testing the reading of old format graftstate file with newer mercurial
1653 1651
1654 1652 $ hg init oldgraft
1655 1653 $ cd oldgraft
1656 1654 $ for ch in a b c; do echo foo > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
1657 1655 $ hg log -GT "{rev}:{node|short} {desc}\n"
1658 1656 @ 2:8be98ac1a569 added c
1659 1657 |
1660 1658 o 1:80e6d2c47cfe added b
1661 1659 |
1662 1660 o 0:f7ad41964313 added a
1663 1661
1664 1662 $ hg up 0
1665 1663 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1666 1664 $ echo bar > b
1667 1665 $ hg add b
1668 1666 $ hg ci -m "bar to b"
1669 1667 created new head
1670 1668 $ hg graft -r 1 -r 2
1671 1669 grafting 1:80e6d2c47cfe "added b"
1672 1670 merging b
1673 1671 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
1674 1672 abort: unresolved conflicts, can't continue
1675 1673 (use 'hg resolve' and 'hg graft --continue')
1676 1674 [255]
1677 1675
1678 1676 Writing the nodes in old format to graftstate
1679 1677
1680 1678 $ hg log -r 1 -r 2 -T '{node}\n' > .hg/graftstate
1681 1679 $ echo foo > b
1682 1680 $ hg resolve -m
1683 1681 (no more unresolved files)
1684 1682 continue: hg graft --continue
1685 1683 $ hg graft --continue
1686 1684 grafting 1:80e6d2c47cfe "added b"
1687 1685 grafting 2:8be98ac1a569 "added c"
1688 1686
1689 1687 Testing that --user is preserved during conflicts and value is reused while
1690 1688 running `hg graft --continue`
1691 1689
1692 1690 $ hg log -G
1693 1691 @ changeset: 5:711e9fa999f1
1694 1692 | tag: tip
1695 1693 | user: test
1696 1694 | date: Thu Jan 01 00:00:00 1970 +0000
1697 1695 | summary: added c
1698 1696 |
1699 1697 o changeset: 4:e5ad7353b408
1700 1698 | user: test
1701 1699 | date: Thu Jan 01 00:00:00 1970 +0000
1702 1700 | summary: added b
1703 1701 |
1704 1702 o changeset: 3:9e887f7a939c
1705 1703 | parent: 0:f7ad41964313
1706 1704 | user: test
1707 1705 | date: Thu Jan 01 00:00:00 1970 +0000
1708 1706 | summary: bar to b
1709 1707 |
1710 1708 | o changeset: 2:8be98ac1a569
1711 1709 | | user: test
1712 1710 | | date: Thu Jan 01 00:00:00 1970 +0000
1713 1711 | | summary: added c
1714 1712 | |
1715 1713 | o changeset: 1:80e6d2c47cfe
1716 1714 |/ user: test
1717 1715 | date: Thu Jan 01 00:00:00 1970 +0000
1718 1716 | summary: added b
1719 1717 |
1720 1718 o changeset: 0:f7ad41964313
1721 1719 user: test
1722 1720 date: Thu Jan 01 00:00:00 1970 +0000
1723 1721 summary: added a
1724 1722
1725 1723
1726 1724 $ hg up '.^^'
1727 1725 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1728 1726
1729 1727 $ hg graft -r 1 -r 2 --user batman
1730 1728 grafting 1:80e6d2c47cfe "added b"
1731 1729 merging b
1732 1730 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
1733 1731 abort: unresolved conflicts, can't continue
1734 1732 (use 'hg resolve' and 'hg graft --continue')
1735 1733 [255]
1736 1734
1737 1735 $ echo wat > b
1738 1736 $ hg resolve -m
1739 1737 (no more unresolved files)
1740 1738 continue: hg graft --continue
1741 1739
1742 1740 $ hg graft --continue
1743 1741 grafting 1:80e6d2c47cfe "added b"
1744 1742 grafting 2:8be98ac1a569 "added c"
1745 1743
1746 1744 $ hg log -Gr 3::
1747 1745 @ changeset: 7:11a36ffaacf2
1748 1746 | tag: tip
1749 1747 | user: batman
1750 1748 | date: Thu Jan 01 00:00:00 1970 +0000
1751 1749 | summary: added c
1752 1750 |
1753 1751 o changeset: 6:76803afc6511
1754 1752 | parent: 3:9e887f7a939c
1755 1753 | user: batman
1756 1754 | date: Thu Jan 01 00:00:00 1970 +0000
1757 1755 | summary: added b
1758 1756 |
1759 1757 | o changeset: 5:711e9fa999f1
1760 1758 | | user: test
1761 1759 | | date: Thu Jan 01 00:00:00 1970 +0000
1762 1760 | | summary: added c
1763 1761 | |
1764 1762 | o changeset: 4:e5ad7353b408
1765 1763 |/ user: test
1766 1764 | date: Thu Jan 01 00:00:00 1970 +0000
1767 1765 | summary: added b
1768 1766 |
1769 1767 o changeset: 3:9e887f7a939c
1770 1768 | parent: 0:f7ad41964313
1771 1769 ~ user: test
1772 1770 date: Thu Jan 01 00:00:00 1970 +0000
1773 1771 summary: bar to b
1774 1772
1775 1773 Test that --date is preserved and reused in `hg graft --continue`
1776 1774
1777 1775 $ hg up '.^^'
1778 1776 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1779 1777 $ hg graft -r 1 -r 2 --date '1234560000 120'
1780 1778 grafting 1:80e6d2c47cfe "added b"
1781 1779 merging b
1782 1780 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
1783 1781 abort: unresolved conflicts, can't continue
1784 1782 (use 'hg resolve' and 'hg graft --continue')
1785 1783 [255]
1786 1784
1787 1785 $ echo foobar > b
1788 1786 $ hg resolve -m
1789 1787 (no more unresolved files)
1790 1788 continue: hg graft --continue
1791 1789 $ hg graft --continue
1792 1790 grafting 1:80e6d2c47cfe "added b"
1793 1791 grafting 2:8be98ac1a569 "added c"
1794 1792
1795 1793 $ hg log -Gr '.^^::.'
1796 1794 @ changeset: 9:1896b76e007a
1797 1795 | tag: tip
1798 1796 | user: test
1799 1797 | date: Fri Feb 13 21:18:00 2009 -0002
1800 1798 | summary: added c
1801 1799 |
1802 1800 o changeset: 8:ce2b4f1632af
1803 1801 | parent: 3:9e887f7a939c
1804 1802 | user: test
1805 1803 | date: Fri Feb 13 21:18:00 2009 -0002
1806 1804 | summary: added b
1807 1805 |
1808 1806 o changeset: 3:9e887f7a939c
1809 1807 | parent: 0:f7ad41964313
1810 1808 ~ user: test
1811 1809 date: Thu Jan 01 00:00:00 1970 +0000
1812 1810 summary: bar to b
1813 1811
1814 1812 Test that --log is preserved and reused in `hg graft --continue`
1815 1813
1816 1814 $ hg up '.^^'
1817 1815 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1818 1816 $ hg graft -r 1 -r 2 --log
1819 1817 grafting 1:80e6d2c47cfe "added b"
1820 1818 merging b
1821 1819 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
1822 1820 abort: unresolved conflicts, can't continue
1823 1821 (use 'hg resolve' and 'hg graft --continue')
1824 1822 [255]
1825 1823
1826 1824 $ echo foobar > b
1827 1825 $ hg resolve -m
1828 1826 (no more unresolved files)
1829 1827 continue: hg graft --continue
1830 1828
1831 1829 $ hg graft --continue
1832 1830 grafting 1:80e6d2c47cfe "added b"
1833 1831 grafting 2:8be98ac1a569 "added c"
1834 1832
1835 1833 $ hg log -GT "{rev}:{node|short} {desc}" -r '.^^::.'
1836 1834 @ 11:30c1050a58b2 added c
1837 1835 | (grafted from 8be98ac1a56990c2d9ca6861041b8390af7bd6f3)
1838 1836 o 10:ec7eda2313e2 added b
1839 1837 | (grafted from 80e6d2c47cfe5b3185519568327a17a061c7efb6)
1840 1838 o 3:9e887f7a939c bar to b
1841 1839 |
1842 1840 ~
1843 1841
1844 1842 $ cd ..
1845 1843
1846 1844 Testing the --stop flag of `hg graft` which stops the interrupted graft
1847 1845
1848 1846 $ hg init stopgraft
1849 1847 $ cd stopgraft
1850 1848 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
1851 1849
1852 1850 $ hg log -G
1853 1851 @ changeset: 3:9150fe93bec6
1854 1852 | tag: tip
1855 1853 | user: test
1856 1854 | date: Thu Jan 01 00:00:00 1970 +0000
1857 1855 | summary: added d
1858 1856 |
1859 1857 o changeset: 2:155349b645be
1860 1858 | user: test
1861 1859 | date: Thu Jan 01 00:00:00 1970 +0000
1862 1860 | summary: added c
1863 1861 |
1864 1862 o changeset: 1:5f6d8a4bf34a
1865 1863 | user: test
1866 1864 | date: Thu Jan 01 00:00:00 1970 +0000
1867 1865 | summary: added b
1868 1866 |
1869 1867 o changeset: 0:9092f1db7931
1870 1868 user: test
1871 1869 date: Thu Jan 01 00:00:00 1970 +0000
1872 1870 summary: added a
1873 1871
1874 1872 $ hg up '.^^'
1875 1873 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1876 1874
1877 1875 $ echo foo > d
1878 1876 $ hg ci -Aqm "added foo to d"
1879 1877
1880 1878 $ hg graft --stop
1881 1879 abort: no interrupted graft found
1882 1880 [255]
1883 1881
1884 1882 $ hg graft -r 3
1885 1883 grafting 3:9150fe93bec6 "added d"
1886 1884 merging d
1887 1885 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1888 1886 abort: unresolved conflicts, can't continue
1889 1887 (use 'hg resolve' and 'hg graft --continue')
1890 1888 [255]
1891 1889
1892 1890 $ hg graft --stop --continue
1893 1891 abort: cannot use '--continue' and '--stop' together
1894 1892 [255]
1895 1893
1896 1894 $ hg graft --stop -U
1897 1895 abort: cannot specify any other flag with '--stop'
1898 1896 [255]
1899 1897 $ hg graft --stop --rev 4
1900 1898 abort: cannot specify any other flag with '--stop'
1901 1899 [255]
1902 1900 $ hg graft --stop --log
1903 1901 abort: cannot specify any other flag with '--stop'
1904 1902 [255]
1905 1903
1906 1904 $ hg graft --stop
1907 1905 stopped the interrupted graft
1908 1906 working directory is now at a0deacecd59d
1909 1907
1910 1908 $ hg diff
1911 1909
1912 1910 $ hg log -Gr '.'
1913 1911 @ changeset: 4:a0deacecd59d
1914 1912 | tag: tip
1915 1913 ~ parent: 1:5f6d8a4bf34a
1916 1914 user: test
1917 1915 date: Thu Jan 01 00:00:00 1970 +0000
1918 1916 summary: added foo to d
1919 1917
1920 1918 $ hg graft -r 2 -r 3
1921 1919 grafting 2:155349b645be "added c"
1922 1920 grafting 3:9150fe93bec6 "added d"
1923 1921 merging d
1924 1922 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
1925 1923 abort: unresolved conflicts, can't continue
1926 1924 (use 'hg resolve' and 'hg graft --continue')
1927 1925 [255]
1928 1926
1929 1927 $ hg graft --stop
1930 1928 stopped the interrupted graft
1931 1929 working directory is now at 75b447541a9e
1932 1930
1933 1931 $ hg diff
1934 1932
1935 1933 $ hg log -G -T "{rev}:{node|short} {desc}"
1936 1934 @ 5:75b447541a9e added c
1937 1935 |
1938 1936 o 4:a0deacecd59d added foo to d
1939 1937 |
1940 1938 | o 3:9150fe93bec6 added d
1941 1939 | |
1942 1940 | o 2:155349b645be added c
1943 1941 |/
1944 1942 o 1:5f6d8a4bf34a added b
1945 1943 |
1946 1944 o 0:9092f1db7931 added a
1947 1945
1948 1946 $ cd ..
1949 1947
1950 1948 Testing the --abort flag for `hg graft` which aborts and rollback to state
1951 1949 before the graft
1952 1950
1953 1951 $ hg init abortgraft
1954 1952 $ cd abortgraft
1955 1953 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
1956 1954
1957 1955 $ hg up '.^^'
1958 1956 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1959 1957
1960 1958 $ echo x > x
1961 1959 $ hg ci -Aqm "added x"
1962 1960 $ hg up '.^'
1963 1961 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1964 1962 $ echo foo > c
1965 1963 $ hg ci -Aqm "added foo to c"
1966 1964
1967 1965 $ hg log -GT "{rev}:{node|short} {desc}"
1968 1966 @ 5:36b793615f78 added foo to c
1969 1967 |
1970 1968 | o 4:863a25e1a9ea added x
1971 1969 |/
1972 1970 | o 3:9150fe93bec6 added d
1973 1971 | |
1974 1972 | o 2:155349b645be added c
1975 1973 |/
1976 1974 o 1:5f6d8a4bf34a added b
1977 1975 |
1978 1976 o 0:9092f1db7931 added a
1979 1977
1980 1978 $ hg up 9150fe93bec6
1981 1979 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1982 1980
1983 1981 $ hg graft --abort
1984 1982 abort: no interrupted graft to abort
1985 1983 [255]
1986 1984
1987 1985 when stripping is required
1988 1986 $ hg graft -r 4 -r 5
1989 1987 grafting 4:863a25e1a9ea "added x"
1990 1988 grafting 5:36b793615f78 "added foo to c" (tip)
1991 1989 merging c
1992 1990 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
1993 1991 abort: unresolved conflicts, can't continue
1994 1992 (use 'hg resolve' and 'hg graft --continue')
1995 1993 [255]
1996 1994
1997 1995 $ hg graft --continue --abort
1998 1996 abort: cannot use '--continue' and '--abort' together
1999 1997 [255]
2000 1998
2001 1999 $ hg graft --abort --stop
2002 2000 abort: cannot use '--abort' and '--stop' together
2003 2001 [255]
2004 2002
2005 2003 $ hg graft --abort --currentuser
2006 2004 abort: cannot specify any other flag with '--abort'
2007 2005 [255]
2008 2006
2009 2007 $ hg graft --abort --edit
2010 2008 abort: cannot specify any other flag with '--abort'
2011 2009 [255]
2012 2010
2013 2011 $ hg graft --abort
2014 2012 graft aborted
2015 2013 working directory is now at 9150fe93bec6
2016 2014 $ hg log -GT "{rev}:{node|short} {desc}"
2017 2015 o 5:36b793615f78 added foo to c
2018 2016 |
2019 2017 | o 4:863a25e1a9ea added x
2020 2018 |/
2021 2019 | @ 3:9150fe93bec6 added d
2022 2020 | |
2023 2021 | o 2:155349b645be added c
2024 2022 |/
2025 2023 o 1:5f6d8a4bf34a added b
2026 2024 |
2027 2025 o 0:9092f1db7931 added a
2028 2026
2029 2027 when stripping is not required
2030 2028 $ hg graft -r 5
2031 2029 grafting 5:36b793615f78 "added foo to c" (tip)
2032 2030 merging c
2033 2031 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
2034 2032 abort: unresolved conflicts, can't continue
2035 2033 (use 'hg resolve' and 'hg graft --continue')
2036 2034 [255]
2037 2035
2038 2036 $ hg graft --abort
2039 2037 graft aborted
2040 2038 working directory is now at 9150fe93bec6
2041 2039 $ hg log -GT "{rev}:{node|short} {desc}"
2042 2040 o 5:36b793615f78 added foo to c
2043 2041 |
2044 2042 | o 4:863a25e1a9ea added x
2045 2043 |/
2046 2044 | @ 3:9150fe93bec6 added d
2047 2045 | |
2048 2046 | o 2:155349b645be added c
2049 2047 |/
2050 2048 o 1:5f6d8a4bf34a added b
2051 2049 |
2052 2050 o 0:9092f1db7931 added a
2053 2051
2054 2052 when some of the changesets became public
2055 2053
2056 2054 $ hg graft -r 4 -r 5
2057 2055 grafting 4:863a25e1a9ea "added x"
2058 2056 grafting 5:36b793615f78 "added foo to c" (tip)
2059 2057 merging c
2060 2058 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
2061 2059 abort: unresolved conflicts, can't continue
2062 2060 (use 'hg resolve' and 'hg graft --continue')
2063 2061 [255]
2064 2062
2065 2063 $ hg log -GT "{rev}:{node|short} {desc}"
2066 2064 @ 6:6ec71c037d94 added x
2067 2065 |
2068 2066 | o 5:36b793615f78 added foo to c
2069 2067 | |
2070 2068 | | o 4:863a25e1a9ea added x
2071 2069 | |/
2072 2070 o | 3:9150fe93bec6 added d
2073 2071 | |
2074 2072 o | 2:155349b645be added c
2075 2073 |/
2076 2074 o 1:5f6d8a4bf34a added b
2077 2075 |
2078 2076 o 0:9092f1db7931 added a
2079 2077
2080 2078 $ hg phase -r 6 --public
2081 2079
2082 2080 $ hg graft --abort
2083 2081 cannot clean up public changesets 6ec71c037d94
2084 2082 graft aborted
2085 2083 working directory is now at 6ec71c037d94
2086 2084
2087 2085 when we created new changesets on top of existing one
2088 2086
2089 2087 $ hg up '.^^'
2090 2088 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
2091 2089 $ echo y > y
2092 2090 $ hg ci -Aqm "added y"
2093 2091 $ echo z > z
2094 2092 $ hg ci -Aqm "added z"
2095 2093
2096 2094 $ hg up 3
2097 2095 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
2098 2096 $ hg log -GT "{rev}:{node|short} {desc}"
2099 2097 o 8:637f9e9bbfd4 added z
2100 2098 |
2101 2099 o 7:123221671fd4 added y
2102 2100 |
2103 2101 | o 6:6ec71c037d94 added x
2104 2102 | |
2105 2103 | | o 5:36b793615f78 added foo to c
2106 2104 | | |
2107 2105 | | | o 4:863a25e1a9ea added x
2108 2106 | | |/
2109 2107 | @ | 3:9150fe93bec6 added d
2110 2108 |/ /
2111 2109 o / 2:155349b645be added c
2112 2110 |/
2113 2111 o 1:5f6d8a4bf34a added b
2114 2112 |
2115 2113 o 0:9092f1db7931 added a
2116 2114
2117 2115 $ hg graft -r 8 -r 7 -r 5
2118 2116 grafting 8:637f9e9bbfd4 "added z" (tip)
2119 2117 grafting 7:123221671fd4 "added y"
2120 2118 grafting 5:36b793615f78 "added foo to c"
2121 2119 merging c
2122 2120 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
2123 2121 abort: unresolved conflicts, can't continue
2124 2122 (use 'hg resolve' and 'hg graft --continue')
2125 2123 [255]
2126 2124
2127 2125 $ cd ..
2128 2126 $ hg init pullrepo
2129 2127 $ cd pullrepo
2130 2128 $ cat >> .hg/hgrc <<EOF
2131 2129 > [phases]
2132 2130 > publish=False
2133 2131 > EOF
2134 2132 $ hg pull ../abortgraft --config phases.publish=False
2135 2133 pulling from ../abortgraft
2136 2134 requesting all changes
2137 2135 adding changesets
2138 2136 adding manifests
2139 2137 adding file changes
2140 2138 added 11 changesets with 9 changes to 8 files (+4 heads)
2141 2139 new changesets 9092f1db7931:6b98ff0062dd (6 drafts)
2142 2140 (run 'hg heads' to see heads, 'hg merge' to merge)
2143 2141 $ hg up 9
2144 2142 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
2145 2143 $ echo w > w
2146 2144 $ hg ci -Aqm "added w" --config phases.publish=False
2147 2145
2148 2146 $ cd ../abortgraft
2149 2147 $ hg pull ../pullrepo
2150 2148 pulling from ../pullrepo
2151 2149 searching for changes
2152 2150 adding changesets
2153 2151 adding manifests
2154 2152 adding file changes
2155 2153 added 1 changesets with 1 changes to 1 files (+1 heads)
2156 2154 new changesets 311dfc6cf3bf (1 drafts)
2157 2155 (run 'hg heads .' to see heads, 'hg merge' to merge)
2158 2156
2159 2157 $ hg graft --abort
2160 2158 new changesets detected on destination branch, can't strip
2161 2159 graft aborted
2162 2160 working directory is now at 6b98ff0062dd
2163 2161
2164 2162 $ cd ..
2165 2163
2166 2164 ============================
2167 2165 Testing --no-commit option:|
2168 2166 ============================
2169 2167
2170 2168 $ hg init nocommit
2171 2169 $ cd nocommit
2172 2170 $ echo a > a
2173 2171 $ hg ci -qAma
2174 2172 $ echo b > b
2175 2173 $ hg ci -qAmb
2176 2174 $ hg up -q 0
2177 2175 $ echo c > c
2178 2176 $ hg ci -qAmc
2179 2177 $ hg log -GT "{rev}:{node|short} {desc}\n"
2180 2178 @ 2:d36c0562f908 c
2181 2179 |
2182 2180 | o 1:d2ae7f538514 b
2183 2181 |/
2184 2182 o 0:cb9a9f314b8b a
2185 2183
2186 2184
2187 2185 Check reporting when --no-commit used with non-applicable options:
2188 2186
2189 2187 $ hg graft 1 --no-commit -e
2190 2188 abort: cannot specify --no-commit and --edit together
2191 2189 [255]
2192 2190
2193 2191 $ hg graft 1 --no-commit --log
2194 2192 abort: cannot specify --no-commit and --log together
2195 2193 [255]
2196 2194
2197 2195 $ hg graft 1 --no-commit -D
2198 2196 abort: cannot specify --no-commit and --currentdate together
2199 2197 [255]
2200 2198
2201 2199 Test --no-commit is working:
2202 2200 $ hg graft 1 --no-commit
2203 2201 grafting 1:d2ae7f538514 "b"
2204 2202
2205 2203 $ hg log -GT "{rev}:{node|short} {desc}\n"
2206 2204 @ 2:d36c0562f908 c
2207 2205 |
2208 2206 | o 1:d2ae7f538514 b
2209 2207 |/
2210 2208 o 0:cb9a9f314b8b a
2211 2209
2212 2210
2213 2211 $ hg diff
2214 2212 diff -r d36c0562f908 b
2215 2213 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2216 2214 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2217 2215 @@ -0,0 +1,1 @@
2218 2216 +b
2219 2217
2220 2218 Prepare wrdir to check --no-commit is resepected after --continue:
2221 2219
2222 2220 $ hg up -qC
2223 2221 $ echo A>a
2224 2222 $ hg ci -qm "A in file a"
2225 2223 $ hg up -q 1
2226 2224 $ echo B>a
2227 2225 $ hg ci -qm "B in file a"
2228 2226 $ hg log -GT "{rev}:{node|short} {desc}\n"
2229 2227 @ 4:2aa9ad1006ff B in file a
2230 2228 |
2231 2229 | o 3:09e253b87e17 A in file a
2232 2230 | |
2233 2231 | o 2:d36c0562f908 c
2234 2232 | |
2235 2233 o | 1:d2ae7f538514 b
2236 2234 |/
2237 2235 o 0:cb9a9f314b8b a
2238 2236
2239 2237
2240 2238 $ hg graft 3 --no-commit
2241 2239 grafting 3:09e253b87e17 "A in file a"
2242 2240 merging a
2243 2241 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
2244 2242 abort: unresolved conflicts, can't continue
2245 2243 (use 'hg resolve' and 'hg graft --continue')
2246 2244 [255]
2247 2245
2248 2246 Resolve conflict:
2249 2247 $ echo A>a
2250 2248 $ hg resolve --mark
2251 2249 (no more unresolved files)
2252 2250 continue: hg graft --continue
2253 2251
2254 2252 $ hg graft --continue
2255 2253 grafting 3:09e253b87e17 "A in file a"
2256 2254 $ hg log -GT "{rev}:{node|short} {desc}\n"
2257 2255 @ 4:2aa9ad1006ff B in file a
2258 2256 |
2259 2257 | o 3:09e253b87e17 A in file a
2260 2258 | |
2261 2259 | o 2:d36c0562f908 c
2262 2260 | |
2263 2261 o | 1:d2ae7f538514 b
2264 2262 |/
2265 2263 o 0:cb9a9f314b8b a
2266 2264
2267 2265 $ hg diff
2268 2266 diff -r 2aa9ad1006ff a
2269 2267 --- a/a Thu Jan 01 00:00:00 1970 +0000
2270 2268 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2271 2269 @@ -1,1 +1,1 @@
2272 2270 -B
2273 2271 +A
2274 2272
2275 2273 $ hg up -qC
2276 2274
2277 2275 Check --no-commit is resepected when passed with --continue:
2278 2276
2279 2277 $ hg graft 3
2280 2278 grafting 3:09e253b87e17 "A in file a"
2281 2279 merging a
2282 2280 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
2283 2281 abort: unresolved conflicts, can't continue
2284 2282 (use 'hg resolve' and 'hg graft --continue')
2285 2283 [255]
2286 2284
2287 2285 Resolve conflict:
2288 2286 $ echo A>a
2289 2287 $ hg resolve --mark
2290 2288 (no more unresolved files)
2291 2289 continue: hg graft --continue
2292 2290
2293 2291 $ hg graft --continue --no-commit
2294 2292 grafting 3:09e253b87e17 "A in file a"
2295 2293 $ hg diff
2296 2294 diff -r 2aa9ad1006ff a
2297 2295 --- a/a Thu Jan 01 00:00:00 1970 +0000
2298 2296 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2299 2297 @@ -1,1 +1,1 @@
2300 2298 -B
2301 2299 +A
2302 2300
2303 2301 $ hg log -GT "{rev}:{node|short} {desc}\n"
2304 2302 @ 4:2aa9ad1006ff B in file a
2305 2303 |
2306 2304 | o 3:09e253b87e17 A in file a
2307 2305 | |
2308 2306 | o 2:d36c0562f908 c
2309 2307 | |
2310 2308 o | 1:d2ae7f538514 b
2311 2309 |/
2312 2310 o 0:cb9a9f314b8b a
2313 2311
2314 2312 $ hg up -qC
2315 2313
2316 2314 Test --no-commit when graft multiple revisions:
2317 2315 When there is conflict:
2318 2316 $ hg graft -r "2::3" --no-commit
2319 2317 grafting 2:d36c0562f908 "c"
2320 2318 grafting 3:09e253b87e17 "A in file a"
2321 2319 merging a
2322 2320 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
2323 2321 abort: unresolved conflicts, can't continue
2324 2322 (use 'hg resolve' and 'hg graft --continue')
2325 2323 [255]
2326 2324
2327 2325 $ echo A>a
2328 2326 $ hg resolve --mark
2329 2327 (no more unresolved files)
2330 2328 continue: hg graft --continue
2331 2329 $ hg graft --continue
2332 2330 grafting 3:09e253b87e17 "A in file a"
2333 2331 $ hg diff
2334 2332 diff -r 2aa9ad1006ff a
2335 2333 --- a/a Thu Jan 01 00:00:00 1970 +0000
2336 2334 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2337 2335 @@ -1,1 +1,1 @@
2338 2336 -B
2339 2337 +A
2340 2338 diff -r 2aa9ad1006ff c
2341 2339 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2342 2340 +++ b/c Thu Jan 01 00:00:00 1970 +0000
2343 2341 @@ -0,0 +1,1 @@
2344 2342 +c
2345 2343
2346 2344 $ hg log -GT "{rev}:{node|short} {desc}\n"
2347 2345 @ 4:2aa9ad1006ff B in file a
2348 2346 |
2349 2347 | o 3:09e253b87e17 A in file a
2350 2348 | |
2351 2349 | o 2:d36c0562f908 c
2352 2350 | |
2353 2351 o | 1:d2ae7f538514 b
2354 2352 |/
2355 2353 o 0:cb9a9f314b8b a
2356 2354
2357 2355 $ hg up -qC
2358 2356
2359 2357 When there is no conflict:
2360 2358 $ echo d>d
2361 2359 $ hg add d -q
2362 2360 $ hg ci -qmd
2363 2361 $ hg up 3 -q
2364 2362 $ hg log -GT "{rev}:{node|short} {desc}\n"
2365 2363 o 5:baefa8927fc0 d
2366 2364 |
2367 2365 o 4:2aa9ad1006ff B in file a
2368 2366 |
2369 2367 | @ 3:09e253b87e17 A in file a
2370 2368 | |
2371 2369 | o 2:d36c0562f908 c
2372 2370 | |
2373 2371 o | 1:d2ae7f538514 b
2374 2372 |/
2375 2373 o 0:cb9a9f314b8b a
2376 2374
2377 2375
2378 2376 $ hg graft -r 1 -r 5 --no-commit
2379 2377 grafting 1:d2ae7f538514 "b"
2380 2378 grafting 5:baefa8927fc0 "d" (tip)
2381 2379 $ hg diff
2382 2380 diff -r 09e253b87e17 b
2383 2381 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2384 2382 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2385 2383 @@ -0,0 +1,1 @@
2386 2384 +b
2387 2385 diff -r 09e253b87e17 d
2388 2386 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2389 2387 +++ b/d Thu Jan 01 00:00:00 1970 +0000
2390 2388 @@ -0,0 +1,1 @@
2391 2389 +d
2392 2390 $ hg log -GT "{rev}:{node|short} {desc}\n"
2393 2391 o 5:baefa8927fc0 d
2394 2392 |
2395 2393 o 4:2aa9ad1006ff B in file a
2396 2394 |
2397 2395 | @ 3:09e253b87e17 A in file a
2398 2396 | |
2399 2397 | o 2:d36c0562f908 c
2400 2398 | |
2401 2399 o | 1:d2ae7f538514 b
2402 2400 |/
2403 2401 o 0:cb9a9f314b8b a
2404 2402
2405 2403 $ cd ..
@@ -1,1052 +1,1031 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], "w")
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
11 11 perform a test merge with possible renaming
12 12 args:
13 13 $1 = action in local branch
14 14 $2 = action in remote branch
15 15 $3 = action in working dir
16 16 $4 = expected result
17 17
18 18 $ tm()
19 19 > {
20 20 > hg init t
21 21 > cd t
22 22 > echo "[merge]" >> .hg/hgrc
23 23 > echo "followcopies = 1" >> .hg/hgrc
24 24 >
25 25 > # base
26 26 > echo base > a
27 27 > echo base > rev # used to force commits
28 28 > hg add a rev
29 29 > hg ci -m "base"
30 30 >
31 31 > # remote
32 32 > echo remote > rev
33 33 > if [ "$2" != "" ] ; then $2 ; fi
34 34 > hg ci -m "remote"
35 35 >
36 36 > # local
37 37 > hg co -q 0
38 38 > echo local > rev
39 39 > if [ "$1" != "" ] ; then $1 ; fi
40 40 > hg ci -m "local"
41 41 >
42 42 > # working dir
43 43 > echo local > rev
44 44 > if [ "$3" != "" ] ; then $3 ; fi
45 45 >
46 46 > # merge
47 47 > echo "--------------"
48 48 > echo "test L:$1 R:$2 W:$3 - $4"
49 49 > echo "--------------"
50 50 > hg merge -y --debug --traceback --tool="\"$PYTHON\" ../merge"
51 51 >
52 52 > echo "--------------"
53 53 > hg status -camC -X rev
54 54 >
55 55 > hg ci -m "merge"
56 56 >
57 57 > echo "--------------"
58 58 > echo
59 59 >
60 60 > cd ..
61 61 > rm -r t
62 62 > }
63 63 $ up() {
64 64 > cp rev $1
65 65 > hg add $1 2> /dev/null
66 66 > if [ "$2" != "" ] ; then
67 67 > cp rev $2
68 68 > hg add $2 2> /dev/null
69 69 > fi
70 70 > }
71 71 $ um() { up $1; hg mv $1 $2; }
72 72 $ nc() { hg cp $1 $2; } # just copy
73 73 $ nm() { hg mv $1 $2; } # just move
74 74 $ tm "up a " "nc a b" " " "1 get local a to b"
75 75 created new head
76 76 --------------
77 77 test L:up a R:nc a b W: - 1 get local a to b
78 78 --------------
79 79 unmatched files in other:
80 80 b
81 81 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
82 82 src: 'a' -> dst: 'b' *
83 83 checking for directory renames
84 84 resolving manifests
85 85 branchmerge: True, force: False, partial: False
86 86 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
87 87 preserving a for resolve of b
88 88 preserving rev for resolve of rev
89 89 starting 4 threads for background file closing (?)
90 90 b: remote copied from a -> m (premerge)
91 91 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
92 92 merging a and b to b
93 93 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
94 94 premerge successful
95 95 rev: versions differ -> m (premerge)
96 96 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
97 97 merging rev
98 98 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
99 99 rev: versions differ -> m (merge)
100 100 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
101 101 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 102 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
103 103 merge tool returned: 0
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 unmatched files in local:
118 118 b
119 119 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
120 120 src: 'a' -> dst: 'b' *
121 121 checking for directory renames
122 122 resolving manifests
123 123 branchmerge: True, force: False, partial: False
124 124 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
125 125 preserving b for resolve of b
126 126 preserving rev for resolve of rev
127 127 a: remote is newer -> g
128 128 getting a
129 129 b: local copied/moved from a -> m (premerge)
130 130 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
131 131 merging b and a to b
132 132 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
133 133 premerge successful
134 134 rev: versions differ -> m (premerge)
135 135 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
136 136 merging rev
137 137 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
138 138 rev: versions differ -> m (merge)
139 139 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
140 140 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
141 141 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
142 142 merge tool returned: 0
143 143 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
144 144 (branch merge, don't forget to commit)
145 145 --------------
146 146 M a
147 147 M b
148 148 a
149 149 --------------
150 150
151 151 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
152 152 created new head
153 153 --------------
154 154 test L:up a R:nm a b W: - 3 get local a change to b, remove a
155 155 --------------
156 156 unmatched files in other:
157 157 b
158 158 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
159 159 src: 'a' -> dst: 'b' *
160 160 checking for directory renames
161 161 resolving manifests
162 162 branchmerge: True, force: False, partial: False
163 163 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
164 164 preserving a for resolve of b
165 165 preserving rev for resolve of rev
166 166 removing a
167 167 starting 4 threads for background file closing (?)
168 168 b: remote moved from a -> m (premerge)
169 169 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
170 170 merging a and b to b
171 171 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
172 172 premerge successful
173 173 rev: versions differ -> m (premerge)
174 174 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
175 175 merging rev
176 176 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
177 177 rev: versions differ -> m (merge)
178 178 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
179 179 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
180 180 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
181 181 merge tool returned: 0
182 182 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
183 183 (branch merge, don't forget to commit)
184 184 --------------
185 185 M b
186 186 a
187 187 --------------
188 188
189 189 $ tm "nm a b" "up a " " " "4 get remote change to b"
190 190 created new head
191 191 --------------
192 192 test L:nm a b R:up a W: - 4 get remote change to b
193 193 --------------
194 194 unmatched files in local:
195 195 b
196 196 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
197 197 src: 'a' -> dst: 'b' *
198 198 checking for directory renames
199 199 resolving manifests
200 200 branchmerge: True, force: False, partial: False
201 201 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
202 202 preserving b for resolve of b
203 203 preserving rev for resolve of rev
204 204 starting 4 threads for background file closing (?)
205 205 b: local copied/moved from a -> m (premerge)
206 206 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
207 207 merging b and a to b
208 208 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
209 209 premerge successful
210 210 rev: versions differ -> m (premerge)
211 211 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
212 212 merging rev
213 213 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
214 214 rev: versions differ -> m (merge)
215 215 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
216 216 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
217 217 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
218 218 merge tool returned: 0
219 219 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
220 220 (branch merge, don't forget to commit)
221 221 --------------
222 222 M b
223 223 a
224 224 --------------
225 225
226 226 $ tm " " "nc a b" " " "5 get b"
227 227 created new head
228 228 --------------
229 229 test L: R:nc a b W: - 5 get b
230 230 --------------
231 231 unmatched files in other:
232 232 b
233 233 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
234 234 src: 'a' -> dst: 'b'
235 235 checking for directory renames
236 236 resolving manifests
237 237 branchmerge: True, force: False, partial: False
238 238 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
239 239 preserving rev for resolve of rev
240 240 b: remote created -> g
241 241 getting b
242 242 rev: versions differ -> m (premerge)
243 243 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
244 244 merging rev
245 245 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
246 246 rev: versions differ -> m (merge)
247 247 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
248 248 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
249 249 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
250 250 merge tool returned: 0
251 251 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
252 252 (branch merge, don't forget to commit)
253 253 --------------
254 254 M b
255 255 C a
256 256 --------------
257 257
258 258 $ tm "nc a b" " " " " "6 nothing"
259 259 created new head
260 260 --------------
261 261 test L:nc a b R: W: - 6 nothing
262 262 --------------
263 263 unmatched files in local:
264 264 b
265 265 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
266 266 src: 'a' -> dst: 'b'
267 267 checking for directory renames
268 268 resolving manifests
269 269 branchmerge: True, force: False, partial: False
270 270 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
271 271 preserving rev for resolve of rev
272 272 starting 4 threads for background file closing (?)
273 273 rev: versions differ -> m (premerge)
274 274 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
275 275 merging rev
276 276 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
277 277 rev: versions differ -> m (merge)
278 278 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
279 279 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
280 280 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
281 281 merge tool returned: 0
282 282 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
283 283 (branch merge, don't forget to commit)
284 284 --------------
285 285 C a
286 286 C b
287 287 --------------
288 288
289 289 $ tm " " "nm a b" " " "7 get b"
290 290 created new head
291 291 --------------
292 292 test L: R:nm a b W: - 7 get b
293 293 --------------
294 294 unmatched files in other:
295 295 b
296 296 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
297 297 src: 'a' -> dst: 'b'
298 298 checking for directory renames
299 299 resolving manifests
300 300 branchmerge: True, force: False, partial: False
301 301 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
302 302 preserving rev for resolve of rev
303 303 a: other deleted -> r
304 304 removing a
305 305 b: remote created -> g
306 306 getting b
307 307 rev: versions differ -> m (premerge)
308 308 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
309 309 merging rev
310 310 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
311 311 rev: versions differ -> m (merge)
312 312 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
313 313 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
314 314 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
315 315 merge tool returned: 0
316 316 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
317 317 (branch merge, don't forget to commit)
318 318 --------------
319 319 M b
320 320 --------------
321 321
322 322 $ tm "nm a b" " " " " "8 nothing"
323 323 created new head
324 324 --------------
325 325 test L:nm a b R: W: - 8 nothing
326 326 --------------
327 327 unmatched files in local:
328 328 b
329 329 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
330 330 src: 'a' -> dst: 'b'
331 331 checking for directory renames
332 332 resolving manifests
333 333 branchmerge: True, force: False, partial: False
334 334 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
335 335 preserving rev for resolve of rev
336 336 starting 4 threads for background file closing (?)
337 337 rev: versions differ -> m (premerge)
338 338 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
339 339 merging rev
340 340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
341 341 rev: versions differ -> m (merge)
342 342 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
343 343 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
344 344 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
345 345 merge tool returned: 0
346 346 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
347 347 (branch merge, don't forget to commit)
348 348 --------------
349 349 C b
350 350 --------------
351 351
352 352 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
353 353 created new head
354 354 --------------
355 355 test L:um a b R:um a b W: - 9 do merge with ancestor in a
356 356 --------------
357 unmatched files new in both:
358 b
359 357 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
360 358 src: 'a' -> dst: 'b' *
361 359 checking for directory renames
362 360 resolving manifests
363 361 branchmerge: True, force: False, partial: False
364 362 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
365 363 preserving b for resolve of b
366 364 preserving rev for resolve of rev
367 365 starting 4 threads for background file closing (?)
368 366 b: both renamed from a -> m (premerge)
369 367 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
370 368 merging b
371 369 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
372 370 rev: versions differ -> m (premerge)
373 371 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
374 372 merging rev
375 373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
376 374 b: both renamed from a -> m (merge)
377 375 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
378 376 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
379 377 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
380 378 merge tool returned: 0
381 379 rev: versions differ -> m (merge)
382 380 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
383 381 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
384 382 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
385 383 merge tool returned: 0
386 384 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
387 385 (branch merge, don't forget to commit)
388 386 --------------
389 387 M b
390 388 --------------
391 389
392 390
393 391 m "um a c" "um x c" " " "10 do merge with no ancestor"
394 392
395 393 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
396 394 created new head
397 395 --------------
398 396 test L:nm a b R:nm a c W: - 11 get c, keep b
399 397 --------------
400 398 unmatched files in local:
401 399 b
402 400 unmatched files in other:
403 401 c
404 402 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
405 403 src: 'a' -> dst: 'b' !
406 404 src: 'a' -> dst: 'c' !
407 405 checking for directory renames
408 406 resolving manifests
409 407 branchmerge: True, force: False, partial: False
410 408 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
411 409 note: possible conflict - a was renamed multiple times to:
412 410 b
413 411 c
414 412 preserving rev for resolve of rev
415 413 c: remote created -> g
416 414 getting c
417 415 rev: versions differ -> m (premerge)
418 416 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
419 417 merging rev
420 418 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
421 419 rev: versions differ -> m (merge)
422 420 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
423 421 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
424 422 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
425 423 merge tool returned: 0
426 424 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
427 425 (branch merge, don't forget to commit)
428 426 --------------
429 427 M c
430 428 C b
431 429 --------------
432 430
433 431 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
434 432 created new head
435 433 --------------
436 434 test L:nc a b R:up b W: - 12 merge b no ancestor
437 435 --------------
438 unmatched files new in both:
439 b
440 436 resolving manifests
441 437 branchmerge: True, force: False, partial: False
442 438 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
443 439 preserving b for resolve of b
444 440 preserving rev for resolve of rev
445 441 starting 4 threads for background file closing (?)
446 442 b: both created -> m (premerge)
447 443 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
448 444 merging b
449 445 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
450 446 rev: versions differ -> m (premerge)
451 447 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
452 448 merging rev
453 449 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
454 450 b: both created -> m (merge)
455 451 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
456 452 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
457 453 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
458 454 merge tool returned: 0
459 455 rev: versions differ -> m (merge)
460 456 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
461 457 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
462 458 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
463 459 merge tool returned: 0
464 460 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
465 461 (branch merge, don't forget to commit)
466 462 --------------
467 463 M b
468 464 C a
469 465 --------------
470 466
471 467 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
472 468 created new head
473 469 --------------
474 470 test L:up b R:nm a b W: - 13 merge b no ancestor
475 471 --------------
476 unmatched files new in both:
477 b
478 472 resolving manifests
479 473 branchmerge: True, force: False, partial: False
480 474 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
481 475 preserving b for resolve of b
482 476 preserving rev for resolve of rev
483 477 a: other deleted -> r
484 478 removing a
485 479 starting 4 threads for background file closing (?)
486 480 b: both created -> m (premerge)
487 481 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
488 482 merging b
489 483 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
490 484 rev: versions differ -> m (premerge)
491 485 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
492 486 merging rev
493 487 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
494 488 b: both created -> m (merge)
495 489 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
496 490 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
497 491 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
498 492 merge tool returned: 0
499 493 rev: versions differ -> m (merge)
500 494 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
501 495 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
502 496 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
503 497 merge tool returned: 0
504 498 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
505 499 (branch merge, don't forget to commit)
506 500 --------------
507 501 M b
508 502 --------------
509 503
510 504 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
511 505 created new head
512 506 --------------
513 507 test L:nc a b R:up a b W: - 14 merge b no ancestor
514 508 --------------
515 unmatched files new in both:
516 b
517 509 resolving manifests
518 510 branchmerge: True, force: False, partial: False
519 511 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
520 512 preserving b for resolve of b
521 513 preserving rev for resolve of rev
522 514 a: remote is newer -> g
523 515 getting a
524 516 b: both created -> m (premerge)
525 517 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
526 518 merging b
527 519 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
528 520 rev: versions differ -> m (premerge)
529 521 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
530 522 merging rev
531 523 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
532 524 b: both created -> m (merge)
533 525 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
534 526 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
535 527 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
536 528 merge tool returned: 0
537 529 rev: versions differ -> m (merge)
538 530 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
539 531 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
540 532 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
541 533 merge tool returned: 0
542 534 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
543 535 (branch merge, don't forget to commit)
544 536 --------------
545 537 M a
546 538 M b
547 539 --------------
548 540
549 541 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
550 542 created new head
551 543 --------------
552 544 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
553 545 --------------
554 unmatched files new in both:
555 b
556 546 resolving manifests
557 547 branchmerge: True, force: False, partial: False
558 548 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
559 549 preserving b for resolve of b
560 550 preserving rev for resolve of rev
561 551 a: other deleted -> r
562 552 removing a
563 553 starting 4 threads for background file closing (?)
564 554 b: both created -> m (premerge)
565 555 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
566 556 merging b
567 557 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
568 558 rev: versions differ -> m (premerge)
569 559 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
570 560 merging rev
571 561 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
572 562 b: both created -> m (merge)
573 563 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
574 564 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
575 565 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
576 566 merge tool returned: 0
577 567 rev: versions differ -> m (merge)
578 568 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
579 569 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
580 570 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
581 571 merge tool returned: 0
582 572 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
583 573 (branch merge, don't forget to commit)
584 574 --------------
585 575 M b
586 576 --------------
587 577
588 578 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
589 579 created new head
590 580 --------------
591 581 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
592 582 --------------
593 unmatched files new in both:
594 b
595 583 resolving manifests
596 584 branchmerge: True, force: False, partial: False
597 585 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
598 586 preserving b for resolve of b
599 587 preserving rev for resolve of rev
600 588 a: remote is newer -> g
601 589 getting a
602 590 b: both created -> m (premerge)
603 591 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
604 592 merging b
605 593 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
606 594 rev: versions differ -> m (premerge)
607 595 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
608 596 merging rev
609 597 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
610 598 b: both created -> m (merge)
611 599 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
612 600 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
613 601 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
614 602 merge tool returned: 0
615 603 rev: versions differ -> m (merge)
616 604 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
617 605 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
618 606 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
619 607 merge tool returned: 0
620 608 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
621 609 (branch merge, don't forget to commit)
622 610 --------------
623 611 M a
624 612 M b
625 613 --------------
626 614
627 615 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
628 616 created new head
629 617 --------------
630 618 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
631 619 --------------
632 unmatched files new in both:
633 b
634 620 resolving manifests
635 621 branchmerge: True, force: False, partial: False
636 622 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
637 623 preserving b for resolve of b
638 624 preserving rev for resolve of rev
639 625 starting 4 threads for background file closing (?)
640 626 b: both created -> m (premerge)
641 627 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
642 628 merging b
643 629 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
644 630 rev: versions differ -> m (premerge)
645 631 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
646 632 merging rev
647 633 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
648 634 b: both created -> m (merge)
649 635 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
650 636 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
651 637 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
652 638 merge tool returned: 0
653 639 rev: versions differ -> m (merge)
654 640 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
655 641 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
656 642 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
657 643 merge tool returned: 0
658 644 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
659 645 (branch merge, don't forget to commit)
660 646 --------------
661 647 M b
662 648 C a
663 649 --------------
664 650
665 651 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
666 652 created new head
667 653 --------------
668 654 test L:nm a b R:up a b W: - 18 merge b no ancestor
669 655 --------------
670 unmatched files new in both:
671 b
672 656 resolving manifests
673 657 branchmerge: True, force: False, partial: False
674 658 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
675 659 preserving b for resolve of b
676 660 preserving rev for resolve of rev
677 661 starting 4 threads for background file closing (?)
678 662 a: prompt deleted/changed -> m (premerge)
679 663 picked tool ':prompt' for a (binary False symlink False changedelete True)
680 664 file 'a' was deleted in local [working copy] but was modified in other [merge rev].
681 665 What do you want to do?
682 666 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
683 667 b: both created -> m (premerge)
684 668 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
685 669 merging b
686 670 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
687 671 rev: versions differ -> m (premerge)
688 672 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
689 673 merging rev
690 674 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
691 675 b: both created -> m (merge)
692 676 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
693 677 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
694 678 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
695 679 merge tool returned: 0
696 680 rev: versions differ -> m (merge)
697 681 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
698 682 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
699 683 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
700 684 merge tool returned: 0
701 685 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
702 686 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
703 687 --------------
704 688 M a
705 689 M b
706 690 abort: unresolved merge conflicts (see 'hg help resolve')
707 691 --------------
708 692
709 693 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
710 694 created new head
711 695 --------------
712 696 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
713 697 --------------
714 unmatched files new in both:
715 b
716 698 resolving manifests
717 699 branchmerge: True, force: False, partial: False
718 700 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
719 701 preserving a for resolve of a
720 702 preserving b for resolve of b
721 703 preserving rev for resolve of rev
722 704 starting 4 threads for background file closing (?)
723 705 a: prompt changed/deleted -> m (premerge)
724 706 picked tool ':prompt' for a (binary False symlink False changedelete True)
725 707 file 'a' was deleted in other [merge rev] but was modified in local [working copy].
726 708 What do you want to do?
727 709 use (c)hanged version, (d)elete, or leave (u)nresolved? u
728 710 b: both created -> m (premerge)
729 711 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
730 712 merging b
731 713 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
732 714 rev: versions differ -> m (premerge)
733 715 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
734 716 merging rev
735 717 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
736 718 b: both created -> m (merge)
737 719 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
738 720 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
739 721 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
740 722 merge tool returned: 0
741 723 rev: versions differ -> m (merge)
742 724 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
743 725 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
744 726 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
745 727 merge tool returned: 0
746 728 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
747 729 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
748 730 --------------
749 731 M b
750 732 C a
751 733 abort: unresolved merge conflicts (see 'hg help resolve')
752 734 --------------
753 735
754 736 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
755 737 created new head
756 738 --------------
757 739 test L:up a R:um a b W: - 20 merge a and b to b, remove a
758 740 --------------
759 741 unmatched files in other:
760 742 b
761 743 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
762 744 src: 'a' -> dst: 'b' *
763 745 checking for directory renames
764 746 resolving manifests
765 747 branchmerge: True, force: False, partial: False
766 748 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
767 749 preserving a for resolve of b
768 750 preserving rev for resolve of rev
769 751 removing a
770 752 starting 4 threads for background file closing (?)
771 753 b: remote moved from a -> m (premerge)
772 754 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
773 755 merging a and b to b
774 756 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
775 757 rev: versions differ -> m (premerge)
776 758 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
777 759 merging rev
778 760 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
779 761 b: remote moved from a -> m (merge)
780 762 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
781 763 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
782 764 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
783 765 merge tool returned: 0
784 766 rev: versions differ -> m (merge)
785 767 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
786 768 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
787 769 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
788 770 merge tool returned: 0
789 771 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
790 772 (branch merge, don't forget to commit)
791 773 --------------
792 774 M b
793 775 a
794 776 --------------
795 777
796 778 $ tm "um a b" "up a " " " "21 merge a and b to b"
797 779 created new head
798 780 --------------
799 781 test L:um a b R:up a W: - 21 merge a and b to b
800 782 --------------
801 783 unmatched files in local:
802 784 b
803 785 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
804 786 src: 'a' -> dst: 'b' *
805 787 checking for directory renames
806 788 resolving manifests
807 789 branchmerge: True, force: False, partial: False
808 790 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
809 791 preserving b for resolve of b
810 792 preserving rev for resolve of rev
811 793 starting 4 threads for background file closing (?)
812 794 b: local copied/moved from a -> m (premerge)
813 795 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
814 796 merging b and a to b
815 797 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
816 798 rev: versions differ -> m (premerge)
817 799 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
818 800 merging rev
819 801 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
820 802 b: local copied/moved from a -> m (merge)
821 803 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
822 804 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
823 805 launching merge tool: * ../merge *$TESTTMP/t/t/b* * * (glob)
824 806 merge tool returned: 0
825 807 rev: versions differ -> m (merge)
826 808 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
827 809 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
828 810 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
829 811 merge tool returned: 0
830 812 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
831 813 (branch merge, don't forget to commit)
832 814 --------------
833 815 M b
834 816 a
835 817 --------------
836 818
837 819
838 820 m "nm a b" "um x a" " " "22 get a, keep b"
839 821
840 822 $ tm "nm a b" "up a c" " " "23 get c, keep b"
841 823 created new head
842 824 --------------
843 825 test L:nm a b R:up a c W: - 23 get c, keep b
844 826 --------------
845 827 unmatched files in local:
846 828 b
847 829 unmatched files in other:
848 830 c
849 831 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
850 832 src: 'a' -> dst: 'b' *
851 833 checking for directory renames
852 834 resolving manifests
853 835 branchmerge: True, force: False, partial: False
854 836 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
855 837 preserving b for resolve of b
856 838 preserving rev for resolve of rev
857 839 c: remote created -> g
858 840 getting c
859 841 b: local copied/moved from a -> m (premerge)
860 842 picked tool '* ../merge' for b (binary False symlink False changedelete False) (glob)
861 843 merging b and a to b
862 844 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
863 845 premerge successful
864 846 rev: versions differ -> m (premerge)
865 847 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
866 848 merging rev
867 849 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
868 850 rev: versions differ -> m (merge)
869 851 picked tool '* ../merge' for rev (binary False symlink False changedelete False) (glob)
870 852 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
871 853 launching merge tool: * ../merge *$TESTTMP/t/t/rev* * * (glob)
872 854 merge tool returned: 0
873 855 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
874 856 (branch merge, don't forget to commit)
875 857 --------------
876 858 M b
877 859 a
878 860 M c
879 861 --------------
880 862
881 863
882 864 $ cd ..
883 865
884 866
885 867 Systematic and terse testing of merge merges and ancestor calculation:
886 868
887 869 Expected result:
888 870
889 871 \ a m1 m2 dst
890 872 0 - f f f "versions differ"
891 873 1 f g g g "versions differ"
892 874 2 f f f f "versions differ"
893 875 3 f f g f+g "remote copied to " + f
894 876 4 f f g g "remote moved to " + f
895 877 5 f g f f+g "local copied to " + f2
896 878 6 f g f g "local moved to " + f2
897 879 7 - (f) f f "remote differs from untracked local"
898 880 8 f (f) f f "remote differs from untracked local"
899 881
900 882 $ hg init ancestortest
901 883 $ cd ancestortest
902 884 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
903 885 $ hg ci -Aqm "a"
904 886 $ mkdir 0
905 887 $ touch 0/f
906 888 $ hg mv 1/f 1/g
907 889 $ hg cp 5/f 5/g
908 890 $ hg mv 6/f 6/g
909 891 $ hg rm 8/f
910 892 $ for x in */*; do echo m1 > $x; done
911 893 $ hg ci -Aqm "m1"
912 894 $ hg up -qr0
913 895 $ mkdir 0 7
914 896 $ touch 0/f 7/f
915 897 $ hg mv 1/f 1/g
916 898 $ hg cp 3/f 3/g
917 899 $ hg mv 4/f 4/g
918 900 $ for x in */*; do echo m2 > $x; done
919 901 $ hg ci -Aqm "m2"
920 902 $ hg up -qr1
921 903 $ mkdir 7 8
922 904 $ echo m > 7/f
923 905 $ echo m > 8/f
924 906 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^resolving manifests/,$d' 2> /dev/null
925 907 unmatched files in local:
926 908 5/g
927 909 6/g
928 910 unmatched files in other:
929 911 3/g
930 912 4/g
931 913 7/f
932 unmatched files new in both:
933 0/f
934 1/g
935 914 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
936 915 src: '1/f' -> dst: '1/g' *
937 916 src: '3/f' -> dst: '3/g' *
938 917 src: '4/f' -> dst: '4/g' *
939 918 src: '5/f' -> dst: '5/g' *
940 919 src: '6/f' -> dst: '6/g' *
941 920 checking for directory renames
942 921 $ hg mani
943 922 0/f
944 923 1/g
945 924 2/f
946 925 3/f
947 926 4/f
948 927 5/f
949 928 5/g
950 929 6/g
951 930 $ for f in */*; do echo $f:; cat $f; done
952 931 0/f:
953 932 m1
954 933 0/f.base:
955 934 0/f.local:
956 935 m1
957 936 0/f.orig:
958 937 m1
959 938 0/f.other:
960 939 m2
961 940 1/g:
962 941 m1
963 942 1/g.base:
964 943 a
965 944 1/g.local:
966 945 m1
967 946 1/g.orig:
968 947 m1
969 948 1/g.other:
970 949 m2
971 950 2/f:
972 951 m1
973 952 2/f.base:
974 953 a
975 954 2/f.local:
976 955 m1
977 956 2/f.orig:
978 957 m1
979 958 2/f.other:
980 959 m2
981 960 3/f:
982 961 m1
983 962 3/f.base:
984 963 a
985 964 3/f.local:
986 965 m1
987 966 3/f.orig:
988 967 m1
989 968 3/f.other:
990 969 m2
991 970 3/g:
992 971 m1
993 972 3/g.base:
994 973 a
995 974 3/g.local:
996 975 m1
997 976 3/g.orig:
998 977 m1
999 978 3/g.other:
1000 979 m2
1001 980 4/g:
1002 981 m1
1003 982 4/g.base:
1004 983 a
1005 984 4/g.local:
1006 985 m1
1007 986 4/g.orig:
1008 987 m1
1009 988 4/g.other:
1010 989 m2
1011 990 5/f:
1012 991 m1
1013 992 5/f.base:
1014 993 a
1015 994 5/f.local:
1016 995 m1
1017 996 5/f.orig:
1018 997 m1
1019 998 5/f.other:
1020 999 m2
1021 1000 5/g:
1022 1001 m1
1023 1002 5/g.base:
1024 1003 a
1025 1004 5/g.local:
1026 1005 m1
1027 1006 5/g.orig:
1028 1007 m1
1029 1008 5/g.other:
1030 1009 m2
1031 1010 6/g:
1032 1011 m1
1033 1012 6/g.base:
1034 1013 a
1035 1014 6/g.local:
1036 1015 m1
1037 1016 6/g.orig:
1038 1017 m1
1039 1018 6/g.other:
1040 1019 m2
1041 1020 7/f:
1042 1021 m
1043 1022 7/f.base:
1044 1023 7/f.local:
1045 1024 m
1046 1025 7/f.orig:
1047 1026 m
1048 1027 7/f.other:
1049 1028 m2
1050 1029 8/f:
1051 1030 m2
1052 1031 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now