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