##// END OF EJS Templates
manifestmerge: pass in branchmerge and force separately...
Siddharth Agarwal -
r18605:bcf29565 default
parent child Browse files
Show More
@@ -1,1179 +1,1181 b''
1 1 # Copyright 2009-2010 Gregory P. Ward
2 2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 3 # Copyright 2010-2011 Fog Creek Software
4 4 # Copyright 2010-2011 Unity Technologies
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 '''Overridden Mercurial commands and functions for the largefiles extension'''
10 10
11 11 import os
12 12 import copy
13 13
14 14 from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
15 15 node, archival, error, merge, discovery
16 16 from mercurial.i18n import _
17 17 from mercurial.node import hex
18 18 from hgext import rebase
19 19
20 20 import lfutil
21 21 import lfcommands
22 22
23 23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
24 24
25 25 def installnormalfilesmatchfn(manifest):
26 26 '''overrides scmutil.match so that the matcher it returns will ignore all
27 27 largefiles'''
28 28 oldmatch = None # for the closure
29 29 def overridematch(ctx, pats=[], opts={}, globbed=False,
30 30 default='relpath'):
31 31 match = oldmatch(ctx, pats, opts, globbed, default)
32 32 m = copy.copy(match)
33 33 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
34 34 manifest)
35 35 m._files = filter(notlfile, m._files)
36 36 m._fmap = set(m._files)
37 37 origmatchfn = m.matchfn
38 38 m.matchfn = lambda f: notlfile(f) and origmatchfn(f) or None
39 39 return m
40 40 oldmatch = installmatchfn(overridematch)
41 41
42 42 def installmatchfn(f):
43 43 oldmatch = scmutil.match
44 44 setattr(f, 'oldmatch', oldmatch)
45 45 scmutil.match = f
46 46 return oldmatch
47 47
48 48 def restorematchfn():
49 49 '''restores scmutil.match to what it was before installnormalfilesmatchfn
50 50 was called. no-op if scmutil.match is its original function.
51 51
52 52 Note that n calls to installnormalfilesmatchfn will require n calls to
53 53 restore matchfn to reverse'''
54 54 scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match)
55 55
56 56 def addlargefiles(ui, repo, *pats, **opts):
57 57 large = opts.pop('large', None)
58 58 lfsize = lfutil.getminsize(
59 59 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
60 60
61 61 lfmatcher = None
62 62 if lfutil.islfilesrepo(repo):
63 63 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
64 64 if lfpats:
65 65 lfmatcher = match_.match(repo.root, '', list(lfpats))
66 66
67 67 lfnames = []
68 68 m = scmutil.match(repo[None], pats, opts)
69 69 m.bad = lambda x, y: None
70 70 wctx = repo[None]
71 71 for f in repo.walk(m):
72 72 exact = m.exact(f)
73 73 lfile = lfutil.standin(f) in wctx
74 74 nfile = f in wctx
75 75 exists = lfile or nfile
76 76
77 77 # Don't warn the user when they attempt to add a normal tracked file.
78 78 # The normal add code will do that for us.
79 79 if exact and exists:
80 80 if lfile:
81 81 ui.warn(_('%s already a largefile\n') % f)
82 82 continue
83 83
84 84 if (exact or not exists) and not lfutil.isstandin(f):
85 85 wfile = repo.wjoin(f)
86 86
87 87 # In case the file was removed previously, but not committed
88 88 # (issue3507)
89 89 if not os.path.exists(wfile):
90 90 continue
91 91
92 92 abovemin = (lfsize and
93 93 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
94 94 if large or abovemin or (lfmatcher and lfmatcher(f)):
95 95 lfnames.append(f)
96 96 if ui.verbose or not exact:
97 97 ui.status(_('adding %s as a largefile\n') % m.rel(f))
98 98
99 99 bad = []
100 100 standins = []
101 101
102 102 # Need to lock, otherwise there could be a race condition between
103 103 # when standins are created and added to the repo.
104 104 wlock = repo.wlock()
105 105 try:
106 106 if not opts.get('dry_run'):
107 107 lfdirstate = lfutil.openlfdirstate(ui, repo)
108 108 for f in lfnames:
109 109 standinname = lfutil.standin(f)
110 110 lfutil.writestandin(repo, standinname, hash='',
111 111 executable=lfutil.getexecutable(repo.wjoin(f)))
112 112 standins.append(standinname)
113 113 if lfdirstate[f] == 'r':
114 114 lfdirstate.normallookup(f)
115 115 else:
116 116 lfdirstate.add(f)
117 117 lfdirstate.write()
118 118 bad += [lfutil.splitstandin(f)
119 119 for f in repo[None].add(standins)
120 120 if f in m.files()]
121 121 finally:
122 122 wlock.release()
123 123 return bad
124 124
125 125 def removelargefiles(ui, repo, *pats, **opts):
126 126 after = opts.get('after')
127 127 if not pats and not after:
128 128 raise util.Abort(_('no files specified'))
129 129 m = scmutil.match(repo[None], pats, opts)
130 130 try:
131 131 repo.lfstatus = True
132 132 s = repo.status(match=m, clean=True)
133 133 finally:
134 134 repo.lfstatus = False
135 135 manifest = repo[None].manifest()
136 136 modified, added, deleted, clean = [[f for f in list
137 137 if lfutil.standin(f) in manifest]
138 138 for list in [s[0], s[1], s[3], s[6]]]
139 139
140 140 def warn(files, msg):
141 141 for f in files:
142 142 ui.warn(msg % m.rel(f))
143 143 return int(len(files) > 0)
144 144
145 145 result = 0
146 146
147 147 if after:
148 148 remove, forget = deleted, []
149 149 result = warn(modified + added + clean,
150 150 _('not removing %s: file still exists\n'))
151 151 else:
152 152 remove, forget = deleted + clean, []
153 153 result = warn(modified, _('not removing %s: file is modified (use -f'
154 154 ' to force removal)\n'))
155 155 result = warn(added, _('not removing %s: file has been marked for add'
156 156 ' (use forget to undo)\n')) or result
157 157
158 158 for f in sorted(remove + forget):
159 159 if ui.verbose or not m.exact(f):
160 160 ui.status(_('removing %s\n') % m.rel(f))
161 161
162 162 # Need to lock because standin files are deleted then removed from the
163 163 # repository and we could race in-between.
164 164 wlock = repo.wlock()
165 165 try:
166 166 lfdirstate = lfutil.openlfdirstate(ui, repo)
167 167 for f in remove:
168 168 if not after:
169 169 # If this is being called by addremove, notify the user that we
170 170 # are removing the file.
171 171 if getattr(repo, "_isaddremove", False):
172 172 ui.status(_('removing %s\n') % f)
173 173 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
174 174 lfdirstate.remove(f)
175 175 lfdirstate.write()
176 176 forget = [lfutil.standin(f) for f in forget]
177 177 remove = [lfutil.standin(f) for f in remove]
178 178 repo[None].forget(forget)
179 179 # If this is being called by addremove, let the original addremove
180 180 # function handle this.
181 181 if not getattr(repo, "_isaddremove", False):
182 182 for f in remove:
183 183 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
184 184 repo[None].forget(remove)
185 185 finally:
186 186 wlock.release()
187 187
188 188 return result
189 189
190 190 # For overriding mercurial.hgweb.webcommands so that largefiles will
191 191 # appear at their right place in the manifests.
192 192 def decodepath(orig, path):
193 193 return lfutil.splitstandin(path) or path
194 194
195 195 # -- Wrappers: modify existing commands --------------------------------
196 196
197 197 # Add works by going through the files that the user wanted to add and
198 198 # checking if they should be added as largefiles. Then it makes a new
199 199 # matcher which matches only the normal files and runs the original
200 200 # version of add.
201 201 def overrideadd(orig, ui, repo, *pats, **opts):
202 202 normal = opts.pop('normal')
203 203 if normal:
204 204 if opts.get('large'):
205 205 raise util.Abort(_('--normal cannot be used with --large'))
206 206 return orig(ui, repo, *pats, **opts)
207 207 bad = addlargefiles(ui, repo, *pats, **opts)
208 208 installnormalfilesmatchfn(repo[None].manifest())
209 209 result = orig(ui, repo, *pats, **opts)
210 210 restorematchfn()
211 211
212 212 return (result == 1 or bad) and 1 or 0
213 213
214 214 def overrideremove(orig, ui, repo, *pats, **opts):
215 215 installnormalfilesmatchfn(repo[None].manifest())
216 216 result = orig(ui, repo, *pats, **opts)
217 217 restorematchfn()
218 218 return removelargefiles(ui, repo, *pats, **opts) or result
219 219
220 220 def overridestatusfn(orig, repo, rev2, **opts):
221 221 try:
222 222 repo._repo.lfstatus = True
223 223 return orig(repo, rev2, **opts)
224 224 finally:
225 225 repo._repo.lfstatus = False
226 226
227 227 def overridestatus(orig, ui, repo, *pats, **opts):
228 228 try:
229 229 repo.lfstatus = True
230 230 return orig(ui, repo, *pats, **opts)
231 231 finally:
232 232 repo.lfstatus = False
233 233
234 234 def overridedirty(orig, repo, ignoreupdate=False):
235 235 try:
236 236 repo._repo.lfstatus = True
237 237 return orig(repo, ignoreupdate)
238 238 finally:
239 239 repo._repo.lfstatus = False
240 240
241 241 def overridelog(orig, ui, repo, *pats, **opts):
242 242 def overridematch(ctx, pats=[], opts={}, globbed=False,
243 243 default='relpath'):
244 244 """Matcher that merges root directory with .hglf, suitable for log.
245 245 It is still possible to match .hglf directly.
246 246 For any listed files run log on the standin too.
247 247 matchfn tries both the given filename and with .hglf stripped.
248 248 """
249 249 match = oldmatch(ctx, pats, opts, globbed, default)
250 250 m = copy.copy(match)
251 251 standins = [lfutil.standin(f) for f in m._files]
252 252 m._files.extend(standins)
253 253 m._fmap = set(m._files)
254 254 origmatchfn = m.matchfn
255 255 def lfmatchfn(f):
256 256 lf = lfutil.splitstandin(f)
257 257 if lf is not None and origmatchfn(lf):
258 258 return True
259 259 r = origmatchfn(f)
260 260 return r
261 261 m.matchfn = lfmatchfn
262 262 return m
263 263 oldmatch = installmatchfn(overridematch)
264 264 try:
265 265 repo.lfstatus = True
266 266 return orig(ui, repo, *pats, **opts)
267 267 finally:
268 268 repo.lfstatus = False
269 269 restorematchfn()
270 270
271 271 def overrideverify(orig, ui, repo, *pats, **opts):
272 272 large = opts.pop('large', False)
273 273 all = opts.pop('lfa', False)
274 274 contents = opts.pop('lfc', False)
275 275
276 276 result = orig(ui, repo, *pats, **opts)
277 277 if large or all or contents:
278 278 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
279 279 return result
280 280
281 281 def overridedebugstate(orig, ui, repo, *pats, **opts):
282 282 large = opts.pop('large', False)
283 283 if large:
284 284 lfcommands.debugdirstate(ui, repo)
285 285 else:
286 286 orig(ui, repo, *pats, **opts)
287 287
288 288 # Override needs to refresh standins so that update's normal merge
289 289 # will go through properly. Then the other update hook (overriding repo.update)
290 290 # will get the new files. Filemerge is also overridden so that the merge
291 291 # will merge standins correctly.
292 292 def overrideupdate(orig, ui, repo, *pats, **opts):
293 293 lfdirstate = lfutil.openlfdirstate(ui, repo)
294 294 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
295 295 False, False)
296 296 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
297 297
298 298 # Need to lock between the standins getting updated and their
299 299 # largefiles getting updated
300 300 wlock = repo.wlock()
301 301 try:
302 302 if opts['check']:
303 303 mod = len(modified) > 0
304 304 for lfile in unsure:
305 305 standin = lfutil.standin(lfile)
306 306 if repo['.'][standin].data().strip() != \
307 307 lfutil.hashfile(repo.wjoin(lfile)):
308 308 mod = True
309 309 else:
310 310 lfdirstate.normal(lfile)
311 311 lfdirstate.write()
312 312 if mod:
313 313 raise util.Abort(_('uncommitted local changes'))
314 314 # XXX handle removed differently
315 315 if not opts['clean']:
316 316 for lfile in unsure + modified + added:
317 317 lfutil.updatestandin(repo, lfutil.standin(lfile))
318 318 finally:
319 319 wlock.release()
320 320 return orig(ui, repo, *pats, **opts)
321 321
322 322 # Before starting the manifest merge, merge.updates will call
323 323 # _checkunknown to check if there are any files in the merged-in
324 324 # changeset that collide with unknown files in the working copy.
325 325 #
326 326 # The largefiles are seen as unknown, so this prevents us from merging
327 327 # in a file 'foo' if we already have a largefile with the same name.
328 328 #
329 329 # The overridden function filters the unknown files by removing any
330 330 # largefiles. This makes the merge proceed and we can then handle this
331 331 # case further in the overridden manifestmerge function below.
332 332 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
333 333 if lfutil.standin(f) in wctx:
334 334 return False
335 335 return origfn(repo, wctx, mctx, f)
336 336
337 337 # The manifest merge handles conflicts on the manifest level. We want
338 338 # to handle changes in largefile-ness of files at this level too.
339 339 #
340 340 # The strategy is to run the original manifestmerge and then process
341 341 # the action list it outputs. There are two cases we need to deal with:
342 342 #
343 343 # 1. Normal file in p1, largefile in p2. Here the largefile is
344 344 # detected via its standin file, which will enter the working copy
345 345 # with a "get" action. It is not "merge" since the standin is all
346 346 # Mercurial is concerned with at this level -- the link to the
347 347 # existing normal file is not relevant here.
348 348 #
349 349 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
350 350 # since the largefile will be present in the working copy and
351 351 # different from the normal file in p2. Mercurial therefore
352 352 # triggers a merge action.
353 353 #
354 354 # In both cases, we prompt the user and emit new actions to either
355 355 # remove the standin (if the normal file was kept) or to remove the
356 356 # normal file and get the standin (if the largefile was kept). The
357 357 # default prompt answer is to use the largefile version since it was
358 358 # presumably changed on purpose.
359 359 #
360 360 # Finally, the merge.applyupdates function will then take care of
361 361 # writing the files into the working copy and lfcommands.updatelfiles
362 362 # will update the largefiles.
363 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
364 actions = origfn(repo, p1, p2, pa, overwrite, partial)
363 def overridemanifestmerge(origfn, repo, p1, p2, pa, branchmerge, force,
364 partial):
365 overwrite = force and not branchmerge
366 actions = origfn(repo, p1, p2, pa, branchmerge, force, partial)
365 367 processed = []
366 368
367 369 for action in actions:
368 370 if overwrite:
369 371 processed.append(action)
370 372 continue
371 373 f, m, args, msg = action
372 374
373 375 choices = (_('&Largefile'), _('&Normal file'))
374 376 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
375 377 # Case 1: normal file in the working copy, largefile in
376 378 # the second parent
377 379 lfile = lfutil.splitstandin(f)
378 380 standin = f
379 381 msg = _('%s has been turned into a largefile\n'
380 382 'use (l)argefile or keep as (n)ormal file?') % lfile
381 383 if repo.ui.promptchoice(msg, choices, 0) == 0:
382 384 processed.append((lfile, "r", None, msg))
383 385 processed.append((standin, "g", (p2.flags(standin),), msg))
384 386 else:
385 387 processed.append((standin, "r", None, msg))
386 388 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
387 389 # Case 2: largefile in the working copy, normal file in
388 390 # the second parent
389 391 standin = lfutil.standin(f)
390 392 lfile = f
391 393 msg = _('%s has been turned into a normal file\n'
392 394 'keep as (l)argefile or use (n)ormal file?') % lfile
393 395 if repo.ui.promptchoice(msg, choices, 0) == 0:
394 396 processed.append((lfile, "r", None, msg))
395 397 else:
396 398 processed.append((standin, "r", None, msg))
397 399 processed.append((lfile, "g", (p2.flags(lfile),), msg))
398 400 else:
399 401 processed.append(action)
400 402
401 403 return processed
402 404
403 405 # Override filemerge to prompt the user about how they wish to merge
404 406 # largefiles. This will handle identical edits, and copy/rename +
405 407 # edit without prompting the user.
406 408 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
407 409 # Use better variable names here. Because this is a wrapper we cannot
408 410 # change the variable names in the function declaration.
409 411 fcdest, fcother, fcancestor = fcd, fco, fca
410 412 if not lfutil.isstandin(orig):
411 413 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
412 414 else:
413 415 if not fcother.cmp(fcdest): # files identical?
414 416 return None
415 417
416 418 # backwards, use working dir parent as ancestor
417 419 if fcancestor == fcother:
418 420 fcancestor = fcdest.parents()[0]
419 421
420 422 if orig != fcother.path():
421 423 repo.ui.status(_('merging %s and %s to %s\n')
422 424 % (lfutil.splitstandin(orig),
423 425 lfutil.splitstandin(fcother.path()),
424 426 lfutil.splitstandin(fcdest.path())))
425 427 else:
426 428 repo.ui.status(_('merging %s\n')
427 429 % lfutil.splitstandin(fcdest.path()))
428 430
429 431 if fcancestor.path() != fcother.path() and fcother.data() == \
430 432 fcancestor.data():
431 433 return 0
432 434 if fcancestor.path() != fcdest.path() and fcdest.data() == \
433 435 fcancestor.data():
434 436 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
435 437 return 0
436 438
437 439 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
438 440 'keep (l)ocal or take (o)ther?') %
439 441 lfutil.splitstandin(orig),
440 442 (_('&Local'), _('&Other')), 0) == 0:
441 443 return 0
442 444 else:
443 445 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
444 446 return 0
445 447
446 448 # Copy first changes the matchers to match standins instead of
447 449 # largefiles. Then it overrides util.copyfile in that function it
448 450 # checks if the destination largefile already exists. It also keeps a
449 451 # list of copied files so that the largefiles can be copied and the
450 452 # dirstate updated.
451 453 def overridecopy(orig, ui, repo, pats, opts, rename=False):
452 454 # doesn't remove largefile on rename
453 455 if len(pats) < 2:
454 456 # this isn't legal, let the original function deal with it
455 457 return orig(ui, repo, pats, opts, rename)
456 458
457 459 def makestandin(relpath):
458 460 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
459 461 return os.path.join(repo.wjoin(lfutil.standin(path)))
460 462
461 463 fullpats = scmutil.expandpats(pats)
462 464 dest = fullpats[-1]
463 465
464 466 if os.path.isdir(dest):
465 467 if not os.path.isdir(makestandin(dest)):
466 468 os.makedirs(makestandin(dest))
467 469 # This could copy both lfiles and normal files in one command,
468 470 # but we don't want to do that. First replace their matcher to
469 471 # only match normal files and run it, then replace it to just
470 472 # match largefiles and run it again.
471 473 nonormalfiles = False
472 474 nolfiles = False
473 475 try:
474 476 try:
475 477 installnormalfilesmatchfn(repo[None].manifest())
476 478 result = orig(ui, repo, pats, opts, rename)
477 479 except util.Abort, e:
478 480 if str(e) != _('no files to copy'):
479 481 raise e
480 482 else:
481 483 nonormalfiles = True
482 484 result = 0
483 485 finally:
484 486 restorematchfn()
485 487
486 488 # The first rename can cause our current working directory to be removed.
487 489 # In that case there is nothing left to copy/rename so just quit.
488 490 try:
489 491 repo.getcwd()
490 492 except OSError:
491 493 return result
492 494
493 495 try:
494 496 try:
495 497 # When we call orig below it creates the standins but we don't add
496 498 # them to the dir state until later so lock during that time.
497 499 wlock = repo.wlock()
498 500
499 501 manifest = repo[None].manifest()
500 502 oldmatch = None # for the closure
501 503 def overridematch(ctx, pats=[], opts={}, globbed=False,
502 504 default='relpath'):
503 505 newpats = []
504 506 # The patterns were previously mangled to add the standin
505 507 # directory; we need to remove that now
506 508 for pat in pats:
507 509 if match_.patkind(pat) is None and lfutil.shortname in pat:
508 510 newpats.append(pat.replace(lfutil.shortname, ''))
509 511 else:
510 512 newpats.append(pat)
511 513 match = oldmatch(ctx, newpats, opts, globbed, default)
512 514 m = copy.copy(match)
513 515 lfile = lambda f: lfutil.standin(f) in manifest
514 516 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
515 517 m._fmap = set(m._files)
516 518 origmatchfn = m.matchfn
517 519 m.matchfn = lambda f: (lfutil.isstandin(f) and
518 520 (f in manifest) and
519 521 origmatchfn(lfutil.splitstandin(f)) or
520 522 None)
521 523 return m
522 524 oldmatch = installmatchfn(overridematch)
523 525 listpats = []
524 526 for pat in pats:
525 527 if match_.patkind(pat) is not None:
526 528 listpats.append(pat)
527 529 else:
528 530 listpats.append(makestandin(pat))
529 531
530 532 try:
531 533 origcopyfile = util.copyfile
532 534 copiedfiles = []
533 535 def overridecopyfile(src, dest):
534 536 if (lfutil.shortname in src and
535 537 dest.startswith(repo.wjoin(lfutil.shortname))):
536 538 destlfile = dest.replace(lfutil.shortname, '')
537 539 if not opts['force'] and os.path.exists(destlfile):
538 540 raise IOError('',
539 541 _('destination largefile already exists'))
540 542 copiedfiles.append((src, dest))
541 543 origcopyfile(src, dest)
542 544
543 545 util.copyfile = overridecopyfile
544 546 result += orig(ui, repo, listpats, opts, rename)
545 547 finally:
546 548 util.copyfile = origcopyfile
547 549
548 550 lfdirstate = lfutil.openlfdirstate(ui, repo)
549 551 for (src, dest) in copiedfiles:
550 552 if (lfutil.shortname in src and
551 553 dest.startswith(repo.wjoin(lfutil.shortname))):
552 554 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
553 555 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
554 556 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
555 557 if not os.path.isdir(destlfiledir):
556 558 os.makedirs(destlfiledir)
557 559 if rename:
558 560 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
559 561 lfdirstate.remove(srclfile)
560 562 else:
561 563 util.copyfile(repo.wjoin(srclfile),
562 564 repo.wjoin(destlfile))
563 565
564 566 lfdirstate.add(destlfile)
565 567 lfdirstate.write()
566 568 except util.Abort, e:
567 569 if str(e) != _('no files to copy'):
568 570 raise e
569 571 else:
570 572 nolfiles = True
571 573 finally:
572 574 restorematchfn()
573 575 wlock.release()
574 576
575 577 if nolfiles and nonormalfiles:
576 578 raise util.Abort(_('no files to copy'))
577 579
578 580 return result
579 581
580 582 # When the user calls revert, we have to be careful to not revert any
581 583 # changes to other largefiles accidentally. This means we have to keep
582 584 # track of the largefiles that are being reverted so we only pull down
583 585 # the necessary largefiles.
584 586 #
585 587 # Standins are only updated (to match the hash of largefiles) before
586 588 # commits. Update the standins then run the original revert, changing
587 589 # the matcher to hit standins instead of largefiles. Based on the
588 590 # resulting standins update the largefiles. Then return the standins
589 591 # to their proper state
590 592 def overriderevert(orig, ui, repo, *pats, **opts):
591 593 # Because we put the standins in a bad state (by updating them)
592 594 # and then return them to a correct state we need to lock to
593 595 # prevent others from changing them in their incorrect state.
594 596 wlock = repo.wlock()
595 597 try:
596 598 lfdirstate = lfutil.openlfdirstate(ui, repo)
597 599 (modified, added, removed, missing, unknown, ignored, clean) = \
598 600 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
599 601 lfdirstate.write()
600 602 for lfile in modified:
601 603 lfutil.updatestandin(repo, lfutil.standin(lfile))
602 604 for lfile in missing:
603 605 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
604 606 os.unlink(repo.wjoin(lfutil.standin(lfile)))
605 607
606 608 try:
607 609 ctx = scmutil.revsingle(repo, opts.get('rev'))
608 610 oldmatch = None # for the closure
609 611 def overridematch(ctx, pats=[], opts={}, globbed=False,
610 612 default='relpath'):
611 613 match = oldmatch(ctx, pats, opts, globbed, default)
612 614 m = copy.copy(match)
613 615 def tostandin(f):
614 616 if lfutil.standin(f) in ctx:
615 617 return lfutil.standin(f)
616 618 elif lfutil.standin(f) in repo[None]:
617 619 return None
618 620 return f
619 621 m._files = [tostandin(f) for f in m._files]
620 622 m._files = [f for f in m._files if f is not None]
621 623 m._fmap = set(m._files)
622 624 origmatchfn = m.matchfn
623 625 def matchfn(f):
624 626 if lfutil.isstandin(f):
625 627 # We need to keep track of what largefiles are being
626 628 # matched so we know which ones to update later --
627 629 # otherwise we accidentally revert changes to other
628 630 # largefiles. This is repo-specific, so duckpunch the
629 631 # repo object to keep the list of largefiles for us
630 632 # later.
631 633 if origmatchfn(lfutil.splitstandin(f)) and \
632 634 (f in repo[None] or f in ctx):
633 635 lfileslist = getattr(repo, '_lfilestoupdate', [])
634 636 lfileslist.append(lfutil.splitstandin(f))
635 637 repo._lfilestoupdate = lfileslist
636 638 return True
637 639 else:
638 640 return False
639 641 return origmatchfn(f)
640 642 m.matchfn = matchfn
641 643 return m
642 644 oldmatch = installmatchfn(overridematch)
643 645 scmutil.match
644 646 matches = overridematch(repo[None], pats, opts)
645 647 orig(ui, repo, *pats, **opts)
646 648 finally:
647 649 restorematchfn()
648 650 lfileslist = getattr(repo, '_lfilestoupdate', [])
649 651 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
650 652 printmessage=False)
651 653
652 654 # empty out the largefiles list so we start fresh next time
653 655 repo._lfilestoupdate = []
654 656 for lfile in modified:
655 657 if lfile in lfileslist:
656 658 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
657 659 in repo['.']:
658 660 lfutil.writestandin(repo, lfutil.standin(lfile),
659 661 repo['.'][lfile].data().strip(),
660 662 'x' in repo['.'][lfile].flags())
661 663 lfdirstate = lfutil.openlfdirstate(ui, repo)
662 664 for lfile in added:
663 665 standin = lfutil.standin(lfile)
664 666 if standin not in ctx and (standin in matches or opts.get('all')):
665 667 if lfile in lfdirstate:
666 668 lfdirstate.drop(lfile)
667 669 util.unlinkpath(repo.wjoin(standin))
668 670 lfdirstate.write()
669 671 finally:
670 672 wlock.release()
671 673
672 674 def hgupdaterepo(orig, repo, node, overwrite):
673 675 if not overwrite:
674 676 # Only call updatelfiles on the standins that have changed to save time
675 677 oldstandins = lfutil.getstandinsstate(repo)
676 678
677 679 result = orig(repo, node, overwrite)
678 680
679 681 filelist = None
680 682 if not overwrite:
681 683 newstandins = lfutil.getstandinsstate(repo)
682 684 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
683 685 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist)
684 686 return result
685 687
686 688 def hgmerge(orig, repo, node, force=None, remind=True):
687 689 # Mark the repo as being in the middle of a merge, so that
688 690 # updatelfiles() will know that it needs to trust the standins in
689 691 # the working copy, not in the standins in the current node
690 692 repo._ismerging = True
691 693 try:
692 694 result = orig(repo, node, force, remind)
693 695 lfcommands.updatelfiles(repo.ui, repo)
694 696 finally:
695 697 repo._ismerging = False
696 698 return result
697 699
698 700 # When we rebase a repository with remotely changed largefiles, we need to
699 701 # take some extra care so that the largefiles are correctly updated in the
700 702 # working copy
701 703 def overridepull(orig, ui, repo, source=None, **opts):
702 704 revsprepull = len(repo)
703 705 if opts.get('rebase', False):
704 706 repo._isrebasing = True
705 707 try:
706 708 if opts.get('update'):
707 709 del opts['update']
708 710 ui.debug('--update and --rebase are not compatible, ignoring '
709 711 'the update flag\n')
710 712 del opts['rebase']
711 713 cmdutil.bailifchanged(repo)
712 714 origpostincoming = commands.postincoming
713 715 def _dummy(*args, **kwargs):
714 716 pass
715 717 commands.postincoming = _dummy
716 718 if not source:
717 719 source = 'default'
718 720 repo.lfpullsource = source
719 721 try:
720 722 result = commands.pull(ui, repo, source, **opts)
721 723 finally:
722 724 commands.postincoming = origpostincoming
723 725 revspostpull = len(repo)
724 726 if revspostpull > revsprepull:
725 727 result = result or rebase.rebase(ui, repo)
726 728 finally:
727 729 repo._isrebasing = False
728 730 else:
729 731 if not source:
730 732 source = 'default'
731 733 repo.lfpullsource = source
732 734 oldheads = lfutil.getcurrentheads(repo)
733 735 result = orig(ui, repo, source, **opts)
734 736 # If we do not have the new largefiles for any new heads we pulled, we
735 737 # will run into a problem later if we try to merge or rebase with one of
736 738 # these heads, so cache the largefiles now directly into the system
737 739 # cache.
738 740 numcached = 0
739 741 heads = lfutil.getcurrentheads(repo)
740 742 newheads = set(heads).difference(set(oldheads))
741 743 if len(newheads) > 0:
742 744 ui.status(_("caching largefiles for %s heads\n" % len(newheads)))
743 745 for head in newheads:
744 746 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
745 747 numcached += len(cached)
746 748 ui.status(_("%d largefiles cached\n") % numcached)
747 749 if opts.get('all_largefiles'):
748 750 revspostpull = len(repo)
749 751 revs = []
750 752 for rev in xrange(revsprepull + 1, revspostpull):
751 753 revs.append(repo[rev].rev())
752 754 lfcommands.downloadlfiles(ui, repo, revs)
753 755 return result
754 756
755 757 def overrideclone(orig, ui, source, dest=None, **opts):
756 758 d = dest
757 759 if d is None:
758 760 d = hg.defaultdest(source)
759 761 if opts.get('all_largefiles') and not hg.islocal(d):
760 762 raise util.Abort(_(
761 763 '--all-largefiles is incompatible with non-local destination %s' %
762 764 d))
763 765
764 766 return orig(ui, source, dest, **opts)
765 767
766 768 def hgclone(orig, ui, opts, *args, **kwargs):
767 769 result = orig(ui, opts, *args, **kwargs)
768 770
769 771 if result is not None:
770 772 sourcerepo, destrepo = result
771 773 repo = destrepo.local()
772 774
773 775 # The .hglf directory must exist for the standin matcher to match
774 776 # anything (which listlfiles uses for each rev), and .hg/largefiles is
775 777 # assumed to exist by the code that caches the downloaded file. These
776 778 # directories exist if clone updated to any rev. (If the repo does not
777 779 # have largefiles, download never gets to the point of needing
778 780 # .hg/largefiles, and the standin matcher won't match anything anyway.)
779 781 if 'largefiles' in repo.requirements:
780 782 if opts.get('noupdate'):
781 783 util.makedirs(repo.wjoin(lfutil.shortname))
782 784 util.makedirs(repo.join(lfutil.longname))
783 785
784 786 # Caching is implicitly limited to 'rev' option, since the dest repo was
785 787 # truncated at that point. The user may expect a download count with
786 788 # this option, so attempt whether or not this is a largefile repo.
787 789 if opts.get('all_largefiles'):
788 790 success, missing = lfcommands.downloadlfiles(ui, repo, None)
789 791
790 792 if missing != 0:
791 793 return None
792 794
793 795 return result
794 796
795 797 def overriderebase(orig, ui, repo, **opts):
796 798 repo._isrebasing = True
797 799 try:
798 800 return orig(ui, repo, **opts)
799 801 finally:
800 802 repo._isrebasing = False
801 803
802 804 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
803 805 prefix=None, mtime=None, subrepos=None):
804 806 # No need to lock because we are only reading history and
805 807 # largefile caches, neither of which are modified.
806 808 lfcommands.cachelfiles(repo.ui, repo, node)
807 809
808 810 if kind not in archival.archivers:
809 811 raise util.Abort(_("unknown archive type '%s'") % kind)
810 812
811 813 ctx = repo[node]
812 814
813 815 if kind == 'files':
814 816 if prefix:
815 817 raise util.Abort(
816 818 _('cannot give prefix when archiving to files'))
817 819 else:
818 820 prefix = archival.tidyprefix(dest, kind, prefix)
819 821
820 822 def write(name, mode, islink, getdata):
821 823 if matchfn and not matchfn(name):
822 824 return
823 825 data = getdata()
824 826 if decode:
825 827 data = repo.wwritedata(name, data)
826 828 archiver.addfile(prefix + name, mode, islink, data)
827 829
828 830 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
829 831
830 832 if repo.ui.configbool("ui", "archivemeta", True):
831 833 def metadata():
832 834 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
833 835 hex(repo.changelog.node(0)), hex(node), ctx.branch())
834 836
835 837 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
836 838 if repo.tagtype(t) == 'global')
837 839 if not tags:
838 840 repo.ui.pushbuffer()
839 841 opts = {'template': '{latesttag}\n{latesttagdistance}',
840 842 'style': '', 'patch': None, 'git': None}
841 843 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
842 844 ltags, dist = repo.ui.popbuffer().split('\n')
843 845 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
844 846 tags += 'latesttagdistance: %s\n' % dist
845 847
846 848 return base + tags
847 849
848 850 write('.hg_archival.txt', 0644, False, metadata)
849 851
850 852 for f in ctx:
851 853 ff = ctx.flags(f)
852 854 getdata = ctx[f].data
853 855 if lfutil.isstandin(f):
854 856 path = lfutil.findfile(repo, getdata().strip())
855 857 if path is None:
856 858 raise util.Abort(
857 859 _('largefile %s not found in repo store or system cache')
858 860 % lfutil.splitstandin(f))
859 861 f = lfutil.splitstandin(f)
860 862
861 863 def getdatafn():
862 864 fd = None
863 865 try:
864 866 fd = open(path, 'rb')
865 867 return fd.read()
866 868 finally:
867 869 if fd:
868 870 fd.close()
869 871
870 872 getdata = getdatafn
871 873 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
872 874
873 875 if subrepos:
874 876 for subpath in sorted(ctx.substate):
875 877 sub = ctx.sub(subpath)
876 878 submatch = match_.narrowmatcher(subpath, matchfn)
877 879 sub.archive(repo.ui, archiver, prefix, submatch)
878 880
879 881 archiver.done()
880 882
881 883 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
882 884 repo._get(repo._state + ('hg',))
883 885 rev = repo._state[1]
884 886 ctx = repo._repo[rev]
885 887
886 888 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
887 889
888 890 def write(name, mode, islink, getdata):
889 891 # At this point, the standin has been replaced with the largefile name,
890 892 # so the normal matcher works here without the lfutil variants.
891 893 if match and not match(f):
892 894 return
893 895 data = getdata()
894 896
895 897 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
896 898
897 899 for f in ctx:
898 900 ff = ctx.flags(f)
899 901 getdata = ctx[f].data
900 902 if lfutil.isstandin(f):
901 903 path = lfutil.findfile(repo._repo, getdata().strip())
902 904 if path is None:
903 905 raise util.Abort(
904 906 _('largefile %s not found in repo store or system cache')
905 907 % lfutil.splitstandin(f))
906 908 f = lfutil.splitstandin(f)
907 909
908 910 def getdatafn():
909 911 fd = None
910 912 try:
911 913 fd = open(os.path.join(prefix, path), 'rb')
912 914 return fd.read()
913 915 finally:
914 916 if fd:
915 917 fd.close()
916 918
917 919 getdata = getdatafn
918 920
919 921 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
920 922
921 923 for subpath in sorted(ctx.substate):
922 924 sub = ctx.sub(subpath)
923 925 submatch = match_.narrowmatcher(subpath, match)
924 926 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
925 927 submatch)
926 928
927 929 # If a largefile is modified, the change is not reflected in its
928 930 # standin until a commit. cmdutil.bailifchanged() raises an exception
929 931 # if the repo has uncommitted changes. Wrap it to also check if
930 932 # largefiles were changed. This is used by bisect and backout.
931 933 def overridebailifchanged(orig, repo):
932 934 orig(repo)
933 935 repo.lfstatus = True
934 936 modified, added, removed, deleted = repo.status()[:4]
935 937 repo.lfstatus = False
936 938 if modified or added or removed or deleted:
937 939 raise util.Abort(_('outstanding uncommitted changes'))
938 940
939 941 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
940 942 def overridefetch(orig, ui, repo, *pats, **opts):
941 943 repo.lfstatus = True
942 944 modified, added, removed, deleted = repo.status()[:4]
943 945 repo.lfstatus = False
944 946 if modified or added or removed or deleted:
945 947 raise util.Abort(_('outstanding uncommitted changes'))
946 948 return orig(ui, repo, *pats, **opts)
947 949
948 950 def overrideforget(orig, ui, repo, *pats, **opts):
949 951 installnormalfilesmatchfn(repo[None].manifest())
950 952 result = orig(ui, repo, *pats, **opts)
951 953 restorematchfn()
952 954 m = scmutil.match(repo[None], pats, opts)
953 955
954 956 try:
955 957 repo.lfstatus = True
956 958 s = repo.status(match=m, clean=True)
957 959 finally:
958 960 repo.lfstatus = False
959 961 forget = sorted(s[0] + s[1] + s[3] + s[6])
960 962 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
961 963
962 964 for f in forget:
963 965 if lfutil.standin(f) not in repo.dirstate and not \
964 966 os.path.isdir(m.rel(lfutil.standin(f))):
965 967 ui.warn(_('not removing %s: file is already untracked\n')
966 968 % m.rel(f))
967 969 result = 1
968 970
969 971 for f in forget:
970 972 if ui.verbose or not m.exact(f):
971 973 ui.status(_('removing %s\n') % m.rel(f))
972 974
973 975 # Need to lock because standin files are deleted then removed from the
974 976 # repository and we could race in-between.
975 977 wlock = repo.wlock()
976 978 try:
977 979 lfdirstate = lfutil.openlfdirstate(ui, repo)
978 980 for f in forget:
979 981 if lfdirstate[f] == 'a':
980 982 lfdirstate.drop(f)
981 983 else:
982 984 lfdirstate.remove(f)
983 985 lfdirstate.write()
984 986 standins = [lfutil.standin(f) for f in forget]
985 987 for f in standins:
986 988 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
987 989 repo[None].forget(standins)
988 990 finally:
989 991 wlock.release()
990 992
991 993 return result
992 994
993 995 def getoutgoinglfiles(ui, repo, dest=None, **opts):
994 996 dest = ui.expandpath(dest or 'default-push', dest or 'default')
995 997 dest, branches = hg.parseurl(dest, opts.get('branch'))
996 998 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
997 999 if revs:
998 1000 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
999 1001
1000 1002 try:
1001 1003 remote = hg.peer(repo, opts, dest)
1002 1004 except error.RepoError:
1003 1005 return None
1004 1006 outgoing = discovery.findcommonoutgoing(repo, remote.peer(), force=False)
1005 1007 if not outgoing.missing:
1006 1008 return outgoing.missing
1007 1009 o = repo.changelog.nodesbetween(outgoing.missing, revs)[0]
1008 1010 if opts.get('newest_first'):
1009 1011 o.reverse()
1010 1012
1011 1013 toupload = set()
1012 1014 for n in o:
1013 1015 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
1014 1016 ctx = repo[n]
1015 1017 files = set(ctx.files())
1016 1018 if len(parents) == 2:
1017 1019 mc = ctx.manifest()
1018 1020 mp1 = ctx.parents()[0].manifest()
1019 1021 mp2 = ctx.parents()[1].manifest()
1020 1022 for f in mp1:
1021 1023 if f not in mc:
1022 1024 files.add(f)
1023 1025 for f in mp2:
1024 1026 if f not in mc:
1025 1027 files.add(f)
1026 1028 for f in mc:
1027 1029 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
1028 1030 files.add(f)
1029 1031 toupload = toupload.union(
1030 1032 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
1031 1033 return sorted(toupload)
1032 1034
1033 1035 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
1034 1036 result = orig(ui, repo, dest, **opts)
1035 1037
1036 1038 if opts.pop('large', None):
1037 1039 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
1038 1040 if toupload is None:
1039 1041 ui.status(_('largefiles: No remote repo\n'))
1040 1042 elif not toupload:
1041 1043 ui.status(_('largefiles: no files to upload\n'))
1042 1044 else:
1043 1045 ui.status(_('largefiles to upload:\n'))
1044 1046 for file in toupload:
1045 1047 ui.status(lfutil.splitstandin(file) + '\n')
1046 1048 ui.status('\n')
1047 1049
1048 1050 return result
1049 1051
1050 1052 def overridesummary(orig, ui, repo, *pats, **opts):
1051 1053 try:
1052 1054 repo.lfstatus = True
1053 1055 orig(ui, repo, *pats, **opts)
1054 1056 finally:
1055 1057 repo.lfstatus = False
1056 1058
1057 1059 if opts.pop('large', None):
1058 1060 toupload = getoutgoinglfiles(ui, repo, None, **opts)
1059 1061 if toupload is None:
1060 1062 # i18n: column positioning for "hg summary"
1061 1063 ui.status(_('largefiles: (no remote repo)\n'))
1062 1064 elif not toupload:
1063 1065 # i18n: column positioning for "hg summary"
1064 1066 ui.status(_('largefiles: (no files to upload)\n'))
1065 1067 else:
1066 1068 # i18n: column positioning for "hg summary"
1067 1069 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1068 1070
1069 1071 def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None,
1070 1072 similarity=None):
1071 1073 if not lfutil.islfilesrepo(repo):
1072 1074 return orig(repo, pats, opts, dry_run, similarity)
1073 1075 # Get the list of missing largefiles so we can remove them
1074 1076 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1075 1077 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1076 1078 False, False)
1077 1079 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1078 1080
1079 1081 # Call into the normal remove code, but the removing of the standin, we want
1080 1082 # to have handled by original addremove. Monkey patching here makes sure
1081 1083 # we don't remove the standin in the largefiles code, preventing a very
1082 1084 # confused state later.
1083 1085 if missing:
1084 1086 m = [repo.wjoin(f) for f in missing]
1085 1087 repo._isaddremove = True
1086 1088 removelargefiles(repo.ui, repo, *m, **opts)
1087 1089 repo._isaddremove = False
1088 1090 # Call into the normal add code, and any files that *should* be added as
1089 1091 # largefiles will be
1090 1092 addlargefiles(repo.ui, repo, *pats, **opts)
1091 1093 # Now that we've handled largefiles, hand off to the original addremove
1092 1094 # function to take care of the rest. Make sure it doesn't do anything with
1093 1095 # largefiles by installing a matcher that will ignore them.
1094 1096 installnormalfilesmatchfn(repo[None].manifest())
1095 1097 result = orig(repo, pats, opts, dry_run, similarity)
1096 1098 restorematchfn()
1097 1099 return result
1098 1100
1099 1101 # Calling purge with --all will cause the largefiles to be deleted.
1100 1102 # Override repo.status to prevent this from happening.
1101 1103 def overridepurge(orig, ui, repo, *dirs, **opts):
1102 1104 # XXX large file status is buggy when used on repo proxy.
1103 1105 # XXX this needs to be investigate.
1104 1106 repo = repo.unfiltered()
1105 1107 oldstatus = repo.status
1106 1108 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1107 1109 clean=False, unknown=False, listsubrepos=False):
1108 1110 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1109 1111 listsubrepos)
1110 1112 lfdirstate = lfutil.openlfdirstate(ui, repo)
1111 1113 modified, added, removed, deleted, unknown, ignored, clean = r
1112 1114 unknown = [f for f in unknown if lfdirstate[f] == '?']
1113 1115 ignored = [f for f in ignored if lfdirstate[f] == '?']
1114 1116 return modified, added, removed, deleted, unknown, ignored, clean
1115 1117 repo.status = overridestatus
1116 1118 orig(ui, repo, *dirs, **opts)
1117 1119 repo.status = oldstatus
1118 1120
1119 1121 def overriderollback(orig, ui, repo, **opts):
1120 1122 result = orig(ui, repo, **opts)
1121 1123 merge.update(repo, node=None, branchmerge=False, force=True,
1122 1124 partial=lfutil.isstandin)
1123 1125 wlock = repo.wlock()
1124 1126 try:
1125 1127 lfdirstate = lfutil.openlfdirstate(ui, repo)
1126 1128 lfiles = lfutil.listlfiles(repo)
1127 1129 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1128 1130 for file in lfiles:
1129 1131 if file in oldlfiles:
1130 1132 lfdirstate.normallookup(file)
1131 1133 else:
1132 1134 lfdirstate.add(file)
1133 1135 lfdirstate.write()
1134 1136 finally:
1135 1137 wlock.release()
1136 1138 return result
1137 1139
1138 1140 def overridetransplant(orig, ui, repo, *revs, **opts):
1139 1141 try:
1140 1142 oldstandins = lfutil.getstandinsstate(repo)
1141 1143 repo._istransplanting = True
1142 1144 result = orig(ui, repo, *revs, **opts)
1143 1145 newstandins = lfutil.getstandinsstate(repo)
1144 1146 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1145 1147 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1146 1148 printmessage=True)
1147 1149 finally:
1148 1150 repo._istransplanting = False
1149 1151 return result
1150 1152
1151 1153 def overridecat(orig, ui, repo, file1, *pats, **opts):
1152 1154 ctx = scmutil.revsingle(repo, opts.get('rev'))
1153 1155 err = 1
1154 1156 notbad = set()
1155 1157 m = scmutil.match(ctx, (file1,) + pats, opts)
1156 1158 origmatchfn = m.matchfn
1157 1159 def lfmatchfn(f):
1158 1160 lf = lfutil.splitstandin(f)
1159 1161 if lf is None:
1160 1162 return origmatchfn(f)
1161 1163 notbad.add(lf)
1162 1164 return origmatchfn(lf)
1163 1165 m.matchfn = lfmatchfn
1164 1166 m.bad = lambda f, msg: f not in notbad
1165 1167 for f in ctx.walk(m):
1166 1168 lf = lfutil.splitstandin(f)
1167 1169 if lf is None:
1168 1170 err = orig(ui, repo, f, **opts)
1169 1171 else:
1170 1172 err = lfcommands.catlfile(repo, lf, ctx.rev(), opts.get('output'))
1171 1173 return err
1172 1174
1173 1175 def mercurialsinkbefore(orig, sink):
1174 1176 sink.repo._isconverting = True
1175 1177 orig(sink)
1176 1178
1177 1179 def mercurialsinkafter(orig, sink):
1178 1180 sink.repo._isconverting = False
1179 1181 orig(sink)
@@ -1,641 +1,642 b''
1 1 # merge.py - directory-level update/merge handling for Mercurial
2 2 #
3 3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from node import nullid, nullrev, hex, bin
9 9 from i18n import _
10 10 import error, util, filemerge, copies, subrepo
11 11 import errno, os, shutil
12 12
13 13 class mergestate(object):
14 14 '''track 3-way merge state of individual files'''
15 15 def __init__(self, repo):
16 16 self._repo = repo
17 17 self._dirty = False
18 18 self._read()
19 19 def reset(self, node=None):
20 20 self._state = {}
21 21 if node:
22 22 self._local = node
23 23 shutil.rmtree(self._repo.join("merge"), True)
24 24 self._dirty = False
25 25 def _read(self):
26 26 self._state = {}
27 27 try:
28 28 f = self._repo.opener("merge/state")
29 29 for i, l in enumerate(f):
30 30 if i == 0:
31 31 self._local = bin(l[:-1])
32 32 else:
33 33 bits = l[:-1].split("\0")
34 34 self._state[bits[0]] = bits[1:]
35 35 f.close()
36 36 except IOError, err:
37 37 if err.errno != errno.ENOENT:
38 38 raise
39 39 self._dirty = False
40 40 def commit(self):
41 41 if self._dirty:
42 42 f = self._repo.opener("merge/state", "w")
43 43 f.write(hex(self._local) + "\n")
44 44 for d, v in self._state.iteritems():
45 45 f.write("\0".join([d] + v) + "\n")
46 46 f.close()
47 47 self._dirty = False
48 48 def add(self, fcl, fco, fca, fd):
49 49 hash = util.sha1(fcl.path()).hexdigest()
50 50 self._repo.opener.write("merge/" + hash, fcl.data())
51 51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
52 52 hex(fca.filenode()), fco.path(), fcl.flags()]
53 53 self._dirty = True
54 54 def __contains__(self, dfile):
55 55 return dfile in self._state
56 56 def __getitem__(self, dfile):
57 57 return self._state[dfile][0]
58 58 def __iter__(self):
59 59 l = self._state.keys()
60 60 l.sort()
61 61 for f in l:
62 62 yield f
63 63 def mark(self, dfile, state):
64 64 self._state[dfile][0] = state
65 65 self._dirty = True
66 66 def resolve(self, dfile, wctx, octx):
67 67 if self[dfile] == 'r':
68 68 return 0
69 69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
70 70 fcd = wctx[dfile]
71 71 fco = octx[ofile]
72 72 fca = self._repo.filectx(afile, fileid=anode)
73 73 # "premerge" x flags
74 74 flo = fco.flags()
75 75 fla = fca.flags()
76 76 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
77 77 if fca.node() == nullid:
78 78 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
79 79 afile)
80 80 elif flags == fla:
81 81 flags = flo
82 82 # restore local
83 83 f = self._repo.opener("merge/" + hash)
84 84 self._repo.wwrite(dfile, f.read(), flags)
85 85 f.close()
86 86 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
87 87 if r is None:
88 88 # no real conflict
89 89 del self._state[dfile]
90 90 elif not r:
91 91 self.mark(dfile, 'r')
92 92 return r
93 93
94 94 def _checkunknownfile(repo, wctx, mctx, f):
95 95 return (not repo.dirstate._ignore(f)
96 96 and os.path.isfile(repo.wjoin(f))
97 97 and repo.dirstate.normalize(f) not in repo.dirstate
98 98 and mctx[f].cmp(wctx[f]))
99 99
100 100 def _checkunknown(repo, wctx, mctx):
101 101 "check for collisions between unknown files and files in mctx"
102 102
103 103 error = False
104 104 for f in mctx:
105 105 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
106 106 error = True
107 107 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
108 108 if error:
109 109 raise util.Abort(_("untracked files in working directory differ "
110 110 "from files in requested revision"))
111 111
112 112 def _remains(f, m, ma, workingctx=False):
113 113 """check whether specified file remains after merge.
114 114
115 115 It is assumed that specified file is not contained in the manifest
116 116 of the other context.
117 117 """
118 118 if f in ma:
119 119 n = m[f]
120 120 if n != ma[f]:
121 121 return True # because it is changed locally
122 122 # even though it doesn't remain, if "remote deleted" is
123 123 # chosen in manifestmerge()
124 124 elif workingctx and n[20:] == "a":
125 125 return True # because it is added locally (linear merge specific)
126 126 else:
127 127 return False # because it is removed remotely
128 128 else:
129 129 return True # because it is added locally
130 130
131 131 def _checkcollision(mctx, extractxs):
132 132 "check for case folding collisions in the destination context"
133 133 folded = {}
134 134 for fn in mctx:
135 135 fold = util.normcase(fn)
136 136 if fold in folded:
137 137 raise util.Abort(_("case-folding collision between %s and %s")
138 138 % (fn, folded[fold]))
139 139 folded[fold] = fn
140 140
141 141 if extractxs:
142 142 wctx, actx = extractxs
143 143 # class to delay looking up copy mapping
144 144 class pathcopies(object):
145 145 @util.propertycache
146 146 def map(self):
147 147 # {dst@mctx: src@wctx} copy mapping
148 148 return copies.pathcopies(wctx, mctx)
149 149 pc = pathcopies()
150 150
151 151 for fn in wctx:
152 152 fold = util.normcase(fn)
153 153 mfn = folded.get(fold, None)
154 154 if (mfn and mfn != fn and pc.map.get(mfn) != fn and
155 155 _remains(fn, wctx.manifest(), actx.manifest(), True) and
156 156 _remains(mfn, mctx.manifest(), actx.manifest())):
157 157 raise util.Abort(_("case-folding collision between %s and %s")
158 158 % (mfn, fn))
159 159
160 160 def _forgetremoved(wctx, mctx, branchmerge):
161 161 """
162 162 Forget removed files
163 163
164 164 If we're jumping between revisions (as opposed to merging), and if
165 165 neither the working directory nor the target rev has the file,
166 166 then we need to remove it from the dirstate, to prevent the
167 167 dirstate from listing the file when it is no longer in the
168 168 manifest.
169 169
170 170 If we're merging, and the other revision has removed a file
171 171 that is not present in the working directory, we need to mark it
172 172 as removed.
173 173 """
174 174
175 175 actions = []
176 176 state = branchmerge and 'r' or 'f'
177 177 for f in wctx.deleted():
178 178 if f not in mctx:
179 179 actions.append((f, state, None, "forget deleted"))
180 180
181 181 if not branchmerge:
182 182 for f in wctx.removed():
183 183 if f not in mctx:
184 184 actions.append((f, "f", None, "forget removed"))
185 185
186 186 return actions
187 187
188 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
188 def manifestmerge(repo, p1, p2, pa, branchmerge, force, partial):
189 189 """
190 190 Merge p1 and p2 with ancestor pa and generate merge action list
191 191
192 overwrite = whether we clobber working files
192 branchmerge and force are as passed in to update
193 193 partial = function to filter file lists
194 194 """
195 195
196 overwrite = force and not branchmerge
196 197 actions, copy, movewithdir = [], {}, {}
197 198
198 199 if overwrite:
199 200 pa = p1
200 201 elif pa == p2: # backwards
201 202 pa = p1.p1()
202 203 elif pa and repo.ui.configbool("merge", "followcopies", True):
203 204 ret = copies.mergecopies(repo, p1, p2, pa)
204 205 copy, movewithdir, diverge, renamedelete = ret
205 206 for of, fl in diverge.iteritems():
206 207 actions.append((of, "dr", (fl,), "divergent renames"))
207 208 for of, fl in renamedelete.iteritems():
208 209 actions.append((of, "rd", (fl,), "rename and delete"))
209 210
210 211 repo.ui.note(_("resolving manifests\n"))
211 repo.ui.debug(" overwrite: %s, partial: %s\n"
212 % (bool(overwrite), bool(partial)))
212 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
213 % (bool(branchmerge), bool(force), bool(partial)))
213 214 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2))
214 215
215 216 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
216 217 copied = set(copy.values())
217 218 copied.update(movewithdir.values())
218 219
219 220 if '.hgsubstate' in m1:
220 221 # check whether sub state is modified
221 222 for s in sorted(p1.substate):
222 223 if p1.sub(s).dirty():
223 224 m1['.hgsubstate'] += "+"
224 225 break
225 226
226 227 prompts = []
227 228 # Compare manifests
228 229 for f, n in m1.iteritems():
229 230 if partial and not partial(f):
230 231 continue
231 232 if f in m2:
232 233 n2 = m2[f]
233 234 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
234 235 nol = 'l' not in fl1 + fl2 + fla
235 236 a = ma.get(f, nullid)
236 237 if n == n2 and fl1 == fl2:
237 238 pass # same - keep local
238 239 elif n2 == a and fl2 == fla:
239 240 pass # remote unchanged - keep local
240 241 elif n == a and fl1 == fla: # local unchanged - use remote
241 242 if n == n2: # optimization: keep local content
242 243 actions.append((f, "e", (fl2,), "update permissions"))
243 244 else:
244 245 actions.append((f, "g", (fl2,), "remote is newer"))
245 246 elif nol and n2 == a: # remote only changed 'x'
246 247 actions.append((f, "e", (fl2,), "update permissions"))
247 248 elif nol and n == a: # local only changed 'x'
248 249 actions.append((f, "g", (fl1,), "remote is newer"))
249 250 else: # both changed something
250 251 actions.append((f, "m", (f, f, False), "versions differ"))
251 252 elif f in copied: # files we'll deal with on m2 side
252 253 pass
253 254 elif f in movewithdir: # directory rename
254 255 f2 = movewithdir[f]
255 256 actions.append((f, "d", (None, f2, m1.flags(f)),
256 257 "remote renamed directory to " + f2))
257 258 elif f in copy:
258 259 f2 = copy[f]
259 260 actions.append((f, "m", (f2, f, False),
260 261 "local copied/moved to " + f2))
261 262 elif f in ma: # clean, a different, no remote
262 263 if n != ma[f]:
263 264 prompts.append((f, "cd")) # prompt changed/deleted
264 265 elif n[20:] == "a": # added, no remote
265 266 actions.append((f, "f", None, "remote deleted"))
266 267 else:
267 268 actions.append((f, "r", None, "other deleted"))
268 269
269 270 for f, n in m2.iteritems():
270 271 if partial and not partial(f):
271 272 continue
272 273 if f in m1 or f in copied: # files already visited
273 274 continue
274 275 if f in movewithdir:
275 276 f2 = movewithdir[f]
276 277 actions.append((None, "d", (f, f2, m2.flags(f)),
277 278 "local renamed directory to " + f2))
278 279 elif f in copy:
279 280 f2 = copy[f]
280 281 if f2 in m2:
281 282 actions.append((f2, "m", (f, f, False),
282 283 "remote copied to " + f))
283 284 else:
284 285 actions.append((f2, "m", (f, f, True),
285 286 "remote moved to " + f))
286 287 elif f not in ma:
287 288 if (not overwrite
288 289 and _checkunknownfile(repo, p1, p2, f)):
289 290 actions.append((f, "m", (f, f, False),
290 291 "remote differs from untracked local"))
291 292 else:
292 293 actions.append((f, "g", (m2.flags(f),), "remote created"))
293 294 elif n != ma[f]:
294 295 prompts.append((f, "dc")) # prompt deleted/changed
295 296
296 297 for f, m in sorted(prompts):
297 298 if m == "cd":
298 299 if repo.ui.promptchoice(
299 300 _("local changed %s which remote deleted\n"
300 301 "use (c)hanged version or (d)elete?") % f,
301 302 (_("&Changed"), _("&Delete")), 0):
302 303 actions.append((f, "r", None, "prompt delete"))
303 304 else:
304 305 actions.append((f, "a", None, "prompt keep"))
305 306 elif m == "dc":
306 307 if repo.ui.promptchoice(
307 308 _("remote changed %s which local deleted\n"
308 309 "use (c)hanged version or leave (d)eleted?") % f,
309 310 (_("&Changed"), _("&Deleted")), 0) == 0:
310 311 actions.append((f, "g", (m2.flags(f),), "prompt recreating"))
311 312 else: assert False, m
312 313 return actions
313 314
314 315 def actionkey(a):
315 316 return a[1] == "r" and -1 or 0, a
316 317
317 318 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
318 319 """apply the merge action list to the working directory
319 320
320 321 wctx is the working copy context
321 322 mctx is the context to be merged into the working copy
322 323 actx is the context of the common ancestor
323 324
324 325 Return a tuple of counts (updated, merged, removed, unresolved) that
325 326 describes how many files were affected by the update.
326 327 """
327 328
328 329 updated, merged, removed, unresolved = 0, 0, 0, 0
329 330 ms = mergestate(repo)
330 331 ms.reset(wctx.p1().node())
331 332 moves = []
332 333 actions.sort(key=actionkey)
333 334
334 335 # prescan for merges
335 336 for a in actions:
336 337 f, m, args, msg = a
337 338 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
338 339 if m == "m": # merge
339 340 f2, fd, move = args
340 341 if fd == '.hgsubstate': # merged internally
341 342 continue
342 343 repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd))
343 344 fcl = wctx[f]
344 345 fco = mctx[f2]
345 346 if mctx == actx: # backwards, use working dir parent as ancestor
346 347 if fcl.parents():
347 348 fca = fcl.p1()
348 349 else:
349 350 fca = repo.filectx(f, fileid=nullrev)
350 351 else:
351 352 fca = fcl.ancestor(fco, actx)
352 353 if not fca:
353 354 fca = repo.filectx(f, fileid=nullrev)
354 355 ms.add(fcl, fco, fca, fd)
355 356 if f != fd and move:
356 357 moves.append(f)
357 358
358 359 audit = repo.wopener.audit
359 360
360 361 # remove renamed files after safely stored
361 362 for f in moves:
362 363 if os.path.lexists(repo.wjoin(f)):
363 364 repo.ui.debug("removing %s\n" % f)
364 365 audit(f)
365 366 util.unlinkpath(repo.wjoin(f))
366 367
367 368 numupdates = len(actions)
368 369 for i, a in enumerate(actions):
369 370 f, m, args, msg = a
370 371 repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
371 372 unit=_('files'))
372 373 if m == "r": # remove
373 374 repo.ui.note(_("removing %s\n") % f)
374 375 audit(f)
375 376 if f == '.hgsubstate': # subrepo states need updating
376 377 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
377 378 try:
378 379 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
379 380 except OSError, inst:
380 381 repo.ui.warn(_("update failed to remove %s: %s!\n") %
381 382 (f, inst.strerror))
382 383 removed += 1
383 384 elif m == "m": # merge
384 385 if fd == '.hgsubstate': # subrepo states need updating
385 386 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
386 387 overwrite)
387 388 continue
388 389 f2, fd, move = args
389 390 audit(fd)
390 391 r = ms.resolve(fd, wctx, mctx)
391 392 if r is not None and r > 0:
392 393 unresolved += 1
393 394 else:
394 395 if r is None:
395 396 updated += 1
396 397 else:
397 398 merged += 1
398 399 elif m == "g": # get
399 400 flags, = args
400 401 repo.ui.note(_("getting %s\n") % f)
401 402 repo.wwrite(f, mctx.filectx(f).data(), flags)
402 403 updated += 1
403 404 if f == '.hgsubstate': # subrepo states need updating
404 405 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
405 406 elif m == "d": # directory rename
406 407 f2, fd, flags = args
407 408 if f:
408 409 repo.ui.note(_("moving %s to %s\n") % (f, fd))
409 410 audit(f)
410 411 repo.wwrite(fd, wctx.filectx(f).data(), flags)
411 412 util.unlinkpath(repo.wjoin(f))
412 413 if f2:
413 414 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
414 415 repo.wwrite(fd, mctx.filectx(f2).data(), flags)
415 416 updated += 1
416 417 elif m == "dr": # divergent renames
417 418 fl, = args
418 419 repo.ui.warn(_("note: possible conflict - %s was renamed "
419 420 "multiple times to:\n") % f)
420 421 for nf in fl:
421 422 repo.ui.warn(" %s\n" % nf)
422 423 elif m == "rd": # rename and delete
423 424 fl, = args
424 425 repo.ui.warn(_("note: possible conflict - %s was deleted "
425 426 "and renamed to:\n") % f)
426 427 for nf in fl:
427 428 repo.ui.warn(" %s\n" % nf)
428 429 elif m == "e": # exec
429 430 flags, = args
430 431 audit(f)
431 432 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
432 433 updated += 1
433 434 ms.commit()
434 435 repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files'))
435 436
436 437 return updated, merged, removed, unresolved
437 438
438 439 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
439 440 "Calculate the actions needed to merge mctx into tctx"
440 441 actions = []
441 442 folding = not util.checkcase(repo.path)
442 443 if folding:
443 444 # collision check is not needed for clean update
444 445 if (not branchmerge and
445 446 (force or not tctx.dirty(missing=True, branch=False))):
446 447 _checkcollision(mctx, None)
447 448 else:
448 449 _checkcollision(mctx, (tctx, ancestor))
449 450 if not force:
450 451 _checkunknown(repo, tctx, mctx)
451 452 if tctx.rev() is None:
452 453 actions += _forgetremoved(tctx, mctx, branchmerge)
453 454 actions += manifestmerge(repo, tctx, mctx,
454 455 ancestor,
455 force and not branchmerge,
456 branchmerge, force,
456 457 partial)
457 458 return actions
458 459
459 460 def recordupdates(repo, actions, branchmerge):
460 461 "record merge actions to the dirstate"
461 462
462 463 for a in actions:
463 464 f, m, args, msg = a
464 465 if m == "r": # remove
465 466 if branchmerge:
466 467 repo.dirstate.remove(f)
467 468 else:
468 469 repo.dirstate.drop(f)
469 470 elif m == "a": # re-add
470 471 if not branchmerge:
471 472 repo.dirstate.add(f)
472 473 elif m == "f": # forget
473 474 repo.dirstate.drop(f)
474 475 elif m == "e": # exec change
475 476 repo.dirstate.normallookup(f)
476 477 elif m == "g": # get
477 478 if branchmerge:
478 479 repo.dirstate.otherparent(f)
479 480 else:
480 481 repo.dirstate.normal(f)
481 482 elif m == "m": # merge
482 483 f2, fd, move = args
483 484 if branchmerge:
484 485 # We've done a branch merge, mark this file as merged
485 486 # so that we properly record the merger later
486 487 repo.dirstate.merge(fd)
487 488 if f != f2: # copy/rename
488 489 if move:
489 490 repo.dirstate.remove(f)
490 491 if f != fd:
491 492 repo.dirstate.copy(f, fd)
492 493 else:
493 494 repo.dirstate.copy(f2, fd)
494 495 else:
495 496 # We've update-merged a locally modified file, so
496 497 # we set the dirstate to emulate a normal checkout
497 498 # of that file some time in the past. Thus our
498 499 # merge will appear as a normal local file
499 500 # modification.
500 501 if f2 == fd: # file not locally copied/moved
501 502 repo.dirstate.normallookup(fd)
502 503 if move:
503 504 repo.dirstate.drop(f)
504 505 elif m == "d": # directory rename
505 506 f2, fd, flag = args
506 507 if not f2 and f not in repo.dirstate:
507 508 # untracked file moved
508 509 continue
509 510 if branchmerge:
510 511 repo.dirstate.add(fd)
511 512 if f:
512 513 repo.dirstate.remove(f)
513 514 repo.dirstate.copy(f, fd)
514 515 if f2:
515 516 repo.dirstate.copy(f2, fd)
516 517 else:
517 518 repo.dirstate.normal(fd)
518 519 if f:
519 520 repo.dirstate.drop(f)
520 521
521 522 def update(repo, node, branchmerge, force, partial, ancestor=None,
522 523 mergeancestor=False):
523 524 """
524 525 Perform a merge between the working directory and the given node
525 526
526 527 node = the node to update to, or None if unspecified
527 528 branchmerge = whether to merge between branches
528 529 force = whether to force branch merging or file overwriting
529 530 partial = a function to filter file lists (dirstate not updated)
530 531 mergeancestor = if false, merging with an ancestor (fast-forward)
531 532 is only allowed between different named branches. This flag
532 533 is used by rebase extension as a temporary fix and should be
533 534 avoided in general.
534 535
535 536 The table below shows all the behaviors of the update command
536 537 given the -c and -C or no options, whether the working directory
537 538 is dirty, whether a revision is specified, and the relationship of
538 539 the parent rev to the target rev (linear, on the same named
539 540 branch, or on another named branch).
540 541
541 542 This logic is tested by test-update-branches.t.
542 543
543 544 -c -C dirty rev | linear same cross
544 545 n n n n | ok (1) x
545 546 n n n y | ok ok ok
546 547 n n y * | merge (2) (2)
547 548 n y * * | --- discard ---
548 549 y n y * | --- (3) ---
549 550 y n n * | --- ok ---
550 551 y y * * | --- (4) ---
551 552
552 553 x = can't happen
553 554 * = don't-care
554 555 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
555 556 2 = abort: crosses branches (use 'hg merge' to merge or
556 557 use 'hg update -C' to discard changes)
557 558 3 = abort: uncommitted local changes
558 559 4 = incompatible options (checked in commands.py)
559 560
560 561 Return the same tuple as applyupdates().
561 562 """
562 563
563 564 onode = node
564 565 wlock = repo.wlock()
565 566 try:
566 567 wc = repo[None]
567 568 if node is None:
568 569 # tip of current branch
569 570 try:
570 571 node = repo.branchtip(wc.branch())
571 572 except error.RepoLookupError:
572 573 if wc.branch() == "default": # no default branch!
573 574 node = repo.lookup("tip") # update to tip
574 575 else:
575 576 raise util.Abort(_("branch %s not found") % wc.branch())
576 577 overwrite = force and not branchmerge
577 578 pl = wc.parents()
578 579 p1, p2 = pl[0], repo[node]
579 580 if ancestor:
580 581 pa = repo[ancestor]
581 582 else:
582 583 pa = p1.ancestor(p2)
583 584
584 585 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
585 586
586 587 ### check phase
587 588 if not overwrite and len(pl) > 1:
588 589 raise util.Abort(_("outstanding uncommitted merges"))
589 590 if branchmerge:
590 591 if pa == p2:
591 592 raise util.Abort(_("merging with a working directory ancestor"
592 593 " has no effect"))
593 594 elif pa == p1:
594 595 if not mergeancestor and p1.branch() == p2.branch():
595 596 raise util.Abort(_("nothing to merge"),
596 597 hint=_("use 'hg update' "
597 598 "or check 'hg heads'"))
598 599 if not force and (wc.files() or wc.deleted()):
599 600 raise util.Abort(_("outstanding uncommitted changes"),
600 601 hint=_("use 'hg status' to list changes"))
601 602 for s in sorted(wc.substate):
602 603 if wc.sub(s).dirty():
603 604 raise util.Abort(_("outstanding uncommitted changes in "
604 605 "subrepository '%s'") % s)
605 606
606 607 elif not overwrite:
607 608 if pa == p1 or pa == p2: # linear
608 609 pass # all good
609 610 elif wc.dirty(missing=True):
610 611 raise util.Abort(_("crosses branches (merge branches or use"
611 612 " --clean to discard changes)"))
612 613 elif onode is None:
613 614 raise util.Abort(_("crosses branches (merge branches or update"
614 615 " --check to force update)"))
615 616 else:
616 617 # Allow jumping branches if clean and specific rev given
617 618 pa = p1
618 619
619 620 ### calculate phase
620 621 actions = calculateupdates(repo, wc, p2, pa,
621 622 branchmerge, force, partial)
622 623
623 624 ### apply phase
624 625 if not branchmerge: # just jump to the new rev
625 626 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
626 627 if not partial:
627 628 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
628 629
629 630 stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
630 631
631 632 if not partial:
632 633 repo.setparents(fp1, fp2)
633 634 recordupdates(repo, actions, branchmerge)
634 635 if not branchmerge:
635 636 repo.dirstate.setbranch(p2.branch())
636 637 finally:
637 638 wlock.release()
638 639
639 640 if not partial:
640 641 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
641 642 return stats
@@ -1,64 +1,64 b''
1 1 $ hg init t
2 2 $ cd t
3 3
4 4 $ echo 1 > a
5 5 $ hg ci -qAm "first"
6 6
7 7 $ hg cp a b
8 8 $ hg mv a c
9 9 $ echo 2 >> b
10 10 $ echo 2 >> c
11 11
12 12 $ hg ci -qAm "second"
13 13
14 14 $ hg co -C 0
15 15 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
16 16
17 17 $ echo 0 > a
18 18 $ echo 1 >> a
19 19
20 20 $ hg ci -qAm "other"
21 21
22 22 $ hg merge --debug
23 23 searching for copies back to rev 1
24 24 unmatched files in other:
25 25 b
26 26 c
27 27 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
28 28 src: 'a' -> dst: 'b' *
29 29 src: 'a' -> dst: 'c' *
30 30 checking for directory renames
31 31 resolving manifests
32 overwrite: False, partial: False
32 branchmerge: True, force: False, partial: False
33 33 ancestor: b8bf91eeebbc, local: add3f11052fa+, remote: 17c05bb7fcb6
34 34 a: remote moved to b -> m
35 35 preserving a for resolve of b
36 36 a: remote moved to c -> m
37 37 preserving a for resolve of c
38 38 removing a
39 39 updating: a 1/2 files (50.00%)
40 40 picked tool 'internal:merge' for b (binary False symlink False)
41 41 merging a and b to b
42 42 my b@add3f11052fa+ other b@17c05bb7fcb6 ancestor a@b8bf91eeebbc
43 43 premerge successful
44 44 updating: a 2/2 files (100.00%)
45 45 picked tool 'internal:merge' for c (binary False symlink False)
46 46 merging a and c to c
47 47 my c@add3f11052fa+ other c@17c05bb7fcb6 ancestor a@b8bf91eeebbc
48 48 premerge successful
49 49 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
50 50 (branch merge, don't forget to commit)
51 51
52 52 file b
53 53 $ cat b
54 54 0
55 55 1
56 56 2
57 57
58 58 file c
59 59 $ cat c
60 60 0
61 61 1
62 62 2
63 63
64 64 $ cd ..
@@ -1,67 +1,67 b''
1 1 $ hg init repo
2 2 $ cd repo
3 3
4 4 $ echo line 1 > foo
5 5 $ hg ci -qAm 'add foo'
6 6
7 7 copy foo to bar and change both files
8 8 $ hg cp foo bar
9 9 $ echo line 2-1 >> foo
10 10 $ echo line 2-2 >> bar
11 11 $ hg ci -m 'cp foo bar; change both'
12 12
13 13 in another branch, change foo in a way that doesn't conflict with
14 14 the other changes
15 15 $ hg up -qC 0
16 16 $ echo line 0 > foo
17 17 $ hg cat foo >> foo
18 18 $ hg ci -m 'change foo'
19 19 created new head
20 20
21 21 we get conflicts that shouldn't be there
22 22 $ hg merge -P
23 23 changeset: 1:484bf6903104
24 24 user: test
25 25 date: Thu Jan 01 00:00:00 1970 +0000
26 26 summary: cp foo bar; change both
27 27
28 28 $ hg merge --debug
29 29 searching for copies back to rev 1
30 30 unmatched files in other:
31 31 bar
32 32 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
33 33 src: 'foo' -> dst: 'bar' *
34 34 checking for directory renames
35 35 resolving manifests
36 overwrite: False, partial: False
36 branchmerge: True, force: False, partial: False
37 37 ancestor: e6dc8efe11cc, local: 6a0df1dad128+, remote: 484bf6903104
38 38 foo: remote copied to bar -> m
39 39 preserving foo for resolve of bar
40 40 foo: versions differ -> m
41 41 preserving foo for resolve of foo
42 42 updating: foo 1/2 files (50.00%)
43 43 picked tool 'internal:merge' for bar (binary False symlink False)
44 44 merging foo and bar to bar
45 45 my bar@6a0df1dad128+ other bar@484bf6903104 ancestor foo@e6dc8efe11cc
46 46 premerge successful
47 47 updating: foo 2/2 files (100.00%)
48 48 picked tool 'internal:merge' for foo (binary False symlink False)
49 49 merging foo
50 50 my foo@6a0df1dad128+ other foo@484bf6903104 ancestor foo@e6dc8efe11cc
51 51 premerge successful
52 52 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
53 53 (branch merge, don't forget to commit)
54 54
55 55 contents of foo
56 56 $ cat foo
57 57 line 0
58 58 line 1
59 59 line 2-1
60 60
61 61 contents of bar
62 62 $ cat bar
63 63 line 0
64 64 line 1
65 65 line 2-2
66 66
67 67 $ cd ..
@@ -1,535 +1,535 b''
1 1 Create a repo with some stuff in it:
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ echo a > a
6 6 $ echo a > d
7 7 $ echo a > e
8 8 $ hg ci -qAm0
9 9 $ echo b > a
10 10 $ hg ci -m1 -u bar
11 11 $ hg mv a b
12 12 $ hg ci -m2
13 13 $ hg cp b c
14 14 $ hg ci -m3 -u baz
15 15 $ echo b > d
16 16 $ echo f > e
17 17 $ hg ci -m4
18 18 $ hg up -q 3
19 19 $ echo b > e
20 20 $ hg branch -q stable
21 21 $ hg ci -m5
22 22 $ hg merge -q default --tool internal:local
23 23 $ hg branch -q default
24 24 $ hg ci -m6
25 25 $ hg phase --public 3
26 26 $ hg phase --force --secret 6
27 27
28 28 $ hg --config extensions.graphlog= log -G --template '{author}@{rev}.{phase}: {desc}\n'
29 29 @ test@6.secret: 6
30 30 |\
31 31 | o test@5.draft: 5
32 32 | |
33 33 o | test@4.draft: 4
34 34 |/
35 35 o baz@3.public: 3
36 36 |
37 37 o test@2.public: 2
38 38 |
39 39 o bar@1.public: 1
40 40 |
41 41 o test@0.public: 0
42 42
43 43
44 44 Need to specify a rev:
45 45
46 46 $ hg graft
47 47 abort: no revisions specified
48 48 [255]
49 49
50 50 Can't graft ancestor:
51 51
52 52 $ hg graft 1 2
53 53 skipping ancestor revision 1
54 54 skipping ancestor revision 2
55 55 [255]
56 56
57 57 Specify revisions with -r:
58 58
59 59 $ hg graft -r 1 -r 2
60 60 skipping ancestor revision 1
61 61 skipping ancestor revision 2
62 62 [255]
63 63
64 64 $ hg graft -r 1 2
65 65 skipping ancestor revision 2
66 66 skipping ancestor revision 1
67 67 [255]
68 68
69 69 Can't graft with dirty wd:
70 70
71 71 $ hg up -q 0
72 72 $ echo foo > a
73 73 $ hg graft 1
74 74 abort: outstanding uncommitted changes
75 75 [255]
76 76 $ hg revert a
77 77
78 78 Graft a rename:
79 79
80 80 $ hg graft 2 -u foo
81 81 grafting revision 2
82 82 merging a and b to b
83 83 $ hg export tip --git
84 84 # HG changeset patch
85 85 # User foo
86 86 # Date 0 0
87 87 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
88 88 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
89 89 2
90 90
91 91 diff --git a/a b/b
92 92 rename from a
93 93 rename to b
94 94
95 95 Look for extra:source
96 96
97 97 $ hg log --debug -r tip
98 98 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
99 99 tag: tip
100 100 phase: draft
101 101 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
102 102 parent: -1:0000000000000000000000000000000000000000
103 103 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
104 104 user: foo
105 105 date: Thu Jan 01 00:00:00 1970 +0000
106 106 files+: b
107 107 files-: a
108 108 extra: branch=default
109 109 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
110 110 description:
111 111 2
112 112
113 113
114 114
115 115 Graft out of order, skipping a merge and a duplicate
116 116
117 117 $ hg graft 1 5 4 3 'merge()' 2 -n
118 118 skipping ungraftable merge revision 6
119 119 skipping already grafted revision 2
120 120 grafting revision 1
121 121 grafting revision 5
122 122 grafting revision 4
123 123 grafting revision 3
124 124
125 125 $ hg graft 1 5 4 3 'merge()' 2 --debug
126 126 skipping ungraftable merge revision 6
127 127 scanning for duplicate grafts
128 128 skipping already grafted revision 2
129 129 grafting revision 1
130 130 searching for copies back to rev 1
131 131 unmatched files in local:
132 132 b
133 133 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
134 134 src: 'a' -> dst: 'b' *
135 135 checking for directory renames
136 136 resolving manifests
137 overwrite: False, partial: False
137 branchmerge: True, force: True, partial: False
138 138 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
139 139 b: local copied/moved to a -> m
140 140 preserving b for resolve of b
141 141 updating: b 1/1 files (100.00%)
142 142 picked tool 'internal:merge' for b (binary False symlink False)
143 143 merging b and a to b
144 144 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
145 145 premerge successful
146 146 b
147 147 grafting revision 5
148 148 searching for copies back to rev 1
149 149 resolving manifests
150 overwrite: False, partial: False
150 branchmerge: True, force: True, partial: False
151 151 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
152 152 e: remote is newer -> g
153 153 updating: e 1/1 files (100.00%)
154 154 getting e
155 155 e
156 156 grafting revision 4
157 157 searching for copies back to rev 1
158 158 resolving manifests
159 overwrite: False, partial: False
159 branchmerge: True, force: True, partial: False
160 160 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
161 161 d: remote is newer -> g
162 162 e: versions differ -> m
163 163 preserving e for resolve of e
164 164 updating: d 1/2 files (50.00%)
165 165 getting d
166 166 updating: e 2/2 files (100.00%)
167 167 picked tool 'internal:merge' for e (binary False symlink False)
168 168 merging e
169 169 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
170 170 warning: conflicts during merge.
171 171 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
172 172 abort: unresolved conflicts, can't continue
173 173 (use hg resolve and hg graft --continue)
174 174 [255]
175 175
176 176 Continue without resolve should fail:
177 177
178 178 $ hg graft -c
179 179 grafting revision 4
180 180 abort: unresolved merge conflicts (see hg help resolve)
181 181 [255]
182 182
183 183 Fix up:
184 184
185 185 $ echo b > e
186 186 $ hg resolve -m e
187 187
188 188 Continue with a revision should fail:
189 189
190 190 $ hg graft -c 6
191 191 abort: can't specify --continue and revisions
192 192 [255]
193 193
194 194 $ hg graft -c -r 6
195 195 abort: can't specify --continue and revisions
196 196 [255]
197 197
198 198 Continue for real, clobber usernames
199 199
200 200 $ hg graft -c -U
201 201 grafting revision 4
202 202 grafting revision 3
203 203
204 204 Compare with original:
205 205
206 206 $ hg diff -r 6
207 207 $ hg status --rev 0:. -C
208 208 M d
209 209 M e
210 210 A b
211 211 a
212 212 A c
213 213 a
214 214 R a
215 215
216 216 View graph:
217 217
218 218 $ hg --config extensions.graphlog= log -G --template '{author}@{rev}.{phase}: {desc}\n'
219 219 @ test@11.draft: 3
220 220 |
221 221 o test@10.draft: 4
222 222 |
223 223 o test@9.draft: 5
224 224 |
225 225 o bar@8.draft: 1
226 226 |
227 227 o foo@7.draft: 2
228 228 |
229 229 | o test@6.secret: 6
230 230 | |\
231 231 | | o test@5.draft: 5
232 232 | | |
233 233 | o | test@4.draft: 4
234 234 | |/
235 235 | o baz@3.public: 3
236 236 | |
237 237 | o test@2.public: 2
238 238 | |
239 239 | o bar@1.public: 1
240 240 |/
241 241 o test@0.public: 0
242 242
243 243 Graft again onto another branch should preserve the original source
244 244 $ hg up -q 0
245 245 $ echo 'g'>g
246 246 $ hg add g
247 247 $ hg ci -m 7
248 248 created new head
249 249 $ hg graft 7
250 250 grafting revision 7
251 251
252 252 $ hg log -r 7 --template '{rev}:{node}\n'
253 253 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
254 254 $ hg log -r 2 --template '{rev}:{node}\n'
255 255 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
256 256
257 257 $ hg log --debug -r tip
258 258 changeset: 13:9db0f28fd3747e92c57d015f53b5593aeec53c2d
259 259 tag: tip
260 260 phase: draft
261 261 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
262 262 parent: -1:0000000000000000000000000000000000000000
263 263 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
264 264 user: foo
265 265 date: Thu Jan 01 00:00:00 1970 +0000
266 266 files+: b
267 267 files-: a
268 268 extra: branch=default
269 269 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
270 270 description:
271 271 2
272 272
273 273
274 274 Disallow grafting an already grafted cset onto its original branch
275 275 $ hg up -q 6
276 276 $ hg graft 7
277 277 skipping already grafted revision 7 (was grafted from 2)
278 278 [255]
279 279
280 280 Disallow grafting already grafted csets with the same origin onto each other
281 281 $ hg up -q 13
282 282 $ hg graft 2
283 283 skipping already grafted revision 2
284 284 [255]
285 285 $ hg graft 7
286 286 skipping already grafted revision 7 (same origin 2)
287 287 [255]
288 288
289 289 $ hg up -q 7
290 290 $ hg graft 2
291 291 skipping already grafted revision 2
292 292 [255]
293 293 $ hg graft tip
294 294 skipping already grafted revision 13 (same origin 2)
295 295 [255]
296 296
297 297 Graft with --log
298 298
299 299 $ hg up -Cq 1
300 300 $ hg graft 3 --log -u foo
301 301 grafting revision 3
302 302 warning: can't find ancestor for 'c' copied from 'b'!
303 303 $ hg log --template '{rev} {parents} {desc}\n' -r tip
304 304 14 1:5d205f8b35b6 3
305 305 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
306 306
307 307 Resolve conflicted graft
308 308 $ hg up -q 0
309 309 $ echo b > a
310 310 $ hg ci -m 8
311 311 created new head
312 312 $ echo a > a
313 313 $ hg ci -m 9
314 314 $ hg graft 1 --tool internal:fail
315 315 grafting revision 1
316 316 abort: unresolved conflicts, can't continue
317 317 (use hg resolve and hg graft --continue)
318 318 [255]
319 319 $ hg resolve --all
320 320 merging a
321 321 $ hg graft -c
322 322 grafting revision 1
323 323 $ hg export tip --git
324 324 # HG changeset patch
325 325 # User bar
326 326 # Date 0 0
327 327 # Node ID 64ecd9071ce83c6e62f538d8ce7709d53f32ebf7
328 328 # Parent 4bdb9a9d0b84ffee1d30f0dfc7744cade17aa19c
329 329 1
330 330
331 331 diff --git a/a b/a
332 332 --- a/a
333 333 +++ b/a
334 334 @@ -1,1 +1,1 @@
335 335 -a
336 336 +b
337 337
338 338 Resolve conflicted graft with rename
339 339 $ echo c > a
340 340 $ hg ci -m 10
341 341 $ hg graft 2 --tool internal:fail
342 342 grafting revision 2
343 343 abort: unresolved conflicts, can't continue
344 344 (use hg resolve and hg graft --continue)
345 345 [255]
346 346 $ hg resolve --all
347 347 merging a and b to b
348 348 $ hg graft -c
349 349 grafting revision 2
350 350 $ hg export tip --git
351 351 # HG changeset patch
352 352 # User test
353 353 # Date 0 0
354 354 # Node ID 2e80e1351d6ed50302fe1e05f8bd1d4d412b6e11
355 355 # Parent e5a51ae854a8bbaaf25cc5c6a57ff46042dadbb4
356 356 2
357 357
358 358 diff --git a/a b/b
359 359 rename from a
360 360 rename to b
361 361
362 362 Test simple origin(), with and without args
363 363 $ hg log -r 'origin()'
364 364 changeset: 1:5d205f8b35b6
365 365 user: bar
366 366 date: Thu Jan 01 00:00:00 1970 +0000
367 367 summary: 1
368 368
369 369 changeset: 2:5c095ad7e90f
370 370 user: test
371 371 date: Thu Jan 01 00:00:00 1970 +0000
372 372 summary: 2
373 373
374 374 changeset: 3:4c60f11aa304
375 375 user: baz
376 376 date: Thu Jan 01 00:00:00 1970 +0000
377 377 summary: 3
378 378
379 379 changeset: 4:9c233e8e184d
380 380 user: test
381 381 date: Thu Jan 01 00:00:00 1970 +0000
382 382 summary: 4
383 383
384 384 changeset: 5:97f8bfe72746
385 385 branch: stable
386 386 parent: 3:4c60f11aa304
387 387 user: test
388 388 date: Thu Jan 01 00:00:00 1970 +0000
389 389 summary: 5
390 390
391 391 $ hg log -r 'origin(7)'
392 392 changeset: 2:5c095ad7e90f
393 393 user: test
394 394 date: Thu Jan 01 00:00:00 1970 +0000
395 395 summary: 2
396 396
397 397 Now transplant a graft to test following through copies
398 398 $ hg up -q 0
399 399 $ hg branch -q dev
400 400 $ hg ci -qm "dev branch"
401 401 $ hg --config extensions.transplant= transplant -q 7
402 402 $ hg log -r 'origin(.)'
403 403 changeset: 2:5c095ad7e90f
404 404 user: test
405 405 date: Thu Jan 01 00:00:00 1970 +0000
406 406 summary: 2
407 407
408 408 Test simple destination
409 409 $ hg log -r 'destination()'
410 410 changeset: 7:ef0ef43d49e7
411 411 parent: 0:68795b066622
412 412 user: foo
413 413 date: Thu Jan 01 00:00:00 1970 +0000
414 414 summary: 2
415 415
416 416 changeset: 8:6b9e5368ca4e
417 417 user: bar
418 418 date: Thu Jan 01 00:00:00 1970 +0000
419 419 summary: 1
420 420
421 421 changeset: 9:1905859650ec
422 422 user: test
423 423 date: Thu Jan 01 00:00:00 1970 +0000
424 424 summary: 5
425 425
426 426 changeset: 10:52dc0b4c6907
427 427 user: test
428 428 date: Thu Jan 01 00:00:00 1970 +0000
429 429 summary: 4
430 430
431 431 changeset: 11:882b35362a6b
432 432 user: test
433 433 date: Thu Jan 01 00:00:00 1970 +0000
434 434 summary: 3
435 435
436 436 changeset: 13:9db0f28fd374
437 437 user: foo
438 438 date: Thu Jan 01 00:00:00 1970 +0000
439 439 summary: 2
440 440
441 441 changeset: 14:f64defefacee
442 442 parent: 1:5d205f8b35b6
443 443 user: foo
444 444 date: Thu Jan 01 00:00:00 1970 +0000
445 445 summary: 3
446 446
447 447 changeset: 17:64ecd9071ce8
448 448 user: bar
449 449 date: Thu Jan 01 00:00:00 1970 +0000
450 450 summary: 1
451 451
452 452 changeset: 19:2e80e1351d6e
453 453 user: test
454 454 date: Thu Jan 01 00:00:00 1970 +0000
455 455 summary: 2
456 456
457 457 changeset: 21:7e61b508e709
458 458 branch: dev
459 459 tag: tip
460 460 user: foo
461 461 date: Thu Jan 01 00:00:00 1970 +0000
462 462 summary: 2
463 463
464 464 $ hg log -r 'destination(2)'
465 465 changeset: 7:ef0ef43d49e7
466 466 parent: 0:68795b066622
467 467 user: foo
468 468 date: Thu Jan 01 00:00:00 1970 +0000
469 469 summary: 2
470 470
471 471 changeset: 13:9db0f28fd374
472 472 user: foo
473 473 date: Thu Jan 01 00:00:00 1970 +0000
474 474 summary: 2
475 475
476 476 changeset: 19:2e80e1351d6e
477 477 user: test
478 478 date: Thu Jan 01 00:00:00 1970 +0000
479 479 summary: 2
480 480
481 481 changeset: 21:7e61b508e709
482 482 branch: dev
483 483 tag: tip
484 484 user: foo
485 485 date: Thu Jan 01 00:00:00 1970 +0000
486 486 summary: 2
487 487
488 488 Transplants of grafts can find a destination...
489 489 $ hg log -r 'destination(7)'
490 490 changeset: 21:7e61b508e709
491 491 branch: dev
492 492 tag: tip
493 493 user: foo
494 494 date: Thu Jan 01 00:00:00 1970 +0000
495 495 summary: 2
496 496
497 497 ... grafts of grafts unfortunately can't
498 498 $ hg graft -q 13
499 499 $ hg log -r 'destination(13)'
500 500 All copies of a cset
501 501 $ hg log -r 'origin(13) or destination(origin(13))'
502 502 changeset: 2:5c095ad7e90f
503 503 user: test
504 504 date: Thu Jan 01 00:00:00 1970 +0000
505 505 summary: 2
506 506
507 507 changeset: 7:ef0ef43d49e7
508 508 parent: 0:68795b066622
509 509 user: foo
510 510 date: Thu Jan 01 00:00:00 1970 +0000
511 511 summary: 2
512 512
513 513 changeset: 13:9db0f28fd374
514 514 user: foo
515 515 date: Thu Jan 01 00:00:00 1970 +0000
516 516 summary: 2
517 517
518 518 changeset: 19:2e80e1351d6e
519 519 user: test
520 520 date: Thu Jan 01 00:00:00 1970 +0000
521 521 summary: 2
522 522
523 523 changeset: 21:7e61b508e709
524 524 branch: dev
525 525 user: foo
526 526 date: Thu Jan 01 00:00:00 1970 +0000
527 527 summary: 2
528 528
529 529 changeset: 22:1313d0a825e2
530 530 branch: dev
531 531 tag: tip
532 532 user: foo
533 533 date: Thu Jan 01 00:00:00 1970 +0000
534 534 summary: 2
535 535
@@ -1,73 +1,73 b''
1 1 $ "$TESTDIR/hghave" execbit || exit 80
2 2
3 3 Create extension that can disable exec checks:
4 4
5 5 $ cat > noexec.py <<EOF
6 6 > from mercurial import extensions, util
7 7 > def setflags(orig, f, l, x):
8 8 > pass
9 9 > def checkexec(orig, path):
10 10 > return False
11 11 > def extsetup(ui):
12 12 > extensions.wrapfunction(util, 'setflags', setflags)
13 13 > extensions.wrapfunction(util, 'checkexec', checkexec)
14 14 > EOF
15 15
16 16 $ hg init unix-repo
17 17 $ cd unix-repo
18 18 $ touch a
19 19 $ hg add a
20 20 $ hg commit -m 'unix: add a'
21 21 $ hg clone . ../win-repo
22 22 updating to branch default
23 23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 24 $ chmod +x a
25 25 $ hg commit -m 'unix: chmod a'
26 26 $ hg manifest -v
27 27 755 * a
28 28
29 29 $ cd ../win-repo
30 30
31 31 $ touch b
32 32 $ hg add b
33 33 $ hg commit -m 'win: add b'
34 34
35 35 $ hg manifest -v
36 36 644 a
37 37 644 b
38 38
39 39 $ hg pull
40 40 pulling from $TESTTMP/unix-repo
41 41 searching for changes
42 42 adding changesets
43 43 adding manifests
44 44 adding file changes
45 45 added 1 changesets with 0 changes to 0 files (+1 heads)
46 46 (run 'hg heads' to see heads, 'hg merge' to merge)
47 47
48 48 $ hg manifest -v -r tip
49 49 755 * a
50 50
51 51 Simulate a Windows merge:
52 52
53 53 $ hg --config extensions.n=$TESTTMP/noexec.py merge --debug
54 54 searching for copies back to rev 1
55 55 unmatched files in local:
56 56 b
57 57 resolving manifests
58 overwrite: False, partial: False
58 branchmerge: True, force: False, partial: False
59 59 ancestor: a03b0deabf2b, local: d6fa54f68ae1+, remote: 2d8bcf2dda39
60 60 a: update permissions -> e
61 61 updating: a 1/1 files (100.00%)
62 62 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 63 (branch merge, don't forget to commit)
64 64
65 65 Simulate a Windows commit:
66 66
67 67 $ hg --config extensions.n=$TESTTMP/noexec.py commit -m 'win: merge'
68 68
69 69 $ hg manifest -v
70 70 755 * a
71 71 644 b
72 72
73 73 $ cd ..
@@ -1,56 +1,56 b''
1 1 http://mercurial.selenic.com/bts/issue522
2 2
3 3 In the merge below, the file "foo" has the same contents in both
4 4 parents, but if we look at the file-level history, we'll notice that
5 5 the version in p1 is an ancestor of the version in p2. This test makes
6 6 sure that we'll use the version from p2 in the manifest of the merge
7 7 revision.
8 8
9 9 $ hg init
10 10
11 11 $ echo foo > foo
12 12 $ hg ci -qAm 'add foo'
13 13
14 14 $ echo bar >> foo
15 15 $ hg ci -m 'change foo'
16 16
17 17 $ hg backout -r tip -m 'backout changed foo'
18 18 reverting foo
19 19 changeset 2:4d9e78aaceee backs out changeset 1:b515023e500e
20 20
21 21 $ hg up -C 0
22 22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 23
24 24 $ touch bar
25 25 $ hg ci -qAm 'add bar'
26 26
27 27 $ hg merge --debug
28 28 searching for copies back to rev 1
29 29 unmatched files in local:
30 30 bar
31 31 resolving manifests
32 overwrite: False, partial: False
32 branchmerge: True, force: False, partial: False
33 33 ancestor: bbd179dfa0a7, local: 71766447bdbb+, remote: 4d9e78aaceee
34 34 foo: remote is newer -> g
35 35 updating: foo 1/1 files (100.00%)
36 36 getting foo
37 37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 38 (branch merge, don't forget to commit)
39 39
40 40 $ hg debugstate | grep foo
41 41 n 0 -2 unset foo
42 42
43 43 $ hg st -A foo
44 44 M foo
45 45
46 46 $ hg ci -m 'merge'
47 47
48 48 $ hg manifest --debug | grep foo
49 49 c6fc755d7e68f49f880599da29f15add41f42f5a 644 foo
50 50
51 51 $ hg debugindex foo
52 52 rev offset length ..... linkrev nodeid p1 p2 (re)
53 53 0 0 5 ..... 0 2ed2a3912a0b 000000000000 000000000000 (re)
54 54 1 5 9 ..... 1 6f4310b00b9a 2ed2a3912a0b 000000000000 (re)
55 55 2 14 5 ..... 2 c6fc755d7e68 6f4310b00b9a 000000000000 (re)
56 56
@@ -1,101 +1,101 b''
1 1 http://mercurial.selenic.com/bts/issue672
2 2
3 3 # 0-2-4
4 4 # \ \ \
5 5 # 1-3-5
6 6 #
7 7 # rename in #1, content change in #4.
8 8
9 9 $ hg init
10 10
11 11 $ touch 1
12 12 $ touch 2
13 13 $ hg commit -Am init # 0
14 14 adding 1
15 15 adding 2
16 16
17 17 $ hg rename 1 1a
18 18 $ hg commit -m rename # 1
19 19
20 20 $ hg co -C 0
21 21 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 22
23 23 $ echo unrelated >> 2
24 24 $ hg ci -m unrelated1 # 2
25 25 created new head
26 26
27 27 $ hg merge --debug 1
28 28 searching for copies back to rev 1
29 29 unmatched files in other:
30 30 1a
31 31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 32 src: '1' -> dst: '1a'
33 33 checking for directory renames
34 34 resolving manifests
35 overwrite: False, partial: False
35 branchmerge: True, force: False, partial: False
36 36 ancestor: 81f4b099af3d, local: c64f439569a9+, remote: c12dcd37c90a
37 37 1: other deleted -> r
38 38 1a: remote created -> g
39 39 updating: 1 1/2 files (50.00%)
40 40 removing 1
41 41 updating: 1a 2/2 files (100.00%)
42 42 getting 1a
43 43 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 44 (branch merge, don't forget to commit)
45 45
46 46 $ hg ci -m merge1 # 3
47 47
48 48 $ hg co -C 2
49 49 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
50 50
51 51 $ echo hello >> 1
52 52 $ hg ci -m unrelated2 # 4
53 53 created new head
54 54
55 55 $ hg co -C 3
56 56 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
57 57
58 58 $ hg merge -y --debug 4
59 59 searching for copies back to rev 1
60 60 unmatched files in local:
61 61 1a
62 62 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
63 63 src: '1' -> dst: '1a' *
64 64 checking for directory renames
65 65 resolving manifests
66 overwrite: False, partial: False
66 branchmerge: True, force: False, partial: False
67 67 ancestor: c64f439569a9, local: e327dca35ac8+, remote: 746e9549ea96
68 68 1a: local copied/moved to 1 -> m
69 69 preserving 1a for resolve of 1a
70 70 updating: 1a 1/1 files (100.00%)
71 71 picked tool 'internal:merge' for 1a (binary False symlink False)
72 72 merging 1a and 1 to 1a
73 73 my 1a@e327dca35ac8+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
74 74 premerge successful
75 75 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
76 76 (branch merge, don't forget to commit)
77 77
78 78 $ hg co -C 4
79 79 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
80 80
81 81 $ hg merge -y --debug 3
82 82 searching for copies back to rev 1
83 83 unmatched files in other:
84 84 1a
85 85 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
86 86 src: '1' -> dst: '1a' *
87 87 checking for directory renames
88 88 resolving manifests
89 overwrite: False, partial: False
89 branchmerge: True, force: False, partial: False
90 90 ancestor: c64f439569a9, local: 746e9549ea96+, remote: e327dca35ac8
91 91 1: remote moved to 1a -> m
92 92 preserving 1 for resolve of 1a
93 93 removing 1
94 94 updating: 1 1/1 files (100.00%)
95 95 picked tool 'internal:merge' for 1a (binary False symlink False)
96 96 merging 1 and 1a to 1a
97 97 my 1a@746e9549ea96+ other 1a@e327dca35ac8 ancestor 1@81f4b099af3d
98 98 premerge successful
99 99 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
100 100 (branch merge, don't forget to commit)
101 101
@@ -1,2089 +1,2089 b''
1 1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
2 2 $ mkdir "${USERCACHE}"
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > largefiles=
6 6 > purge=
7 7 > rebase=
8 8 > transplant=
9 9 > [phases]
10 10 > publish=False
11 11 > [largefiles]
12 12 > minsize=2
13 13 > patterns=glob:**.dat
14 14 > usercache=${USERCACHE}
15 15 > [hooks]
16 16 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
17 17 > EOF
18 18
19 19 Create the repo with a couple of revisions of both large and normal
20 20 files.
21 21 Test status and dirstate of largefiles and that summary output is correct.
22 22
23 23 $ hg init a
24 24 $ cd a
25 25 $ mkdir sub
26 26 $ echo normal1 > normal1
27 27 $ echo normal2 > sub/normal2
28 28 $ echo large1 > large1
29 29 $ echo large2 > sub/large2
30 30 $ hg add normal1 sub/normal2
31 31 $ hg add --large large1 sub/large2
32 32 $ hg commit -m "add files"
33 33 Invoking status precommit hook
34 34 A large1
35 35 A normal1
36 36 A sub/large2
37 37 A sub/normal2
38 38 $ touch large1 sub/large2
39 39 $ sleep 1
40 40 $ hg st
41 41 $ hg debugstate --nodates
42 42 n 644 41 .hglf/large1
43 43 n 644 41 .hglf/sub/large2
44 44 n 644 8 normal1
45 45 n 644 8 sub/normal2
46 46 $ hg debugstate --large
47 47 n 644 7 large1
48 48 n 644 7 sub/large2
49 49 $ echo normal11 > normal1
50 50 $ echo normal22 > sub/normal2
51 51 $ echo large11 > large1
52 52 $ echo large22 > sub/large2
53 53 $ hg commit -m "edit files"
54 54 Invoking status precommit hook
55 55 M large1
56 56 M normal1
57 57 M sub/large2
58 58 M sub/normal2
59 59 $ hg sum --large
60 60 parent: 1:ce8896473775 tip
61 61 edit files
62 62 branch: default
63 63 commit: (clean)
64 64 update: (current)
65 65 largefiles: (no remote repo)
66 66
67 67 Commit preserved largefile contents.
68 68
69 69 $ cat normal1
70 70 normal11
71 71 $ cat large1
72 72 large11
73 73 $ cat sub/normal2
74 74 normal22
75 75 $ cat sub/large2
76 76 large22
77 77
78 78 Test status, subdir and unknown files
79 79
80 80 $ echo unknown > sub/unknown
81 81 $ hg st --all
82 82 ? sub/unknown
83 83 C large1
84 84 C normal1
85 85 C sub/large2
86 86 C sub/normal2
87 87 $ hg st --all sub
88 88 ? sub/unknown
89 89 C sub/large2
90 90 C sub/normal2
91 91 $ rm sub/unknown
92 92
93 93 Test messages and exit codes for remove warning cases
94 94
95 95 $ hg remove -A large1
96 96 not removing large1: file still exists
97 97 [1]
98 98 $ echo 'modified' > large1
99 99 $ hg remove large1
100 100 not removing large1: file is modified (use -f to force removal)
101 101 [1]
102 102 $ echo 'new' > normalnew
103 103 $ hg add normalnew
104 104 $ echo 'new' > largenew
105 105 $ hg add --large normalnew
106 106 normalnew already tracked!
107 107 $ hg remove normalnew largenew
108 108 not removing largenew: file is untracked
109 109 not removing normalnew: file has been marked for add (use forget to undo)
110 110 [1]
111 111 $ rm normalnew largenew
112 112 $ hg up -Cq
113 113
114 114 Remove both largefiles and normal files.
115 115
116 116 $ hg remove normal1 large1
117 117 $ hg status large1
118 118 R large1
119 119 $ hg commit -m "remove files"
120 120 Invoking status precommit hook
121 121 R large1
122 122 R normal1
123 123 $ ls
124 124 sub
125 125 $ echo "testlargefile" > large1-test
126 126 $ hg add --large large1-test
127 127 $ hg st
128 128 A large1-test
129 129 $ hg rm large1-test
130 130 not removing large1-test: file has been marked for add (use forget to undo)
131 131 [1]
132 132 $ hg st
133 133 A large1-test
134 134 $ hg forget large1-test
135 135 $ hg st
136 136 ? large1-test
137 137 $ hg remove large1-test
138 138 not removing large1-test: file is untracked
139 139 [1]
140 140 $ hg forget large1-test
141 141 not removing large1-test: file is already untracked
142 142 [1]
143 143 $ rm large1-test
144 144
145 145 Copy both largefiles and normal files (testing that status output is correct).
146 146
147 147 $ hg cp sub/normal2 normal1
148 148 $ hg cp sub/large2 large1
149 149 $ hg commit -m "copy files"
150 150 Invoking status precommit hook
151 151 A large1
152 152 A normal1
153 153 $ cat normal1
154 154 normal22
155 155 $ cat large1
156 156 large22
157 157
158 158 Test moving largefiles and verify that normal files are also unaffected.
159 159
160 160 $ hg mv normal1 normal3
161 161 $ hg mv large1 large3
162 162 $ hg mv sub/normal2 sub/normal4
163 163 $ hg mv sub/large2 sub/large4
164 164 $ hg commit -m "move files"
165 165 Invoking status precommit hook
166 166 A large3
167 167 A normal3
168 168 A sub/large4
169 169 A sub/normal4
170 170 R large1
171 171 R normal1
172 172 R sub/large2
173 173 R sub/normal2
174 174 $ cat normal3
175 175 normal22
176 176 $ cat large3
177 177 large22
178 178 $ cat sub/normal4
179 179 normal22
180 180 $ cat sub/large4
181 181 large22
182 182
183 183 Test copies and moves from a directory other than root (issue3516)
184 184
185 185 $ cd ..
186 186 $ hg init lf_cpmv
187 187 $ cd lf_cpmv
188 188 $ mkdir dira
189 189 $ mkdir dira/dirb
190 190 $ touch dira/dirb/largefile
191 191 $ hg add --large dira/dirb/largefile
192 192 $ hg commit -m "added"
193 193 Invoking status precommit hook
194 194 A dira/dirb/largefile
195 195 $ cd dira
196 196 $ hg cp dirb/largefile foo/largefile
197 197 $ hg ci -m "deep copy"
198 198 Invoking status precommit hook
199 199 A dira/foo/largefile
200 200 $ find . | sort
201 201 .
202 202 ./dirb
203 203 ./dirb/largefile
204 204 ./foo
205 205 ./foo/largefile
206 206 $ hg mv foo/largefile baz/largefile
207 207 $ hg ci -m "moved"
208 208 Invoking status precommit hook
209 209 A dira/baz/largefile
210 210 R dira/foo/largefile
211 211 $ find . | sort
212 212 .
213 213 ./baz
214 214 ./baz/largefile
215 215 ./dirb
216 216 ./dirb/largefile
217 217 ./foo
218 218 $ cd ../../a
219 219
220 220 #if serve
221 221 Test display of largefiles in hgweb
222 222
223 223 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
224 224 $ cat ../hg.pid >> $DAEMON_PIDS
225 225 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
226 226 200 Script output follows
227 227
228 228
229 229 drwxr-xr-x sub
230 230 -rw-r--r-- 41 large3
231 231 -rw-r--r-- 9 normal3
232 232
233 233
234 234 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
235 235 200 Script output follows
236 236
237 237
238 238 -rw-r--r-- 41 large4
239 239 -rw-r--r-- 9 normal4
240 240
241 241
242 242 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
243 243 #endif
244 244
245 245 Test archiving the various revisions. These hit corner cases known with
246 246 archiving.
247 247
248 248 $ hg archive -r 0 ../archive0
249 249 $ hg archive -r 1 ../archive1
250 250 $ hg archive -r 2 ../archive2
251 251 $ hg archive -r 3 ../archive3
252 252 $ hg archive -r 4 ../archive4
253 253 $ cd ../archive0
254 254 $ cat normal1
255 255 normal1
256 256 $ cat large1
257 257 large1
258 258 $ cat sub/normal2
259 259 normal2
260 260 $ cat sub/large2
261 261 large2
262 262 $ cd ../archive1
263 263 $ cat normal1
264 264 normal11
265 265 $ cat large1
266 266 large11
267 267 $ cat sub/normal2
268 268 normal22
269 269 $ cat sub/large2
270 270 large22
271 271 $ cd ../archive2
272 272 $ ls
273 273 sub
274 274 $ cat sub/normal2
275 275 normal22
276 276 $ cat sub/large2
277 277 large22
278 278 $ cd ../archive3
279 279 $ cat normal1
280 280 normal22
281 281 $ cat large1
282 282 large22
283 283 $ cat sub/normal2
284 284 normal22
285 285 $ cat sub/large2
286 286 large22
287 287 $ cd ../archive4
288 288 $ cat normal3
289 289 normal22
290 290 $ cat large3
291 291 large22
292 292 $ cat sub/normal4
293 293 normal22
294 294 $ cat sub/large4
295 295 large22
296 296
297 297 Commit corner case: specify files to commit.
298 298
299 299 $ cd ../a
300 300 $ echo normal3 > normal3
301 301 $ echo large3 > large3
302 302 $ echo normal4 > sub/normal4
303 303 $ echo large4 > sub/large4
304 304 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
305 305 Invoking status precommit hook
306 306 M large3
307 307 M normal3
308 308 M sub/large4
309 309 M sub/normal4
310 310 $ cat normal3
311 311 normal3
312 312 $ cat large3
313 313 large3
314 314 $ cat sub/normal4
315 315 normal4
316 316 $ cat sub/large4
317 317 large4
318 318
319 319 One more commit corner case: commit from a subdirectory.
320 320
321 321 $ cd ../a
322 322 $ echo normal33 > normal3
323 323 $ echo large33 > large3
324 324 $ echo normal44 > sub/normal4
325 325 $ echo large44 > sub/large4
326 326 $ cd sub
327 327 $ hg commit -m "edit files yet again"
328 328 Invoking status precommit hook
329 329 M large3
330 330 M normal3
331 331 M sub/large4
332 332 M sub/normal4
333 333 $ cat ../normal3
334 334 normal33
335 335 $ cat ../large3
336 336 large33
337 337 $ cat normal4
338 338 normal44
339 339 $ cat large4
340 340 large44
341 341
342 342 Committing standins is not allowed.
343 343
344 344 $ cd ..
345 345 $ echo large3 > large3
346 346 $ hg commit .hglf/large3 -m "try to commit standin"
347 347 abort: file ".hglf/large3" is a largefile standin
348 348 (commit the largefile itself instead)
349 349 [255]
350 350
351 351 Corner cases for adding largefiles.
352 352
353 353 $ echo large5 > large5
354 354 $ hg add --large large5
355 355 $ hg add --large large5
356 356 large5 already a largefile
357 357 $ mkdir sub2
358 358 $ echo large6 > sub2/large6
359 359 $ echo large7 > sub2/large7
360 360 $ hg add --large sub2
361 361 adding sub2/large6 as a largefile (glob)
362 362 adding sub2/large7 as a largefile (glob)
363 363 $ hg st
364 364 M large3
365 365 A large5
366 366 A sub2/large6
367 367 A sub2/large7
368 368
369 369 Committing directories containing only largefiles.
370 370
371 371 $ mkdir -p z/y/x/m
372 372 $ touch z/y/x/m/large1
373 373 $ touch z/y/x/large2
374 374 $ hg add --large z/y/x/m/large1 z/y/x/large2
375 375 $ hg commit -m "Subdir with directory only containing largefiles" z
376 376 Invoking status precommit hook
377 377 M large3
378 378 A large5
379 379 A sub2/large6
380 380 A sub2/large7
381 381 A z/y/x/large2
382 382 A z/y/x/m/large1
383 383 $ hg rollback --quiet
384 384 $ touch z/y/x/m/normal
385 385 $ hg add z/y/x/m/normal
386 386 $ hg commit -m "Subdir with mixed contents" z
387 387 Invoking status precommit hook
388 388 M large3
389 389 A large5
390 390 A sub2/large6
391 391 A sub2/large7
392 392 A z/y/x/large2
393 393 A z/y/x/m/large1
394 394 A z/y/x/m/normal
395 395 $ hg st
396 396 M large3
397 397 A large5
398 398 A sub2/large6
399 399 A sub2/large7
400 400 $ hg rollback --quiet
401 401 $ hg revert z/y/x/large2 z/y/x/m/large1
402 402 $ rm z/y/x/large2 z/y/x/m/large1
403 403 $ hg commit -m "Subdir with normal contents" z
404 404 Invoking status precommit hook
405 405 M large3
406 406 A large5
407 407 A sub2/large6
408 408 A sub2/large7
409 409 A z/y/x/m/normal
410 410 $ hg st
411 411 M large3
412 412 A large5
413 413 A sub2/large6
414 414 A sub2/large7
415 415 $ hg rollback --quiet
416 416 $ hg revert --quiet z
417 417 $ hg commit -m "Empty subdir" z
418 418 abort: z: no match under directory!
419 419 [255]
420 420 $ rm -rf z
421 421 $ hg ci -m "standin" .hglf
422 422 abort: file ".hglf" is a largefile standin
423 423 (commit the largefile itself instead)
424 424 [255]
425 425
426 426 Test "hg status" with combination of 'file pattern' and 'directory
427 427 pattern' for largefiles:
428 428
429 429 $ hg status sub2/large6 sub2
430 430 A sub2/large6
431 431 A sub2/large7
432 432
433 433 Config settings (pattern **.dat, minsize 2 MB) are respected.
434 434
435 435 $ echo testdata > test.dat
436 436 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
437 437 $ hg add
438 438 adding reallylarge as a largefile
439 439 adding test.dat as a largefile
440 440
441 441 Test that minsize and --lfsize handle float values;
442 442 also tests that --lfsize overrides largefiles.minsize.
443 443 (0.250 MB = 256 kB = 262144 B)
444 444
445 445 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
446 446 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
447 447 $ hg --config largefiles.minsize=.25 add
448 448 adding ratherlarge as a largefile
449 449 adding medium
450 450 $ hg forget medium
451 451 $ hg --config largefiles.minsize=.25 add --lfsize=.125
452 452 adding medium as a largefile
453 453 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
454 454 $ hg --config largefiles.minsize=.25 add --lfsize=.125
455 455 adding notlarge
456 456 $ hg forget notlarge
457 457
458 458 Test forget on largefiles.
459 459
460 460 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
461 461 $ hg commit -m "add/edit more largefiles"
462 462 Invoking status precommit hook
463 463 A sub2/large6
464 464 A sub2/large7
465 465 R large3
466 466 ? large5
467 467 ? medium
468 468 ? notlarge
469 469 ? ratherlarge
470 470 ? reallylarge
471 471 ? test.dat
472 472 $ hg st
473 473 ? large3
474 474 ? large5
475 475 ? medium
476 476 ? notlarge
477 477 ? ratherlarge
478 478 ? reallylarge
479 479 ? test.dat
480 480
481 481 Purge with largefiles: verify that largefiles are still in the working
482 482 dir after a purge.
483 483
484 484 $ hg purge --all
485 485 $ cat sub/large4
486 486 large44
487 487 $ cat sub2/large6
488 488 large6
489 489 $ cat sub2/large7
490 490 large7
491 491
492 492 Test addremove: verify that files that should be added as largfiles are added as
493 493 such and that already-existing largfiles are not added as normal files by
494 494 accident.
495 495
496 496 $ rm normal3
497 497 $ rm sub/large4
498 498 $ echo "testing addremove with patterns" > testaddremove.dat
499 499 $ echo "normaladdremove" > normaladdremove
500 500 $ hg addremove
501 501 removing sub/large4
502 502 adding testaddremove.dat as a largefile
503 503 removing normal3
504 504 adding normaladdremove
505 505
506 506 Test addremove with -R
507 507
508 508 $ hg up -C
509 509 getting changed largefiles
510 510 1 largefiles updated, 0 removed
511 511 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
512 512 $ rm normal3
513 513 $ rm sub/large4
514 514 $ echo "testing addremove with patterns" > testaddremove.dat
515 515 $ echo "normaladdremove" > normaladdremove
516 516 $ cd ..
517 517 $ hg -R a addremove
518 518 removing sub/large4
519 519 adding a/testaddremove.dat as a largefile (glob)
520 520 removing normal3
521 521 adding normaladdremove
522 522 $ cd a
523 523
524 524 Test 3364
525 525 $ hg clone . ../addrm
526 526 updating to branch default
527 527 getting changed largefiles
528 528 3 largefiles updated, 0 removed
529 529 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
530 530 $ cd ../addrm
531 531 $ cat >> .hg/hgrc <<EOF
532 532 > [hooks]
533 533 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
534 534 > EOF
535 535 $ touch foo
536 536 $ hg add --large foo
537 537 $ hg ci -m "add foo"
538 538 Invoking status precommit hook
539 539 A foo
540 540 Invoking status postcommit hook
541 541 C foo
542 542 C normal3
543 543 C sub/large4
544 544 C sub/normal4
545 545 C sub2/large6
546 546 C sub2/large7
547 547 $ rm foo
548 548 $ hg st
549 549 ! foo
550 550 hmm.. no precommit invoked, but there is a postcommit??
551 551 $ hg ci -m "will not checkin"
552 552 nothing changed
553 553 Invoking status postcommit hook
554 554 ! foo
555 555 C normal3
556 556 C sub/large4
557 557 C sub/normal4
558 558 C sub2/large6
559 559 C sub2/large7
560 560 [1]
561 561 $ hg addremove
562 562 removing foo
563 563 $ hg st
564 564 R foo
565 565 $ hg ci -m "used to say nothing changed"
566 566 Invoking status precommit hook
567 567 R foo
568 568 Invoking status postcommit hook
569 569 C normal3
570 570 C sub/large4
571 571 C sub/normal4
572 572 C sub2/large6
573 573 C sub2/large7
574 574 $ hg st
575 575
576 576 Test 3507 (both normal files and largefiles were a problem)
577 577
578 578 $ touch normal
579 579 $ touch large
580 580 $ hg add normal
581 581 $ hg add --large large
582 582 $ hg ci -m "added"
583 583 Invoking status precommit hook
584 584 A large
585 585 A normal
586 586 Invoking status postcommit hook
587 587 C large
588 588 C normal
589 589 C normal3
590 590 C sub/large4
591 591 C sub/normal4
592 592 C sub2/large6
593 593 C sub2/large7
594 594 $ hg remove normal
595 595 $ hg addremove --traceback
596 596 $ hg ci -m "addremoved normal"
597 597 Invoking status precommit hook
598 598 R normal
599 599 Invoking status postcommit hook
600 600 C large
601 601 C normal3
602 602 C sub/large4
603 603 C sub/normal4
604 604 C sub2/large6
605 605 C sub2/large7
606 606 $ hg up -C '.^'
607 607 getting changed largefiles
608 608 0 largefiles updated, 0 removed
609 609 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
610 610 $ hg remove large
611 611 $ hg addremove --traceback
612 612 $ hg ci -m "removed large"
613 613 Invoking status precommit hook
614 614 R large
615 615 created new head
616 616 Invoking status postcommit hook
617 617 C normal
618 618 C normal3
619 619 C sub/large4
620 620 C sub/normal4
621 621 C sub2/large6
622 622 C sub2/large7
623 623
624 624 Test commit -A (issue 3542)
625 625 $ echo large8 > large8
626 626 $ hg add --large large8
627 627 $ hg ci -Am 'this used to add large8 as normal and commit both'
628 628 Invoking status precommit hook
629 629 A large8
630 630 Invoking status postcommit hook
631 631 C large8
632 632 C normal
633 633 C normal3
634 634 C sub/large4
635 635 C sub/normal4
636 636 C sub2/large6
637 637 C sub2/large7
638 638 $ rm large8
639 639 $ hg ci -Am 'this used to not notice the rm'
640 640 removing large8
641 641 Invoking status precommit hook
642 642 R large8
643 643 Invoking status postcommit hook
644 644 C normal
645 645 C normal3
646 646 C sub/large4
647 647 C sub/normal4
648 648 C sub2/large6
649 649 C sub2/large7
650 650
651 651 Test that a standin can't be added as a large file
652 652
653 653 $ touch large
654 654 $ hg add --large large
655 655 $ hg ci -m "add"
656 656 Invoking status precommit hook
657 657 A large
658 658 Invoking status postcommit hook
659 659 C large
660 660 C normal
661 661 C normal3
662 662 C sub/large4
663 663 C sub/normal4
664 664 C sub2/large6
665 665 C sub2/large7
666 666 $ hg remove large
667 667 $ touch large
668 668 $ hg addremove --config largefiles.patterns=**large --traceback
669 669 adding large as a largefile
670 670
671 671 Test that outgoing --large works (with revsets too)
672 672 $ hg outgoing --rev '.^' --large
673 673 comparing with $TESTTMP/a (glob)
674 674 searching for changes
675 675 changeset: 8:c02fd3b77ec4
676 676 user: test
677 677 date: Thu Jan 01 00:00:00 1970 +0000
678 678 summary: add foo
679 679
680 680 changeset: 9:289dd08c9bbb
681 681 user: test
682 682 date: Thu Jan 01 00:00:00 1970 +0000
683 683 summary: used to say nothing changed
684 684
685 685 changeset: 10:34f23ac6ac12
686 686 user: test
687 687 date: Thu Jan 01 00:00:00 1970 +0000
688 688 summary: added
689 689
690 690 changeset: 12:710c1b2f523c
691 691 parent: 10:34f23ac6ac12
692 692 user: test
693 693 date: Thu Jan 01 00:00:00 1970 +0000
694 694 summary: removed large
695 695
696 696 changeset: 13:0a3e75774479
697 697 user: test
698 698 date: Thu Jan 01 00:00:00 1970 +0000
699 699 summary: this used to add large8 as normal and commit both
700 700
701 701 changeset: 14:84f3d378175c
702 702 user: test
703 703 date: Thu Jan 01 00:00:00 1970 +0000
704 704 summary: this used to not notice the rm
705 705
706 706 searching for changes
707 707 largefiles to upload:
708 708 foo
709 709 large
710 710 large8
711 711
712 712 $ cd ../a
713 713
714 714 Clone a largefiles repo.
715 715
716 716 $ hg clone . ../b
717 717 updating to branch default
718 718 getting changed largefiles
719 719 3 largefiles updated, 0 removed
720 720 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 721 $ cd ../b
722 722 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
723 723 7:daea875e9014 add/edit more largefiles
724 724 6:4355d653f84f edit files yet again
725 725 5:9d5af5072dbd edit files again
726 726 4:74c02385b94c move files
727 727 3:9e8fbc4bce62 copy files
728 728 2:51a0ae4d5864 remove files
729 729 1:ce8896473775 edit files
730 730 0:30d30fe6a5be add files
731 731 $ cat normal3
732 732 normal33
733 733 $ cat sub/normal4
734 734 normal44
735 735 $ cat sub/large4
736 736 large44
737 737 $ cat sub2/large6
738 738 large6
739 739 $ cat sub2/large7
740 740 large7
741 741 $ cd ..
742 742 $ hg clone a -r 3 c
743 743 adding changesets
744 744 adding manifests
745 745 adding file changes
746 746 added 4 changesets with 10 changes to 4 files
747 747 updating to branch default
748 748 getting changed largefiles
749 749 2 largefiles updated, 0 removed
750 750 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
751 751 $ cd c
752 752 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
753 753 3:9e8fbc4bce62 copy files
754 754 2:51a0ae4d5864 remove files
755 755 1:ce8896473775 edit files
756 756 0:30d30fe6a5be add files
757 757 $ cat normal1
758 758 normal22
759 759 $ cat large1
760 760 large22
761 761 $ cat sub/normal2
762 762 normal22
763 763 $ cat sub/large2
764 764 large22
765 765
766 766 Old revisions of a clone have correct largefiles content (this also
767 767 tests update).
768 768
769 769 $ hg update -r 1
770 770 getting changed largefiles
771 771 1 largefiles updated, 0 removed
772 772 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
773 773 $ cat large1
774 774 large11
775 775 $ cat sub/large2
776 776 large22
777 777 $ cd ..
778 778
779 779 Test cloning with --all-largefiles flag
780 780
781 781 $ rm "${USERCACHE}"/*
782 782 $ hg clone --all-largefiles a a-backup
783 783 updating to branch default
784 784 getting changed largefiles
785 785 3 largefiles updated, 0 removed
786 786 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 787 8 additional largefiles cached
788 788
789 789 $ rm "${USERCACHE}"/*
790 790 $ hg clone --all-largefiles -u 0 a a-clone0
791 791 updating to branch default
792 792 getting changed largefiles
793 793 2 largefiles updated, 0 removed
794 794 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
795 795 9 additional largefiles cached
796 796 $ hg -R a-clone0 sum
797 797 parent: 0:30d30fe6a5be
798 798 add files
799 799 branch: default
800 800 commit: (clean)
801 801 update: 7 new changesets (update)
802 802
803 803 $ rm "${USERCACHE}"/*
804 804 $ hg clone --all-largefiles -u 1 a a-clone1
805 805 updating to branch default
806 806 getting changed largefiles
807 807 2 largefiles updated, 0 removed
808 808 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
809 809 8 additional largefiles cached
810 810 $ hg -R a-clone1 verify --large --lfa --lfc
811 811 checking changesets
812 812 checking manifests
813 813 crosschecking files in changesets and manifests
814 814 checking files
815 815 10 files, 8 changesets, 24 total revisions
816 816 searching 8 changesets for largefiles
817 817 verified contents of 13 revisions of 6 largefiles
818 818 $ hg -R a-clone1 sum
819 819 parent: 1:ce8896473775
820 820 edit files
821 821 branch: default
822 822 commit: (clean)
823 823 update: 6 new changesets (update)
824 824
825 825 $ rm "${USERCACHE}"/*
826 826 $ hg clone --all-largefiles -U a a-clone-u
827 827 11 additional largefiles cached
828 828 $ hg -R a-clone-u sum
829 829 parent: -1:000000000000 (no revision checked out)
830 830 branch: default
831 831 commit: (clean)
832 832 update: 8 new changesets (update)
833 833
834 834 Show computed destination directory:
835 835
836 836 $ mkdir xyz
837 837 $ cd xyz
838 838 $ hg clone ../a
839 839 destination directory: a
840 840 updating to branch default
841 841 getting changed largefiles
842 842 3 largefiles updated, 0 removed
843 843 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
844 844 $ cd ..
845 845
846 846 Clone URL without path:
847 847
848 848 $ hg clone file://
849 849 abort: repository / not found!
850 850 [255]
851 851
852 852 Ensure base clone command argument validation
853 853
854 854 $ hg clone -U -u 0 a a-clone-failure
855 855 abort: cannot specify both --noupdate and --updaterev
856 856 [255]
857 857
858 858 $ hg clone --all-largefiles a ssh://localhost/a
859 859 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
860 860 [255]
861 861
862 862 Test pulling with --all-largefiles flag. Also test that the largefiles are
863 863 downloaded from 'default' instead of 'default-push' when no source is specified
864 864 (issue3584)
865 865
866 866 $ rm -Rf a-backup
867 867 $ hg clone -r 1 a a-backup
868 868 adding changesets
869 869 adding manifests
870 870 adding file changes
871 871 added 2 changesets with 8 changes to 4 files
872 872 updating to branch default
873 873 getting changed largefiles
874 874 2 largefiles updated, 0 removed
875 875 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 876 $ rm "${USERCACHE}"/*
877 877 $ cd a-backup
878 878 $ hg pull --all-largefiles --config paths.default-push=bogus/path
879 879 pulling from $TESTTMP/a (glob)
880 880 searching for changes
881 881 adding changesets
882 882 adding manifests
883 883 adding file changes
884 884 added 6 changesets with 16 changes to 8 files
885 885 (run 'hg update' to get a working copy)
886 886 caching largefiles for 1 heads
887 887 3 largefiles cached
888 888 3 additional largefiles cached
889 889 $ cd ..
890 890
891 891 Rebasing between two repositories does not revert largefiles to old
892 892 revisions (this was a very bad bug that took a lot of work to fix).
893 893
894 894 $ hg clone a d
895 895 updating to branch default
896 896 getting changed largefiles
897 897 3 largefiles updated, 0 removed
898 898 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
899 899 $ cd b
900 900 $ echo large4-modified > sub/large4
901 901 $ echo normal3-modified > normal3
902 902 $ hg commit -m "modify normal file and largefile in repo b"
903 903 Invoking status precommit hook
904 904 M normal3
905 905 M sub/large4
906 906 $ cd ../d
907 907 $ echo large6-modified > sub2/large6
908 908 $ echo normal4-modified > sub/normal4
909 909 $ hg commit -m "modify normal file largefile in repo d"
910 910 Invoking status precommit hook
911 911 M sub/normal4
912 912 M sub2/large6
913 913 $ cd ..
914 914 $ hg clone d e
915 915 updating to branch default
916 916 getting changed largefiles
917 917 3 largefiles updated, 0 removed
918 918 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
919 919 $ cd d
920 920
921 921 More rebase testing, but also test that the largefiles are downloaded from
922 922 'default' instead of 'default-push' when no source is specified (issue3584).
923 923 The error messages go away if repo 'b' is created with --all-largefiles.
924 924 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
925 925 pulling from $TESTTMP/b (glob)
926 926 searching for changes
927 927 adding changesets
928 928 adding manifests
929 929 adding file changes
930 930 added 1 changesets with 2 changes to 2 files (+1 heads)
931 931 Invoking status precommit hook
932 932 M sub/normal4
933 933 M sub2/large6
934 934 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
935 935 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large3: can't get file locally (glob)
936 936 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large4: can't get file locally (glob)
937 937 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file large1: can't get file locally (glob)
938 938 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob)
939 939 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob)
940 940 error getting id 5f78770c0e77ba4287ad6ef3071c9bf9c379742f from url file:$TESTTMP/b for file large1: can't get file locally (glob)
941 941 error getting id eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob)
942 942 error getting id 4669e532d5b2c093a78eca010077e708a071bb64 from url file:$TESTTMP/b for file large1: can't get file locally (glob)
943 943 error getting id 1deebade43c8c498a3c8daddac0244dc55d1331d from url file:$TESTTMP/b for file sub/large2: can't get file locally (glob)
944 944 0 additional largefiles cached
945 945 9 largefiles failed to download
946 946 nothing to rebase
947 947 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
948 948 9:598410d3eb9a modify normal file largefile in repo d
949 949 8:a381d2c8c80e modify normal file and largefile in repo b
950 950 7:daea875e9014 add/edit more largefiles
951 951 6:4355d653f84f edit files yet again
952 952 5:9d5af5072dbd edit files again
953 953 4:74c02385b94c move files
954 954 3:9e8fbc4bce62 copy files
955 955 2:51a0ae4d5864 remove files
956 956 1:ce8896473775 edit files
957 957 0:30d30fe6a5be add files
958 958 $ cat normal3
959 959 normal3-modified
960 960 $ cat sub/normal4
961 961 normal4-modified
962 962 $ cat sub/large4
963 963 large4-modified
964 964 $ cat sub2/large6
965 965 large6-modified
966 966 $ cat sub2/large7
967 967 large7
968 968 $ cd ../e
969 969 $ hg pull ../b
970 970 pulling from ../b
971 971 searching for changes
972 972 adding changesets
973 973 adding manifests
974 974 adding file changes
975 975 added 1 changesets with 2 changes to 2 files (+1 heads)
976 976 (run 'hg heads' to see heads, 'hg merge' to merge)
977 977 caching largefiles for 1 heads
978 978 0 largefiles cached
979 979 $ hg rebase
980 980 Invoking status precommit hook
981 981 M sub/normal4
982 982 M sub2/large6
983 983 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
984 984 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
985 985 9:598410d3eb9a modify normal file largefile in repo d
986 986 8:a381d2c8c80e modify normal file and largefile in repo b
987 987 7:daea875e9014 add/edit more largefiles
988 988 6:4355d653f84f edit files yet again
989 989 5:9d5af5072dbd edit files again
990 990 4:74c02385b94c move files
991 991 3:9e8fbc4bce62 copy files
992 992 2:51a0ae4d5864 remove files
993 993 1:ce8896473775 edit files
994 994 0:30d30fe6a5be add files
995 995 $ cat normal3
996 996 normal3-modified
997 997 $ cat sub/normal4
998 998 normal4-modified
999 999 $ cat sub/large4
1000 1000 large4-modified
1001 1001 $ cat sub2/large6
1002 1002 large6-modified
1003 1003 $ cat sub2/large7
1004 1004 large7
1005 1005
1006 1006 Log on largefiles
1007 1007
1008 1008 - same output
1009 1009 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1010 1010 8:a381d2c8c80e modify normal file and largefile in repo b
1011 1011 6:4355d653f84f edit files yet again
1012 1012 5:9d5af5072dbd edit files again
1013 1013 4:74c02385b94c move files
1014 1014 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
1015 1015 8:a381d2c8c80e modify normal file and largefile in repo b
1016 1016 6:4355d653f84f edit files yet again
1017 1017 5:9d5af5072dbd edit files again
1018 1018 4:74c02385b94c move files
1019 1019
1020 1020 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1021 1021 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1022 1022 8:a381d2c8c80e modify normal file and largefile in repo b
1023 1023 6:4355d653f84f edit files yet again
1024 1024 5:9d5af5072dbd edit files again
1025 1025 4:74c02385b94c move files
1026 1026 1:ce8896473775 edit files
1027 1027 0:30d30fe6a5be add files
1028 1028 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1029 1029 9:598410d3eb9a modify normal file largefile in repo d
1030 1030 8:a381d2c8c80e modify normal file and largefile in repo b
1031 1031 6:4355d653f84f edit files yet again
1032 1032 5:9d5af5072dbd edit files again
1033 1033 4:74c02385b94c move files
1034 1034 1:ce8896473775 edit files
1035 1035 0:30d30fe6a5be add files
1036 1036
1037 1037 - globbing gives same result
1038 1038 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1039 1039 9:598410d3eb9a modify normal file largefile in repo d
1040 1040 8:a381d2c8c80e modify normal file and largefile in repo b
1041 1041 6:4355d653f84f edit files yet again
1042 1042 5:9d5af5072dbd edit files again
1043 1043 4:74c02385b94c move files
1044 1044 1:ce8896473775 edit files
1045 1045 0:30d30fe6a5be add files
1046 1046
1047 1047 Rollback on largefiles.
1048 1048
1049 1049 $ echo large4-modified-again > sub/large4
1050 1050 $ hg commit -m "Modify large4 again"
1051 1051 Invoking status precommit hook
1052 1052 M sub/large4
1053 1053 $ hg rollback
1054 1054 repository tip rolled back to revision 9 (undo commit)
1055 1055 working directory now based on revision 9
1056 1056 $ hg st
1057 1057 M sub/large4
1058 1058 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1059 1059 9:598410d3eb9a modify normal file largefile in repo d
1060 1060 8:a381d2c8c80e modify normal file and largefile in repo b
1061 1061 7:daea875e9014 add/edit more largefiles
1062 1062 6:4355d653f84f edit files yet again
1063 1063 5:9d5af5072dbd edit files again
1064 1064 4:74c02385b94c move files
1065 1065 3:9e8fbc4bce62 copy files
1066 1066 2:51a0ae4d5864 remove files
1067 1067 1:ce8896473775 edit files
1068 1068 0:30d30fe6a5be add files
1069 1069 $ cat sub/large4
1070 1070 large4-modified-again
1071 1071
1072 1072 "update --check" refuses to update with uncommitted changes.
1073 1073 $ hg update --check 8
1074 1074 abort: uncommitted local changes
1075 1075 [255]
1076 1076
1077 1077 "update --clean" leaves correct largefiles in working copy, even when there is
1078 1078 .orig files from revert in .hglf.
1079 1079
1080 1080 $ echo mistake > sub2/large7
1081 1081 $ hg revert sub2/large7
1082 1082 $ hg -q update --clean -r null
1083 1083 $ hg update --clean
1084 1084 getting changed largefiles
1085 1085 3 largefiles updated, 0 removed
1086 1086 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1087 1087 $ cat normal3
1088 1088 normal3-modified
1089 1089 $ cat sub/normal4
1090 1090 normal4-modified
1091 1091 $ cat sub/large4
1092 1092 large4-modified
1093 1093 $ cat sub2/large6
1094 1094 large6-modified
1095 1095 $ cat sub2/large7
1096 1096 large7
1097 1097 $ cat sub2/large7.orig
1098 1098 mistake
1099 1099 $ cat .hglf/sub2/large7.orig
1100 1100 9dbfb2c79b1c40981b258c3efa1b10b03f18ad31
1101 1101
1102 1102 demonstrate misfeature: .orig file is overwritten on every update -C,
1103 1103 also when clean:
1104 1104 $ hg update --clean
1105 1105 getting changed largefiles
1106 1106 0 largefiles updated, 0 removed
1107 1107 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1108 1108 $ cat sub2/large7.orig
1109 1109 large7
1110 1110 $ rm sub2/large7.orig .hglf/sub2/large7.orig
1111 1111
1112 1112 Now "update check" is happy.
1113 1113 $ hg update --check 8
1114 1114 getting changed largefiles
1115 1115 1 largefiles updated, 0 removed
1116 1116 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1117 1117 $ hg update --check
1118 1118 getting changed largefiles
1119 1119 1 largefiles updated, 0 removed
1120 1120 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1121 1121
1122 1122 Test removing empty largefiles directories on update
1123 1123 $ test -d sub2 && echo "sub2 exists"
1124 1124 sub2 exists
1125 1125 $ hg update -q null
1126 1126 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1127 1127 [1]
1128 1128 $ hg update -q
1129 1129
1130 1130 Test hg remove removes empty largefiles directories
1131 1131 $ test -d sub2 && echo "sub2 exists"
1132 1132 sub2 exists
1133 1133 $ hg remove sub2/*
1134 1134 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1135 1135 [1]
1136 1136 $ hg revert sub2/large6 sub2/large7
1137 1137
1138 1138 "revert" works on largefiles (and normal files too).
1139 1139 $ echo hack3 >> normal3
1140 1140 $ echo hack4 >> sub/normal4
1141 1141 $ echo hack4 >> sub/large4
1142 1142 $ rm sub2/large6
1143 1143 $ hg revert sub2/large6
1144 1144 $ hg rm sub2/large6
1145 1145 $ echo new >> sub2/large8
1146 1146 $ hg add --large sub2/large8
1147 1147 # XXX we don't really want to report that we're reverting the standin;
1148 1148 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1149 1149 $ hg revert sub
1150 1150 reverting .hglf/sub/large4 (glob)
1151 1151 reverting sub/normal4 (glob)
1152 1152 $ hg status
1153 1153 M normal3
1154 1154 A sub2/large8
1155 1155 R sub2/large6
1156 1156 ? sub/large4.orig
1157 1157 ? sub/normal4.orig
1158 1158 $ cat sub/normal4
1159 1159 normal4-modified
1160 1160 $ cat sub/large4
1161 1161 large4-modified
1162 1162 $ hg revert -a --no-backup
1163 1163 undeleting .hglf/sub2/large6 (glob)
1164 1164 forgetting .hglf/sub2/large8 (glob)
1165 1165 reverting normal3
1166 1166 $ hg status
1167 1167 ? sub/large4.orig
1168 1168 ? sub/normal4.orig
1169 1169 ? sub2/large8
1170 1170 $ cat normal3
1171 1171 normal3-modified
1172 1172 $ cat sub2/large6
1173 1173 large6-modified
1174 1174 $ rm sub/*.orig sub2/large8
1175 1175
1176 1176 revert some files to an older revision
1177 1177 $ hg revert --no-backup -r 8 sub2
1178 1178 reverting .hglf/sub2/large6 (glob)
1179 1179 $ cat sub2/large6
1180 1180 large6
1181 1181 $ hg revert --no-backup -C -r '.^' sub2
1182 1182 reverting .hglf/sub2/large6 (glob)
1183 1183 $ hg revert --no-backup sub2
1184 1184 reverting .hglf/sub2/large6 (glob)
1185 1185 $ hg status
1186 1186
1187 1187 "verify --large" actually verifies largefiles
1188 1188
1189 1189 - Where Do We Come From? What Are We? Where Are We Going?
1190 1190 $ pwd
1191 1191 $TESTTMP/e
1192 1192 $ hg paths
1193 1193 default = $TESTTMP/d (glob)
1194 1194
1195 1195 $ hg verify --large
1196 1196 checking changesets
1197 1197 checking manifests
1198 1198 crosschecking files in changesets and manifests
1199 1199 checking files
1200 1200 10 files, 10 changesets, 28 total revisions
1201 1201 searching 1 changesets for largefiles
1202 1202 verified existence of 3 revisions of 3 largefiles
1203 1203
1204 1204 - introduce missing blob in local store repo and make sure that this is caught:
1205 1205 $ mv $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 .
1206 1206 $ hg verify --large
1207 1207 checking changesets
1208 1208 checking manifests
1209 1209 crosschecking files in changesets and manifests
1210 1210 checking files
1211 1211 10 files, 10 changesets, 28 total revisions
1212 1212 searching 1 changesets for largefiles
1213 1213 changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1214 1214 verified existence of 3 revisions of 3 largefiles
1215 1215 [1]
1216 1216
1217 1217 - introduce corruption and make sure that it is caught when checking content:
1218 1218 $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1219 1219 $ hg verify -q --large --lfc
1220 1220 changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1221 1221 [1]
1222 1222
1223 1223 - cleanup
1224 1224 $ mv e166e74c7303192238d60af5a9c4ce9bef0b7928 $TESTTMP/d/.hg/largefiles/
1225 1225
1226 1226 - verifying all revisions will fail because we didn't clone all largefiles to d:
1227 1227 $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1228 1228 $ hg verify -q --lfa --lfc
1229 1229 changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 (glob)
1230 1230 changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d (glob)
1231 1231 changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f (glob)
1232 1232 changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1233 1233 changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1234 1234 changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1235 1235 changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1236 1236 [1]
1237 1237
1238 1238 - cleanup
1239 1239 $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1240 1240
1241 1241 Merging does not revert to old versions of largefiles and also check
1242 1242 that merging after having pulled from a non-default remote works
1243 1243 correctly.
1244 1244
1245 1245 $ cd ..
1246 1246 $ hg clone -r 7 e temp
1247 1247 adding changesets
1248 1248 adding manifests
1249 1249 adding file changes
1250 1250 added 8 changesets with 24 changes to 10 files
1251 1251 updating to branch default
1252 1252 getting changed largefiles
1253 1253 3 largefiles updated, 0 removed
1254 1254 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1255 1255 $ hg clone temp f
1256 1256 updating to branch default
1257 1257 getting changed largefiles
1258 1258 3 largefiles updated, 0 removed
1259 1259 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1260 1260 # Delete the largefiles in the largefiles system cache so that we have an
1261 1261 # opportunity to test that caching after a pull works.
1262 1262 $ rm "${USERCACHE}"/*
1263 1263 $ cd f
1264 1264 $ echo "large4-merge-test" > sub/large4
1265 1265 $ hg commit -m "Modify large4 to test merge"
1266 1266 Invoking status precommit hook
1267 1267 M sub/large4
1268 1268 $ hg pull ../e
1269 1269 pulling from ../e
1270 1270 searching for changes
1271 1271 adding changesets
1272 1272 adding manifests
1273 1273 adding file changes
1274 1274 added 2 changesets with 4 changes to 4 files (+1 heads)
1275 1275 (run 'hg heads' to see heads, 'hg merge' to merge)
1276 1276 caching largefiles for 1 heads
1277 1277 2 largefiles cached
1278 1278 $ hg merge
1279 1279 merging sub/large4
1280 1280 largefile sub/large4 has a merge conflict
1281 1281 keep (l)ocal or take (o)ther? l
1282 1282 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1283 1283 (branch merge, don't forget to commit)
1284 1284 getting changed largefiles
1285 1285 1 largefiles updated, 0 removed
1286 1286 $ hg commit -m "Merge repos e and f"
1287 1287 Invoking status precommit hook
1288 1288 M normal3
1289 1289 M sub/normal4
1290 1290 M sub2/large6
1291 1291 $ cat normal3
1292 1292 normal3-modified
1293 1293 $ cat sub/normal4
1294 1294 normal4-modified
1295 1295 $ cat sub/large4
1296 1296 large4-merge-test
1297 1297 $ cat sub2/large6
1298 1298 large6-modified
1299 1299 $ cat sub2/large7
1300 1300 large7
1301 1301
1302 1302 Test status after merging with a branch that introduces a new largefile:
1303 1303
1304 1304 $ echo large > large
1305 1305 $ hg add --large large
1306 1306 $ hg commit -m 'add largefile'
1307 1307 Invoking status precommit hook
1308 1308 A large
1309 1309 $ hg update -q ".^"
1310 1310 $ echo change >> normal3
1311 1311 $ hg commit -m 'some change'
1312 1312 Invoking status precommit hook
1313 1313 M normal3
1314 1314 created new head
1315 1315 $ hg merge
1316 1316 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1317 1317 (branch merge, don't forget to commit)
1318 1318 getting changed largefiles
1319 1319 1 largefiles updated, 0 removed
1320 1320 $ hg status
1321 1321 M large
1322 1322
1323 1323 - make sure update of merge with removed largefiles fails as expected
1324 1324 $ hg rm sub2/large6
1325 1325 $ hg up -r.
1326 1326 abort: outstanding uncommitted merges
1327 1327 [255]
1328 1328
1329 1329 - revert should be able to revert files introduced in a pending merge
1330 1330 $ hg revert --all -r .
1331 1331 removing .hglf/large (glob)
1332 1332 undeleting .hglf/sub2/large6 (glob)
1333 1333
1334 1334 Test that a normal file and a largefile with the same name and path cannot
1335 1335 coexist.
1336 1336
1337 1337 $ rm sub2/large7
1338 1338 $ echo "largeasnormal" > sub2/large7
1339 1339 $ hg add sub2/large7
1340 1340 sub2/large7 already a largefile
1341 1341
1342 1342 Test that transplanting a largefile change works correctly.
1343 1343
1344 1344 $ cd ..
1345 1345 $ hg clone -r 8 d g
1346 1346 adding changesets
1347 1347 adding manifests
1348 1348 adding file changes
1349 1349 added 9 changesets with 26 changes to 10 files
1350 1350 updating to branch default
1351 1351 getting changed largefiles
1352 1352 3 largefiles updated, 0 removed
1353 1353 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1354 1354 $ cd g
1355 1355 $ hg transplant -s ../d 598410d3eb9a
1356 1356 searching for changes
1357 1357 searching for changes
1358 1358 adding changesets
1359 1359 adding manifests
1360 1360 adding file changes
1361 1361 added 1 changesets with 2 changes to 2 files
1362 1362 getting changed largefiles
1363 1363 1 largefiles updated, 0 removed
1364 1364 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1365 1365 9:598410d3eb9a modify normal file largefile in repo d
1366 1366 8:a381d2c8c80e modify normal file and largefile in repo b
1367 1367 7:daea875e9014 add/edit more largefiles
1368 1368 6:4355d653f84f edit files yet again
1369 1369 5:9d5af5072dbd edit files again
1370 1370 4:74c02385b94c move files
1371 1371 3:9e8fbc4bce62 copy files
1372 1372 2:51a0ae4d5864 remove files
1373 1373 1:ce8896473775 edit files
1374 1374 0:30d30fe6a5be add files
1375 1375 $ cat normal3
1376 1376 normal3-modified
1377 1377 $ cat sub/normal4
1378 1378 normal4-modified
1379 1379 $ cat sub/large4
1380 1380 large4-modified
1381 1381 $ cat sub2/large6
1382 1382 large6-modified
1383 1383 $ cat sub2/large7
1384 1384 large7
1385 1385
1386 1386 Cat a largefile
1387 1387 $ hg cat normal3
1388 1388 normal3-modified
1389 1389 $ hg cat sub/large4
1390 1390 large4-modified
1391 1391 $ rm "${USERCACHE}"/*
1392 1392 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1393 1393 $ cat cat.out
1394 1394 large4-modified
1395 1395 $ rm cat.out
1396 1396 $ hg cat -r a381d2c8c80e normal3
1397 1397 normal3-modified
1398 1398 $ hg cat -r '.^' normal3
1399 1399 normal3-modified
1400 1400 $ hg cat -r '.^' sub/large4 doesntexist
1401 1401 large4-modified
1402 1402 doesntexist: no such file in rev a381d2c8c80e
1403 1403 [1]
1404 1404
1405 1405 Test that renaming a largefile results in correct output for status
1406 1406
1407 1407 $ hg rename sub/large4 large4-renamed
1408 1408 $ hg commit -m "test rename output"
1409 1409 Invoking status precommit hook
1410 1410 A large4-renamed
1411 1411 R sub/large4
1412 1412 $ cat large4-renamed
1413 1413 large4-modified
1414 1414 $ cd sub2
1415 1415 $ hg rename large6 large6-renamed
1416 1416 $ hg st
1417 1417 A sub2/large6-renamed
1418 1418 R sub2/large6
1419 1419 $ cd ..
1420 1420
1421 1421 Test --normal flag
1422 1422
1423 1423 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1424 1424 $ hg add --normal --large new-largefile
1425 1425 abort: --normal cannot be used with --large
1426 1426 [255]
1427 1427 $ hg add --normal new-largefile
1428 1428 new-largefile: up to 69 MB of RAM may be required to manage this file
1429 1429 (use 'hg revert new-largefile' to cancel the pending addition)
1430 1430 $ cd ..
1431 1431
1432 1432 #if serve
1433 1433 vanilla clients not locked out from largefiles servers on vanilla repos
1434 1434 $ mkdir r1
1435 1435 $ cd r1
1436 1436 $ hg init
1437 1437 $ echo c1 > f1
1438 1438 $ hg add f1
1439 1439 $ hg commit -m "m1"
1440 1440 Invoking status precommit hook
1441 1441 A f1
1442 1442 $ cd ..
1443 1443 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1444 1444 $ cat hg.pid >> $DAEMON_PIDS
1445 1445 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1446 1446 requesting all changes
1447 1447 adding changesets
1448 1448 adding manifests
1449 1449 adding file changes
1450 1450 added 1 changesets with 1 changes to 1 files
1451 1451 updating to branch default
1452 1452 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1453 1453
1454 1454 largefiles clients still work with vanilla servers
1455 1455 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1456 1456 $ cat hg.pid >> $DAEMON_PIDS
1457 1457 $ hg clone http://localhost:$HGPORT1 r3
1458 1458 requesting all changes
1459 1459 adding changesets
1460 1460 adding manifests
1461 1461 adding file changes
1462 1462 added 1 changesets with 1 changes to 1 files
1463 1463 updating to branch default
1464 1464 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1465 1465 #endif
1466 1466
1467 1467
1468 1468 vanilla clients locked out from largefiles http repos
1469 1469 $ mkdir r4
1470 1470 $ cd r4
1471 1471 $ hg init
1472 1472 $ echo c1 > f1
1473 1473 $ hg add --large f1
1474 1474 $ hg commit -m "m1"
1475 1475 Invoking status precommit hook
1476 1476 A f1
1477 1477 $ cd ..
1478 1478
1479 1479 largefiles can be pushed locally (issue3583)
1480 1480 $ hg init dest
1481 1481 $ cd r4
1482 1482 $ hg outgoing ../dest
1483 1483 comparing with ../dest
1484 1484 searching for changes
1485 1485 changeset: 0:639881c12b4c
1486 1486 tag: tip
1487 1487 user: test
1488 1488 date: Thu Jan 01 00:00:00 1970 +0000
1489 1489 summary: m1
1490 1490
1491 1491 $ hg push ../dest
1492 1492 pushing to ../dest
1493 1493 searching for changes
1494 1494 searching for changes
1495 1495 adding changesets
1496 1496 adding manifests
1497 1497 adding file changes
1498 1498 added 1 changesets with 1 changes to 1 files
1499 1499
1500 1500 exit code with nothing outgoing (issue3611)
1501 1501 $ hg outgoing ../dest
1502 1502 comparing with ../dest
1503 1503 searching for changes
1504 1504 no changes found
1505 1505 [1]
1506 1506 $ cd ..
1507 1507
1508 1508 #if serve
1509 1509 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1510 1510 $ cat hg.pid >> $DAEMON_PIDS
1511 1511 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1512 1512 abort: remote error:
1513 1513
1514 1514 This repository uses the largefiles extension.
1515 1515
1516 1516 Please enable it in your Mercurial config file.
1517 1517 [255]
1518 1518
1519 1519 used all HGPORTs, kill all daemons
1520 1520 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1521 1521 #endif
1522 1522
1523 1523 vanilla clients locked out from largefiles ssh repos
1524 1524 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1525 1525 abort: remote error:
1526 1526
1527 1527 This repository uses the largefiles extension.
1528 1528
1529 1529 Please enable it in your Mercurial config file.
1530 1530 [255]
1531 1531
1532 1532 #if serve
1533 1533
1534 1534 largefiles clients refuse to push largefiles repos to vanilla servers
1535 1535 $ mkdir r6
1536 1536 $ cd r6
1537 1537 $ hg init
1538 1538 $ echo c1 > f1
1539 1539 $ hg add f1
1540 1540 $ hg commit -m "m1"
1541 1541 Invoking status precommit hook
1542 1542 A f1
1543 1543 $ cat >> .hg/hgrc <<!
1544 1544 > [web]
1545 1545 > push_ssl = false
1546 1546 > allow_push = *
1547 1547 > !
1548 1548 $ cd ..
1549 1549 $ hg clone r6 r7
1550 1550 updating to branch default
1551 1551 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1552 1552 $ cd r7
1553 1553 $ echo c2 > f2
1554 1554 $ hg add --large f2
1555 1555 $ hg commit -m "m2"
1556 1556 Invoking status precommit hook
1557 1557 A f2
1558 1558 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1559 1559 $ cat ../hg.pid >> $DAEMON_PIDS
1560 1560 $ hg push http://localhost:$HGPORT
1561 1561 pushing to http://localhost:$HGPORT/
1562 1562 searching for changes
1563 1563 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1564 1564 [255]
1565 1565 $ cd ..
1566 1566
1567 1567 putlfile errors are shown (issue3123)
1568 1568 Corrupt the cached largefile in r7 and move it out of the servers usercache
1569 1569 $ mv r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 .
1570 1570 $ echo 'client side corruption' > r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8
1571 1571 $ rm "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1572 1572 $ hg init empty
1573 1573 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1574 1574 > --config 'web.allow_push=*' --config web.push_ssl=False
1575 1575 $ cat hg.pid >> $DAEMON_PIDS
1576 1576 $ hg push -R r7 http://localhost:$HGPORT1
1577 1577 pushing to http://localhost:$HGPORT1/
1578 1578 searching for changes
1579 1579 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1580 1580 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1581 1581 [255]
1582 1582 $ mv 4cdac4d8b084d0b599525cf732437fb337d422a8 r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8
1583 1583 Push of file that exists on server but is corrupted - magic healing would be nice ... but too magic
1584 1584 $ echo "server side corruption" > empty/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8
1585 1585 $ hg push -R r7 http://localhost:$HGPORT1
1586 1586 pushing to http://localhost:$HGPORT1/
1587 1587 searching for changes
1588 1588 searching for changes
1589 1589 remote: adding changesets
1590 1590 remote: adding manifests
1591 1591 remote: adding file changes
1592 1592 remote: added 2 changesets with 2 changes to 2 files
1593 1593 $ cat empty/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8
1594 1594 server side corruption
1595 1595 $ rm -rf empty
1596 1596
1597 1597 Push a largefiles repository to a served empty repository
1598 1598 $ hg init r8
1599 1599 $ echo c3 > r8/f1
1600 1600 $ hg add --large r8/f1 -R r8
1601 1601 $ hg commit -m "m1" -R r8
1602 1602 Invoking status precommit hook
1603 1603 A f1
1604 1604 $ hg init empty
1605 1605 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1606 1606 > --config 'web.allow_push=*' --config web.push_ssl=False
1607 1607 $ cat hg.pid >> $DAEMON_PIDS
1608 1608 $ rm "${USERCACHE}"/*
1609 1609 $ hg push -R r8 http://localhost:$HGPORT2/#default
1610 1610 pushing to http://localhost:$HGPORT2/
1611 1611 searching for changes
1612 1612 searching for changes
1613 1613 remote: adding changesets
1614 1614 remote: adding manifests
1615 1615 remote: adding file changes
1616 1616 remote: added 1 changesets with 1 changes to 1 files
1617 1617 $ [ -f "${USERCACHE}"/02a439e5c31c526465ab1a0ca1f431f76b827b90 ]
1618 1618 $ [ -f empty/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90 ]
1619 1619
1620 1620 Clone over http, no largefiles pulled on clone.
1621 1621
1622 1622 $ hg clone http://localhost:$HGPORT2/#default http-clone -U
1623 1623 adding changesets
1624 1624 adding manifests
1625 1625 adding file changes
1626 1626 added 1 changesets with 1 changes to 1 files
1627 1627
1628 1628 test 'verify' with remotestore:
1629 1629
1630 1630 $ rm "${USERCACHE}"/02a439e5c31c526465ab1a0ca1f431f76b827b90
1631 1631 $ mv empty/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90 .
1632 1632 $ hg -R http-clone verify --large --lfa
1633 1633 checking changesets
1634 1634 checking manifests
1635 1635 crosschecking files in changesets and manifests
1636 1636 checking files
1637 1637 1 files, 1 changesets, 1 total revisions
1638 1638 searching 1 changesets for largefiles
1639 1639 changeset 0:cf03e5bb9936: f1 missing
1640 1640 verified existence of 1 revisions of 1 largefiles
1641 1641 [1]
1642 1642 $ mv 02a439e5c31c526465ab1a0ca1f431f76b827b90 empty/.hg/largefiles/
1643 1643 $ hg -R http-clone -q verify --large --lfa
1644 1644
1645 1645 largefiles pulled on update - a largefile missing on the server:
1646 1646 $ mv empty/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90 .
1647 1647 $ hg -R http-clone up --config largefiles.usercache=http-clone-usercache
1648 1648 getting changed largefiles
1649 1649 abort: remotestore: largefile 02a439e5c31c526465ab1a0ca1f431f76b827b90 is missing
1650 1650 [255]
1651 1651 $ hg -R http-clone up -Cqr null
1652 1652
1653 1653 largefiles pulled on update - a largefile corrupted on the server:
1654 1654 $ echo corruption > empty/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90
1655 1655 $ hg -R http-clone up --config largefiles.usercache=http-clone-usercache
1656 1656 getting changed largefiles
1657 1657 f1: data corruption (expected 02a439e5c31c526465ab1a0ca1f431f76b827b90, got 6a7bb2556144babe3899b25e5428123735bb1e27)
1658 1658 0 largefiles updated, 0 removed
1659 1659 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1660 1660 $ hg -R http-clone st
1661 1661 ! f1
1662 1662 $ [ ! -f http-clone/.hg/largefiles/02a439e5c31c526465ab1a0ca1f431f76b827b90 ]
1663 1663 $ [ ! -f http-clone/f1 ]
1664 1664 $ [ ! -f http-clone-usercache ]
1665 1665 $ hg -R http-clone verify --large --lfc
1666 1666 checking changesets
1667 1667 checking manifests
1668 1668 crosschecking files in changesets and manifests
1669 1669 checking files
1670 1670 1 files, 1 changesets, 1 total revisions
1671 1671 searching 1 changesets for largefiles
1672 1672 verified contents of 1 revisions of 1 largefiles
1673 1673 $ hg -R http-clone up -Cqr null
1674 1674
1675 1675 largefiles pulled on update - no server side problems:
1676 1676 $ mv 02a439e5c31c526465ab1a0ca1f431f76b827b90 empty/.hg/largefiles/
1677 1677 $ hg -R http-clone --debug up --config largefiles.usercache=http-clone-usercache
1678 1678 resolving manifests
1679 overwrite: False, partial: False
1679 branchmerge: False, force: False, partial: False
1680 1680 ancestor: 000000000000, local: 000000000000+, remote: cf03e5bb9936
1681 1681 .hglf/f1: remote created -> g
1682 1682 updating: .hglf/f1 1/1 files (100.00%)
1683 1683 getting .hglf/f1
1684 1684 getting changed largefiles
1685 1685 using http://localhost:$HGPORT2/
1686 1686 sending capabilities command
1687 1687 getting largefiles: 0/1 lfile (0.00%)
1688 1688 getting f1:02a439e5c31c526465ab1a0ca1f431f76b827b90
1689 1689 sending batch command
1690 1690 sending getlfile command
1691 1691 found 02a439e5c31c526465ab1a0ca1f431f76b827b90 in store
1692 1692 1 largefiles updated, 0 removed
1693 1693 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1694 1694
1695 1695 $ ls http-clone-usercache/*
1696 1696 http-clone-usercache/02a439e5c31c526465ab1a0ca1f431f76b827b90
1697 1697
1698 1698 $ rm -rf empty http-clone*
1699 1699
1700 1700 used all HGPORTs, kill all daemons
1701 1701 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
1702 1702
1703 1703 #endif
1704 1704
1705 1705
1706 1706 #if unix-permissions
1707 1707
1708 1708 Clone a local repository owned by another user
1709 1709 We have to simulate that here by setting $HOME and removing write permissions
1710 1710 $ ORIGHOME="$HOME"
1711 1711 $ mkdir alice
1712 1712 $ HOME="`pwd`/alice"
1713 1713 $ cd alice
1714 1714 $ hg init pubrepo
1715 1715 $ cd pubrepo
1716 1716 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1717 1717 $ hg add --large a-large-file
1718 1718 $ hg commit -m "Add a large file"
1719 1719 Invoking status precommit hook
1720 1720 A a-large-file
1721 1721 $ cd ..
1722 1722 $ chmod -R a-w pubrepo
1723 1723 $ cd ..
1724 1724 $ mkdir bob
1725 1725 $ HOME="`pwd`/bob"
1726 1726 $ cd bob
1727 1727 $ hg clone --pull ../alice/pubrepo pubrepo
1728 1728 requesting all changes
1729 1729 adding changesets
1730 1730 adding manifests
1731 1731 adding file changes
1732 1732 added 1 changesets with 1 changes to 1 files
1733 1733 updating to branch default
1734 1734 getting changed largefiles
1735 1735 1 largefiles updated, 0 removed
1736 1736 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1737 1737 $ cd ..
1738 1738 $ chmod -R u+w alice/pubrepo
1739 1739 $ HOME="$ORIGHOME"
1740 1740
1741 1741 #endif
1742 1742
1743 1743 #if symlink
1744 1744
1745 1745 Symlink to a large largefile should behave the same as a symlink to a normal file
1746 1746 $ hg init largesymlink
1747 1747 $ cd largesymlink
1748 1748 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1749 1749 $ hg add --large largefile
1750 1750 $ hg commit -m "commit a large file"
1751 1751 Invoking status precommit hook
1752 1752 A largefile
1753 1753 $ ln -s largefile largelink
1754 1754 $ hg add largelink
1755 1755 $ hg commit -m "commit a large symlink"
1756 1756 Invoking status precommit hook
1757 1757 A largelink
1758 1758 $ rm -f largelink
1759 1759 $ hg up >/dev/null
1760 1760 $ test -f largelink
1761 1761 [1]
1762 1762 $ test -L largelink
1763 1763 [1]
1764 1764 $ rm -f largelink # make next part of the test independent of the previous
1765 1765 $ hg up -C >/dev/null
1766 1766 $ test -f largelink
1767 1767 $ test -L largelink
1768 1768 $ cd ..
1769 1769
1770 1770 #endif
1771 1771
1772 1772 test for pattern matching on 'hg status':
1773 1773 to boost performance, largefiles checks whether specified patterns are
1774 1774 related to largefiles in working directory (NOT to STANDIN) or not.
1775 1775
1776 1776 $ hg init statusmatch
1777 1777 $ cd statusmatch
1778 1778
1779 1779 $ mkdir -p a/b/c/d
1780 1780 $ echo normal > a/b/c/d/e.normal.txt
1781 1781 $ hg add a/b/c/d/e.normal.txt
1782 1782 $ echo large > a/b/c/d/e.large.txt
1783 1783 $ hg add --large a/b/c/d/e.large.txt
1784 1784 $ mkdir -p a/b/c/x
1785 1785 $ echo normal > a/b/c/x/y.normal.txt
1786 1786 $ hg add a/b/c/x/y.normal.txt
1787 1787 $ hg commit -m 'add files'
1788 1788 Invoking status precommit hook
1789 1789 A a/b/c/d/e.large.txt
1790 1790 A a/b/c/d/e.normal.txt
1791 1791 A a/b/c/x/y.normal.txt
1792 1792
1793 1793 (1) no pattern: no performance boost
1794 1794 $ hg status -A
1795 1795 C a/b/c/d/e.large.txt
1796 1796 C a/b/c/d/e.normal.txt
1797 1797 C a/b/c/x/y.normal.txt
1798 1798
1799 1799 (2) pattern not related to largefiles: performance boost
1800 1800 $ hg status -A a/b/c/x
1801 1801 C a/b/c/x/y.normal.txt
1802 1802
1803 1803 (3) pattern related to largefiles: no performance boost
1804 1804 $ hg status -A a/b/c/d
1805 1805 C a/b/c/d/e.large.txt
1806 1806 C a/b/c/d/e.normal.txt
1807 1807
1808 1808 (4) pattern related to STANDIN (not to largefiles): performance boost
1809 1809 $ hg status -A .hglf/a
1810 1810 C .hglf/a/b/c/d/e.large.txt
1811 1811
1812 1812 (5) mixed case: no performance boost
1813 1813 $ hg status -A a/b/c/x a/b/c/d
1814 1814 C a/b/c/d/e.large.txt
1815 1815 C a/b/c/d/e.normal.txt
1816 1816 C a/b/c/x/y.normal.txt
1817 1817
1818 1818 verify that largefiles doesn't break filesets
1819 1819
1820 1820 $ hg log --rev . --exclude "set:binary()"
1821 1821 changeset: 0:41bd42f10efa
1822 1822 tag: tip
1823 1823 user: test
1824 1824 date: Thu Jan 01 00:00:00 1970 +0000
1825 1825 summary: add files
1826 1826
1827 1827 verify that large files in subrepos handled properly
1828 1828 $ hg init subrepo
1829 1829 $ echo "subrepo = subrepo" > .hgsub
1830 1830 $ hg add .hgsub
1831 1831 $ hg ci -m "add subrepo"
1832 1832 Invoking status precommit hook
1833 1833 A .hgsub
1834 1834 ? .hgsubstate
1835 1835 $ echo "rev 1" > subrepo/large.txt
1836 1836 $ hg -R subrepo add --large subrepo/large.txt
1837 1837 $ hg sum
1838 1838 parent: 1:8ee150ea2e9c tip
1839 1839 add subrepo
1840 1840 branch: default
1841 1841 commit: 1 subrepos
1842 1842 update: (current)
1843 1843 $ hg st
1844 1844 $ hg st -S
1845 1845 A subrepo/large.txt
1846 1846 $ hg ci -S -m "commit top repo"
1847 1847 committing subrepository subrepo
1848 1848 Invoking status precommit hook
1849 1849 A large.txt
1850 1850 Invoking status precommit hook
1851 1851 M .hgsubstate
1852 1852 # No differences
1853 1853 $ hg st -S
1854 1854 $ hg sum
1855 1855 parent: 2:ce4cd0c527a6 tip
1856 1856 commit top repo
1857 1857 branch: default
1858 1858 commit: (clean)
1859 1859 update: (current)
1860 1860 $ echo "rev 2" > subrepo/large.txt
1861 1861 $ hg st -S
1862 1862 M subrepo/large.txt
1863 1863 $ hg sum
1864 1864 parent: 2:ce4cd0c527a6 tip
1865 1865 commit top repo
1866 1866 branch: default
1867 1867 commit: 1 subrepos
1868 1868 update: (current)
1869 1869 $ hg ci -m "this commit should fail without -S"
1870 1870 abort: uncommitted changes in subrepo subrepo
1871 1871 (use --subrepos for recursive commit)
1872 1872 [255]
1873 1873
1874 1874 Add a normal file to the subrepo, then test archiving
1875 1875
1876 1876 $ echo 'normal file' > subrepo/normal.txt
1877 1877 $ hg -R subrepo add subrepo/normal.txt
1878 1878
1879 1879 Lock in subrepo, otherwise the change isn't archived
1880 1880
1881 1881 $ hg ci -S -m "add normal file to top level"
1882 1882 committing subrepository subrepo
1883 1883 Invoking status precommit hook
1884 1884 M large.txt
1885 1885 A normal.txt
1886 1886 Invoking status precommit hook
1887 1887 M .hgsubstate
1888 1888 $ hg archive -S ../lf_subrepo_archive
1889 1889 $ find ../lf_subrepo_archive | sort
1890 1890 ../lf_subrepo_archive
1891 1891 ../lf_subrepo_archive/.hg_archival.txt
1892 1892 ../lf_subrepo_archive/.hgsub
1893 1893 ../lf_subrepo_archive/.hgsubstate
1894 1894 ../lf_subrepo_archive/a
1895 1895 ../lf_subrepo_archive/a/b
1896 1896 ../lf_subrepo_archive/a/b/c
1897 1897 ../lf_subrepo_archive/a/b/c/d
1898 1898 ../lf_subrepo_archive/a/b/c/d/e.large.txt
1899 1899 ../lf_subrepo_archive/a/b/c/d/e.normal.txt
1900 1900 ../lf_subrepo_archive/a/b/c/x
1901 1901 ../lf_subrepo_archive/a/b/c/x/y.normal.txt
1902 1902 ../lf_subrepo_archive/subrepo
1903 1903 ../lf_subrepo_archive/subrepo/large.txt
1904 1904 ../lf_subrepo_archive/subrepo/normal.txt
1905 1905
1906 1906 Test update with subrepos.
1907 1907
1908 1908 $ hg update 0
1909 1909 getting changed largefiles
1910 1910 0 largefiles updated, 1 removed
1911 1911 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1912 1912 $ hg status -S
1913 1913 $ hg update tip
1914 1914 getting changed largefiles
1915 1915 1 largefiles updated, 0 removed
1916 1916 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1917 1917 $ hg status -S
1918 1918 # modify a large file
1919 1919 $ echo "modified" > subrepo/large.txt
1920 1920 $ hg st -S
1921 1921 M subrepo/large.txt
1922 1922 # update -C should revert the change.
1923 1923 $ hg update -C
1924 1924 getting changed largefiles
1925 1925 1 largefiles updated, 0 removed
1926 1926 getting changed largefiles
1927 1927 0 largefiles updated, 0 removed
1928 1928 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1929 1929 $ hg status -S
1930 1930
1931 1931 Test archiving a revision that references a subrepo that is not yet
1932 1932 cloned (see test-subrepo-recursion.t):
1933 1933
1934 1934 $ hg clone -U . ../empty
1935 1935 $ cd ../empty
1936 1936 $ hg archive --subrepos -r tip ../archive.tar.gz
1937 1937 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
1938 1938 $ cd ..
1939 1939
1940 1940 Test that addremove picks up largefiles prior to the initial commit (issue3541)
1941 1941
1942 1942 $ hg init addrm2
1943 1943 $ cd addrm2
1944 1944 $ touch large.dat
1945 1945 $ touch large2.dat
1946 1946 $ touch normal
1947 1947 $ hg add --large large.dat
1948 1948 $ hg addremove -v
1949 1949 adding large2.dat as a largefile
1950 1950 adding normal
1951 1951
1952 1952 Test that forgetting all largefiles reverts to islfilesrepo() == False
1953 1953 (addremove will add *.dat as normal files now)
1954 1954 $ hg forget large.dat
1955 1955 $ hg forget large2.dat
1956 1956 $ hg addremove -v
1957 1957 adding large.dat
1958 1958 adding large2.dat
1959 1959
1960 1960 Test commit's addremove option prior to the first commit
1961 1961 $ hg forget large.dat
1962 1962 $ hg forget large2.dat
1963 1963 $ hg add --large large.dat
1964 1964 $ hg ci -Am "commit"
1965 1965 adding large2.dat as a largefile
1966 1966 Invoking status precommit hook
1967 1967 A large.dat
1968 1968 A large2.dat
1969 1969 A normal
1970 1970 $ find .hglf | sort
1971 1971 .hglf
1972 1972 .hglf/large.dat
1973 1973 .hglf/large2.dat
1974 1974
1975 1975 Test actions on largefiles using relative paths from subdir
1976 1976
1977 1977 $ mkdir sub
1978 1978 $ cd sub
1979 1979 $ echo anotherlarge > anotherlarge
1980 1980 $ hg add --large anotherlarge
1981 1981 $ hg st
1982 1982 A sub/anotherlarge
1983 1983 $ hg st anotherlarge
1984 1984 A anotherlarge
1985 1985 $ hg commit -m anotherlarge anotherlarge
1986 1986 Invoking status precommit hook
1987 1987 A sub/anotherlarge
1988 1988 $ hg log anotherlarge
1989 1989 changeset: 1:9627a577c5e9
1990 1990 tag: tip
1991 1991 user: test
1992 1992 date: Thu Jan 01 00:00:00 1970 +0000
1993 1993 summary: anotherlarge
1994 1994
1995 1995 $ echo more >> anotherlarge
1996 1996 $ hg st .
1997 1997 M anotherlarge
1998 1998 $ hg cat anotherlarge
1999 1999 anotherlarge
2000 2000 $ hg revert anotherlarge
2001 2001 $ hg st
2002 2002 ? sub/anotherlarge.orig
2003 2003 $ cd ..
2004 2004
2005 2005 $ cd ..
2006 2006
2007 2007 issue3651: summary/outgoing with largefiles shows "no remote repo"
2008 2008 unexpectedly
2009 2009
2010 2010 $ mkdir issue3651
2011 2011 $ cd issue3651
2012 2012
2013 2013 $ hg init src
2014 2014 $ echo a > src/a
2015 2015 $ hg -R src add --large src/a
2016 2016 $ hg -R src commit -m '#0'
2017 2017 Invoking status precommit hook
2018 2018 A a
2019 2019
2020 2020 check messages when no remote repository is specified:
2021 2021 "no remote repo" route for "hg outgoing --large" is not tested here,
2022 2022 because it can't be reproduced easily.
2023 2023
2024 2024 $ hg init clone1
2025 2025 $ hg -R clone1 -q pull src
2026 2026 $ hg -R clone1 -q update
2027 2027 $ hg -R clone1 paths | grep default
2028 2028 [1]
2029 2029
2030 2030 $ hg -R clone1 summary --large
2031 2031 parent: 0:fc0bd45326d3 tip
2032 2032 #0
2033 2033 branch: default
2034 2034 commit: (clean)
2035 2035 update: (current)
2036 2036 largefiles: (no remote repo)
2037 2037
2038 2038 check messages when there is no files to upload:
2039 2039
2040 2040 $ hg -q clone src clone2
2041 2041 $ hg -R clone2 paths | grep default
2042 2042 default = $TESTTMP/issue3651/src (glob)
2043 2043
2044 2044 $ hg -R clone2 summary --large
2045 2045 parent: 0:fc0bd45326d3 tip
2046 2046 #0
2047 2047 branch: default
2048 2048 commit: (clean)
2049 2049 update: (current)
2050 2050 searching for changes
2051 2051 largefiles: (no files to upload)
2052 2052 $ hg -R clone2 outgoing --large
2053 2053 comparing with $TESTTMP/issue3651/src (glob)
2054 2054 searching for changes
2055 2055 no changes found
2056 2056 searching for changes
2057 2057 largefiles: no files to upload
2058 2058 [1]
2059 2059
2060 2060 check messages when there are files to upload:
2061 2061
2062 2062 $ echo b > clone2/b
2063 2063 $ hg -R clone2 add --large clone2/b
2064 2064 $ hg -R clone2 commit -m '#1'
2065 2065 Invoking status precommit hook
2066 2066 A b
2067 2067 $ hg -R clone2 summary --large
2068 2068 parent: 1:1acbe71ce432 tip
2069 2069 #1
2070 2070 branch: default
2071 2071 commit: (clean)
2072 2072 update: (current)
2073 2073 searching for changes
2074 2074 largefiles: 1 to upload
2075 2075 $ hg -R clone2 outgoing --large
2076 2076 comparing with $TESTTMP/issue3651/src (glob)
2077 2077 searching for changes
2078 2078 changeset: 1:1acbe71ce432
2079 2079 tag: tip
2080 2080 user: test
2081 2081 date: Thu Jan 01 00:00:00 1970 +0000
2082 2082 summary: #1
2083 2083
2084 2084 searching for changes
2085 2085 largefiles to upload:
2086 2086 b
2087 2087
2088 2088
2089 2089 $ cd ..
@@ -1,184 +1,184 b''
1 1 Check that renames are correctly saved by a commit after a merge
2 2
3 3 Test with the merge on 3 having the rename on the local parent
4 4
5 5 $ hg init a
6 6 $ cd a
7 7
8 8 $ echo line1 > foo
9 9 $ hg add foo
10 10 $ hg ci -m '0: add foo'
11 11
12 12 $ echo line2 >> foo
13 13 $ hg ci -m '1: change foo'
14 14
15 15 $ hg up -C 0
16 16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 17
18 18 $ hg mv foo bar
19 19 $ rm bar
20 20 $ echo line0 > bar
21 21 $ echo line1 >> bar
22 22 $ hg ci -m '2: mv foo bar; change bar'
23 23 created new head
24 24
25 25 $ hg merge 1
26 26 merging bar and foo to bar
27 27 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
28 28 (branch merge, don't forget to commit)
29 29
30 30 $ cat bar
31 31 line0
32 32 line1
33 33 line2
34 34
35 35 $ hg ci -m '3: merge with local rename'
36 36
37 37 $ hg debugindex bar
38 38 rev offset length ..... linkrev nodeid p1 p2 (re)
39 39 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
40 40 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
41 41
42 42 $ hg debugrename bar
43 43 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
44 44
45 45 $ hg debugindex foo
46 46 rev offset length ..... linkrev nodeid p1 p2 (re)
47 47 0 0 7 ..... 0 690b295714ae 000000000000 000000000000 (re)
48 48 1 7 13 ..... 1 9e25c27b8757 690b295714ae 000000000000 (re)
49 49
50 50
51 51 Revert the content change from rev 2:
52 52
53 53 $ hg up -C 2
54 54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 55 $ rm bar
56 56 $ echo line1 > bar
57 57 $ hg ci -m '4: revert content change from rev 2'
58 58 created new head
59 59
60 60 $ hg log --template '{rev}:{node|short} {parents}\n'
61 61 4:2263c1be0967 2:0f2ff26688b9
62 62 3:0555950ead28 2:0f2ff26688b9 1:5cd961e4045d
63 63 2:0f2ff26688b9 0:2665aaee66e9
64 64 1:5cd961e4045d
65 65 0:2665aaee66e9
66 66
67 67 This should use bar@rev2 as the ancestor:
68 68
69 69 $ hg --debug merge 3
70 70 searching for copies back to rev 1
71 71 resolving manifests
72 overwrite: False, partial: False
72 branchmerge: True, force: False, partial: False
73 73 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 0555950ead28
74 74 bar: versions differ -> m
75 75 preserving bar for resolve of bar
76 76 updating: bar 1/1 files (100.00%)
77 77 picked tool 'internal:merge' for bar (binary False symlink False)
78 78 merging bar
79 79 my bar@2263c1be0967+ other bar@0555950ead28 ancestor bar@0f2ff26688b9
80 80 premerge successful
81 81 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
82 82 (branch merge, don't forget to commit)
83 83
84 84 $ cat bar
85 85 line1
86 86 line2
87 87
88 88 $ hg ci -m '5: merge'
89 89
90 90 $ hg debugindex bar
91 91 rev offset length ..... linkrev nodeid p1 p2 (re)
92 92 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
93 93 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
94 94 2 153 7 ..... 4 ff4b45017382 d35118874825 000000000000 (re)
95 95 3 160 13 ..... 5 3701b4893544 ff4b45017382 5345f5ab8abd (re)
96 96
97 97
98 98 Same thing, but with the merge on 3 having the rename
99 99 on the remote parent:
100 100
101 101 $ cd ..
102 102 $ hg clone -U -r 1 -r 2 a b
103 103 adding changesets
104 104 adding manifests
105 105 adding file changes
106 106 added 3 changesets with 3 changes to 2 files (+1 heads)
107 107 $ cd b
108 108
109 109 $ hg up -C 1
110 110 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 111
112 112 $ hg merge 2
113 113 merging foo and bar to bar
114 114 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
115 115 (branch merge, don't forget to commit)
116 116
117 117 $ cat bar
118 118 line0
119 119 line1
120 120 line2
121 121
122 122 $ hg ci -m '3: merge with remote rename'
123 123
124 124 $ hg debugindex bar
125 125 rev offset length ..... linkrev nodeid p1 p2 (re)
126 126 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
127 127 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
128 128
129 129 $ hg debugrename bar
130 130 bar renamed from foo:9e25c27b87571a1edee5ae4dddee5687746cc8e2
131 131
132 132 $ hg debugindex foo
133 133 rev offset length ..... linkrev nodeid p1 p2 (re)
134 134 0 0 7 ..... 0 690b295714ae 000000000000 000000000000 (re)
135 135 1 7 13 ..... 1 9e25c27b8757 690b295714ae 000000000000 (re)
136 136
137 137
138 138 Revert the content change from rev 2:
139 139
140 140 $ hg up -C 2
141 141 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 142 $ rm bar
143 143 $ echo line1 > bar
144 144 $ hg ci -m '4: revert content change from rev 2'
145 145 created new head
146 146
147 147 $ hg log --template '{rev}:{node|short} {parents}\n'
148 148 4:2263c1be0967 2:0f2ff26688b9
149 149 3:3ffa6b9e35f0 1:5cd961e4045d 2:0f2ff26688b9
150 150 2:0f2ff26688b9 0:2665aaee66e9
151 151 1:5cd961e4045d
152 152 0:2665aaee66e9
153 153
154 154 This should use bar@rev2 as the ancestor:
155 155
156 156 $ hg --debug merge 3
157 157 searching for copies back to rev 1
158 158 resolving manifests
159 overwrite: False, partial: False
159 branchmerge: True, force: False, partial: False
160 160 ancestor: 0f2ff26688b9, local: 2263c1be0967+, remote: 3ffa6b9e35f0
161 161 bar: versions differ -> m
162 162 preserving bar for resolve of bar
163 163 updating: bar 1/1 files (100.00%)
164 164 picked tool 'internal:merge' for bar (binary False symlink False)
165 165 merging bar
166 166 my bar@2263c1be0967+ other bar@3ffa6b9e35f0 ancestor bar@0f2ff26688b9
167 167 premerge successful
168 168 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
169 169 (branch merge, don't forget to commit)
170 170
171 171 $ cat bar
172 172 line1
173 173 line2
174 174
175 175 $ hg ci -m '5: merge'
176 176
177 177 $ hg debugindex bar
178 178 rev offset length ..... linkrev nodeid p1 p2 (re)
179 179 0 0 77 ..... 2 d35118874825 000000000000 000000000000 (re)
180 180 1 77 76 ..... 3 5345f5ab8abd 000000000000 d35118874825 (re)
181 181 2 153 7 ..... 4 ff4b45017382 d35118874825 000000000000 (re)
182 182 3 160 13 ..... 5 3701b4893544 ff4b45017382 5345f5ab8abd (re)
183 183
184 184 $ cd ..
@@ -1,376 +1,376 b''
1 1 $ "$TESTDIR/hghave" symlink execbit || exit 80
2 2
3 3 $ tellmeabout() {
4 4 > if [ -h $1 ]; then
5 5 > echo $1 is a symlink:
6 6 > $TESTDIR/readlink.py $1
7 7 > elif [ -x $1 ]; then
8 8 > echo $1 is an executable file with content:
9 9 > cat $1
10 10 > else
11 11 > echo $1 is a plain file with content:
12 12 > cat $1
13 13 > fi
14 14 > }
15 15
16 16 $ hg init test1
17 17 $ cd test1
18 18
19 19 $ echo a > a
20 20 $ hg ci -Aqmadd
21 21 $ chmod +x a
22 22 $ hg ci -mexecutable
23 23
24 24 $ hg up -q 0
25 25 $ rm a
26 26 $ ln -s symlink a
27 27 $ hg ci -msymlink
28 28 created new head
29 29
30 30 Symlink is local parent, executable is other:
31 31
32 32 $ hg merge --debug
33 33 searching for copies back to rev 1
34 34 resolving manifests
35 overwrite: False, partial: False
35 branchmerge: True, force: False, partial: False
36 36 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
37 37 a: versions differ -> m
38 38 preserving a for resolve of a
39 39 updating: a 1/1 files (100.00%)
40 40 picked tool 'internal:merge' for a (binary False symlink True)
41 41 merging a
42 42 my a@521a1e40188f+ other a@3574f3e69b1c ancestor a@c334dc3be0da
43 43 warning: internal:merge cannot merge symlinks for a
44 44 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
45 45 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
46 46 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
47 47 [1]
48 48
49 49 $ tellmeabout a
50 50 a is a symlink:
51 51 a -> symlink
52 52 $ hg resolve a --tool internal:other
53 53 $ tellmeabout a
54 54 a is an executable file with content:
55 55 a
56 56 $ hg st
57 57 M a
58 58 ? a.orig
59 59
60 60 Symlink is other parent, executable is local:
61 61
62 62 $ hg update -C 1
63 63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 64
65 65 $ hg merge --debug
66 66 searching for copies back to rev 1
67 67 resolving manifests
68 overwrite: False, partial: False
68 branchmerge: True, force: False, partial: False
69 69 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
70 70 a: versions differ -> m
71 71 preserving a for resolve of a
72 72 updating: a 1/1 files (100.00%)
73 73 picked tool 'internal:merge' for a (binary False symlink True)
74 74 merging a
75 75 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
76 76 warning: internal:merge cannot merge symlinks for a
77 77 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
78 78 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
79 79 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
80 80 [1]
81 81
82 82 $ tellmeabout a
83 83 a is an executable file with content:
84 84 a
85 85
86 86 Update to link without local change should get us a symlink (issue3316):
87 87
88 88 $ hg up -C 0
89 89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 90 $ hg up
91 91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 92 $ hg st
93 93 ? a.orig
94 94
95 95 Update to link with local change should cause a merge prompt (issue3200):
96 96
97 97 $ hg up -Cq 0
98 98 $ echo data > a
99 99 $ HGMERGE= hg up -y --debug
100 100 searching for copies back to rev 2
101 101 resolving manifests
102 overwrite: False, partial: False
102 branchmerge: False, force: False, partial: False
103 103 ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
104 104 a: versions differ -> m
105 105 preserving a for resolve of a
106 106 updating: a 1/1 files (100.00%)
107 107 (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
108 108 picked tool 'internal:prompt' for a (binary False symlink True)
109 109 no tool found to merge a
110 110 keep (l)ocal or take (o)ther? l
111 111 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
112 112 $ hg diff --git
113 113 diff --git a/a b/a
114 114 old mode 120000
115 115 new mode 100644
116 116 --- a/a
117 117 +++ b/a
118 118 @@ -1,1 +1,1 @@
119 119 -symlink
120 120 \ No newline at end of file
121 121 +data
122 122
123 123
124 124 Test only 'l' change - happens rarely, except when recovering from situations
125 125 where that was what happened.
126 126
127 127 $ hg init test2
128 128 $ cd test2
129 129 $ printf base > f
130 130 $ hg ci -Aqm0
131 131 $ echo file > f
132 132 $ echo content >> f
133 133 $ hg ci -qm1
134 134 $ hg up -qr0
135 135 $ rm f
136 136 $ ln -s base f
137 137 $ hg ci -qm2
138 138 $ hg merge
139 139 merging f
140 140 warning: internal:merge cannot merge symlinks for f
141 141 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
142 142 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
143 143 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
144 144 [1]
145 145 $ tellmeabout f
146 146 f is a symlink:
147 147 f -> base
148 148
149 149 $ hg up -Cqr1
150 150 $ hg merge
151 151 merging f
152 152 warning: internal:merge cannot merge symlinks for f
153 153 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
154 154 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
155 155 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
156 156 [1]
157 157 $ tellmeabout f
158 158 f is a plain file with content:
159 159 file
160 160 content
161 161
162 162 $ cd ..
163 163
164 164 Test removed 'x' flag merged with change to symlink
165 165
166 166 $ hg init test3
167 167 $ cd test3
168 168 $ echo f > f
169 169 $ chmod +x f
170 170 $ hg ci -Aqm0
171 171 $ chmod -x f
172 172 $ hg ci -qm1
173 173 $ hg up -qr0
174 174 $ rm f
175 175 $ ln -s dangling f
176 176 $ hg ci -qm2
177 177 $ hg merge
178 178 merging f
179 179 warning: internal:merge cannot merge symlinks for f
180 180 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
181 181 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
182 182 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
183 183 [1]
184 184 $ tellmeabout f
185 185 f is a symlink:
186 186 f -> dangling
187 187
188 188 $ hg up -Cqr1
189 189 $ hg merge
190 190 merging f
191 191 warning: internal:merge cannot merge symlinks for f
192 192 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
193 193 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
194 194 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
195 195 [1]
196 196 $ tellmeabout f
197 197 f is a plain file with content:
198 198 f
199 199
200 200 Test removed 'x' flag merged with content change - both ways
201 201
202 202 $ hg up -Cqr0
203 203 $ echo change > f
204 204 $ hg ci -qm3
205 205 $ hg merge -r1
206 206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 207 (branch merge, don't forget to commit)
208 208 $ tellmeabout f
209 209 f is a plain file with content:
210 210 change
211 211
212 212 $ hg up -qCr1
213 213 $ hg merge -r3
214 214 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 215 (branch merge, don't forget to commit)
216 216 $ tellmeabout f
217 217 f is a plain file with content:
218 218 change
219 219
220 220 $ cd ..
221 221
222 222 Test merge with no common ancestor:
223 223 a: just different
224 224 b: x vs -, different (cannot calculate x, cannot ask merge tool)
225 225 c: x vs -, same (cannot calculate x, merge tool is no good)
226 226 d: x vs l, different
227 227 e: x vs l, same
228 228 f: - vs l, different
229 229 g: - vs l, same
230 230 h: l vs l, different
231 231 (where same means the filelog entry is shared and there thus is an ancestor!)
232 232
233 233 $ hg init test4
234 234 $ cd test4
235 235 $ echo 0 > 0
236 236 $ hg ci -Aqm0
237 237
238 238 $ echo 1 > a
239 239 $ echo 1 > b
240 240 $ chmod +x b
241 241 $ echo x > c
242 242 $ chmod +x c
243 243 $ echo 1 > d
244 244 $ chmod +x d
245 245 $ printf x > e
246 246 $ chmod +x e
247 247 $ echo 1 > f
248 248 $ printf x > g
249 249 $ ln -s 1 h
250 250 $ hg ci -qAm1
251 251
252 252 $ hg up -qr0
253 253 $ echo 2 > a
254 254 $ echo 2 > b
255 255 $ echo x > c
256 256 $ ln -s 2 d
257 257 $ ln -s x e
258 258 $ ln -s 2 f
259 259 $ ln -s x g
260 260 $ ln -s 2 h
261 261 $ hg ci -Aqm2
262 262
263 263 $ hg merge
264 264 merging a
265 265 warning: conflicts during merge.
266 266 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
267 267 warning: cannot merge flags for b
268 268 merging b
269 269 warning: conflicts during merge.
270 270 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
271 271 merging d
272 272 warning: internal:merge cannot merge symlinks for d
273 273 merging d incomplete! (edit conflicts, then use 'hg resolve --mark')
274 274 merging f
275 275 warning: internal:merge cannot merge symlinks for f
276 276 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
277 277 merging h
278 278 warning: internal:merge cannot merge symlinks for h
279 279 merging h incomplete! (edit conflicts, then use 'hg resolve --mark')
280 280 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
281 281 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
282 282 [1]
283 283 $ hg resolve -l
284 284 U a
285 285 U b
286 286 U d
287 287 U f
288 288 U h
289 289 $ tellmeabout a
290 290 a is a plain file with content:
291 291 <<<<<<< local
292 292 2
293 293 =======
294 294 1
295 295 >>>>>>> other
296 296 $ tellmeabout b
297 297 b is a plain file with content:
298 298 <<<<<<< local
299 299 2
300 300 =======
301 301 1
302 302 >>>>>>> other
303 303 $ tellmeabout c
304 304 c is a plain file with content:
305 305 x
306 306 $ tellmeabout d
307 307 d is a symlink:
308 308 d -> 2
309 309 $ tellmeabout e
310 310 e is a symlink:
311 311 e -> x
312 312 $ tellmeabout f
313 313 f is a symlink:
314 314 f -> 2
315 315 $ tellmeabout g
316 316 g is a symlink:
317 317 g -> x
318 318 $ tellmeabout h
319 319 h is a symlink:
320 320 h -> 2
321 321
322 322 $ hg up -Cqr1
323 323 $ hg merge
324 324 merging a
325 325 warning: conflicts during merge.
326 326 merging a incomplete! (edit conflicts, then use 'hg resolve --mark')
327 327 warning: cannot merge flags for b
328 328 merging b
329 329 warning: conflicts during merge.
330 330 merging b incomplete! (edit conflicts, then use 'hg resolve --mark')
331 331 merging d
332 332 warning: internal:merge cannot merge symlinks for d
333 333 merging d incomplete! (edit conflicts, then use 'hg resolve --mark')
334 334 merging f
335 335 warning: internal:merge cannot merge symlinks for f
336 336 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
337 337 merging h
338 338 warning: internal:merge cannot merge symlinks for h
339 339 merging h incomplete! (edit conflicts, then use 'hg resolve --mark')
340 340 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
341 341 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
342 342 [1]
343 343 $ tellmeabout a
344 344 a is a plain file with content:
345 345 <<<<<<< local
346 346 1
347 347 =======
348 348 2
349 349 >>>>>>> other
350 350 $ tellmeabout b
351 351 b is an executable file with content:
352 352 <<<<<<< local
353 353 1
354 354 =======
355 355 2
356 356 >>>>>>> other
357 357 $ tellmeabout c
358 358 c is a plain file with content:
359 359 x
360 360 $ tellmeabout d
361 361 d is an executable file with content:
362 362 1
363 363 $ tellmeabout e
364 364 e is an executable file with content:
365 365 x (no-eol)
366 366 $ tellmeabout f
367 367 f is a plain file with content:
368 368 1
369 369 $ tellmeabout g
370 370 g is a plain file with content:
371 371 x (no-eol)
372 372 $ tellmeabout h
373 373 h is a symlink:
374 374 h -> 1
375 375
376 376 $ cd ..
@@ -1,147 +1,147 b''
1 1 initial
2 2 $ hg init test-a
3 3 $ cd test-a
4 4 $ cat >test.txt <<"EOF"
5 5 > 1
6 6 > 2
7 7 > 3
8 8 > EOF
9 9 $ hg add test.txt
10 10 $ hg commit -m "Initial"
11 11
12 12 clone
13 13 $ cd ..
14 14 $ hg clone test-a test-b
15 15 updating to branch default
16 16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 17
18 18 change test-a
19 19 $ cd test-a
20 20 $ cat >test.txt <<"EOF"
21 21 > one
22 22 > two
23 23 > three
24 24 > EOF
25 25 $ hg commit -m "Numbers as words"
26 26
27 27 change test-b
28 28 $ cd ../test-b
29 29 $ cat >test.txt <<"EOF"
30 30 > 1
31 31 > 2.5
32 32 > 3
33 33 > EOF
34 34 $ hg commit -m "2 -> 2.5"
35 35
36 36 now pull and merge from test-a
37 37 $ hg pull ../test-a
38 38 pulling from ../test-a
39 39 searching for changes
40 40 adding changesets
41 41 adding manifests
42 42 adding file changes
43 43 added 1 changesets with 1 changes to 1 files (+1 heads)
44 44 (run 'hg heads' to see heads, 'hg merge' to merge)
45 45 $ hg merge
46 46 merging test.txt
47 47 warning: conflicts during merge.
48 48 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
49 49 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
50 50 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
51 51 [1]
52 52 resolve conflict
53 53 $ cat >test.txt <<"EOF"
54 54 > one
55 55 > two-point-five
56 56 > three
57 57 > EOF
58 58 $ rm -f *.orig
59 59 $ hg resolve -m test.txt
60 60 $ hg commit -m "Merge 1"
61 61
62 62 change test-a again
63 63 $ cd ../test-a
64 64 $ cat >test.txt <<"EOF"
65 65 > one
66 66 > two-point-one
67 67 > three
68 68 > EOF
69 69 $ hg commit -m "two -> two-point-one"
70 70
71 71 pull and merge from test-a again
72 72 $ cd ../test-b
73 73 $ hg pull ../test-a
74 74 pulling from ../test-a
75 75 searching for changes
76 76 adding changesets
77 77 adding manifests
78 78 adding file changes
79 79 added 1 changesets with 1 changes to 1 files (+1 heads)
80 80 (run 'hg heads' to see heads, 'hg merge' to merge)
81 81 $ hg merge --debug
82 82 searching for copies back to rev 1
83 83 resolving manifests
84 overwrite: False, partial: False
84 branchmerge: True, force: False, partial: False
85 85 ancestor: 96b70246a118, local: 50c3a7e29886+, remote: 40d11a4173a8
86 86 test.txt: versions differ -> m
87 87 preserving test.txt for resolve of test.txt
88 88 updating: test.txt 1/1 files (100.00%)
89 89 picked tool 'internal:merge' for test.txt (binary False symlink False)
90 90 merging test.txt
91 91 my test.txt@50c3a7e29886+ other test.txt@40d11a4173a8 ancestor test.txt@96b70246a118
92 92 warning: conflicts during merge.
93 93 merging test.txt incomplete! (edit conflicts, then use 'hg resolve --mark')
94 94 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
95 95 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
96 96 [1]
97 97
98 98 $ cat test.txt
99 99 one
100 100 <<<<<<< local
101 101 two-point-five
102 102 =======
103 103 two-point-one
104 104 >>>>>>> other
105 105 three
106 106
107 107 $ hg debugindex test.txt
108 108 rev offset length ..... linkrev nodeid p1 p2 (re)
109 109 0 0 7 ..... 0 01365c4cca56 000000000000 000000000000 (re)
110 110 1 7 9 ..... 1 7b013192566a 01365c4cca56 000000000000 (re)
111 111 2 16 15 ..... 2 8fe46a3eb557 01365c4cca56 000000000000 (re)
112 112 3 31 2. ..... 3 fc3148072371 7b013192566a 8fe46a3eb557 (re)
113 113 4 5. 25 ..... 4 d40249267ae3 8fe46a3eb557 000000000000 (re)
114 114
115 115 $ hg log
116 116 changeset: 4:40d11a4173a8
117 117 tag: tip
118 118 parent: 2:96b70246a118
119 119 user: test
120 120 date: Thu Jan 01 00:00:00 1970 +0000
121 121 summary: two -> two-point-one
122 122
123 123 changeset: 3:50c3a7e29886
124 124 parent: 1:d1e159716d41
125 125 parent: 2:96b70246a118
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: Merge 1
129 129
130 130 changeset: 2:96b70246a118
131 131 parent: 0:b1832b9d912a
132 132 user: test
133 133 date: Thu Jan 01 00:00:00 1970 +0000
134 134 summary: Numbers as words
135 135
136 136 changeset: 1:d1e159716d41
137 137 user: test
138 138 date: Thu Jan 01 00:00:00 1970 +0000
139 139 summary: 2 -> 2.5
140 140
141 141 changeset: 0:b1832b9d912a
142 142 user: test
143 143 date: Thu Jan 01 00:00:00 1970 +0000
144 144 summary: Initial
145 145
146 146
147 147 $ cd ..
@@ -1,159 +1,159 b''
1 1 $ hg init t
2 2 $ cd t
3 3
4 4 $ mkdir a
5 5 $ echo foo > a/a
6 6 $ echo bar > a/b
7 7 $ hg ci -Am "0"
8 8 adding a/a
9 9 adding a/b
10 10
11 11 $ hg co -C 0
12 12 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 13 $ hg mv a b
14 14 moving a/a to b/a (glob)
15 15 moving a/b to b/b (glob)
16 16 $ hg ci -m "1 mv a/ b/"
17 17
18 18 $ hg co -C 0
19 19 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
20 20 $ echo baz > a/c
21 21 $ echo quux > a/d
22 22 $ hg add a/c
23 23 $ hg ci -m "2 add a/c"
24 24 created new head
25 25
26 26 $ hg merge --debug 1
27 27 searching for copies back to rev 1
28 28 unmatched files in local:
29 29 a/c
30 30 unmatched files in other:
31 31 b/a
32 32 b/b
33 33 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
34 34 src: 'a/a' -> dst: 'b/a'
35 35 src: 'a/b' -> dst: 'b/b'
36 36 checking for directory renames
37 37 discovered dir src: 'a/' -> dst: 'b/'
38 38 pending file src: 'a/c' -> dst: 'b/c'
39 39 resolving manifests
40 overwrite: False, partial: False
40 branchmerge: True, force: False, partial: False
41 41 ancestor: f9b20c0d4c51, local: ce36d17b18fb+, remote: 397f8b00a740
42 42 a/a: other deleted -> r
43 43 a/b: other deleted -> r
44 44 a/c: remote renamed directory to b/c -> d
45 45 b/a: remote created -> g
46 46 b/b: remote created -> g
47 47 updating: a/a 1/5 files (20.00%)
48 48 removing a/a
49 49 updating: a/b 2/5 files (40.00%)
50 50 removing a/b
51 51 updating: a/c 3/5 files (60.00%)
52 52 moving a/c to b/c
53 53 updating: b/a 4/5 files (80.00%)
54 54 getting b/a
55 55 updating: b/b 5/5 files (100.00%)
56 56 getting b/b
57 57 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
58 58 (branch merge, don't forget to commit)
59 59
60 60 $ echo a/* b/*
61 61 a/d b/a b/b b/c
62 62 $ hg st -C
63 63 M b/a
64 64 M b/b
65 65 A b/c
66 66 a/c
67 67 R a/a
68 68 R a/b
69 69 R a/c
70 70 ? a/d
71 71 $ hg ci -m "3 merge 2+1"
72 72 $ hg debugrename b/c
73 73 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88 (glob)
74 74
75 75 $ hg co -C 1
76 76 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
77 77 $ hg merge --debug 2
78 78 searching for copies back to rev 1
79 79 unmatched files in local:
80 80 b/a
81 81 b/b
82 82 unmatched files in other:
83 83 a/c
84 84 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
85 85 src: 'a/a' -> dst: 'b/a'
86 86 src: 'a/b' -> dst: 'b/b'
87 87 checking for directory renames
88 88 discovered dir src: 'a/' -> dst: 'b/'
89 89 pending file src: 'a/c' -> dst: 'b/c'
90 90 resolving manifests
91 overwrite: False, partial: False
91 branchmerge: True, force: False, partial: False
92 92 ancestor: f9b20c0d4c51, local: 397f8b00a740+, remote: ce36d17b18fb
93 93 None: local renamed directory to b/c -> d
94 94 updating:None 1/1 files (100.00%)
95 95 getting a/c to b/c
96 96 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 97 (branch merge, don't forget to commit)
98 98
99 99 $ echo a/* b/*
100 100 a/d b/a b/b b/c
101 101 $ hg st -C
102 102 A b/c
103 103 a/c
104 104 ? a/d
105 105 $ hg ci -m "4 merge 1+2"
106 106 created new head
107 107 $ hg debugrename b/c
108 108 b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88 (glob)
109 109
110 110
111 111 Second scenario with two repos:
112 112
113 113 $ cd ..
114 114 $ hg init r1
115 115 $ cd r1
116 116 $ mkdir a
117 117 $ echo foo > a/f
118 118 $ hg add a
119 119 adding a/f (glob)
120 120 $ hg ci -m "a/f == foo"
121 121 $ cd ..
122 122
123 123 $ hg clone r1 r2
124 124 updating to branch default
125 125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 126 $ cd r2
127 127 $ hg mv a b
128 128 moving a/f to b/f (glob)
129 129 $ echo foo1 > b/f
130 130 $ hg ci -m" a -> b, b/f == foo1"
131 131 $ cd ..
132 132
133 133 $ cd r1
134 134 $ mkdir a/aa
135 135 $ echo bar > a/aa/g
136 136 $ hg add a/aa
137 137 adding a/aa/g (glob)
138 138 $ hg ci -m "a/aa/g"
139 139 $ hg pull ../r2
140 140 pulling from ../r2
141 141 searching for changes
142 142 adding changesets
143 143 adding manifests
144 144 adding file changes
145 145 added 1 changesets with 1 changes to 1 files (+1 heads)
146 146 (run 'hg heads' to see heads, 'hg merge' to merge)
147 147
148 148 $ hg merge
149 149 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
150 150 (branch merge, don't forget to commit)
151 151
152 152 $ hg st -C
153 153 M b/f
154 154 A b/aa/g
155 155 a/aa/g
156 156 R a/aa/g
157 157 R a/f
158 158
159 159 $ cd ..
@@ -1,195 +1,195 b''
1 1 $ hg init
2 2
3 3 $ echo "[merge]" >> .hg/hgrc
4 4 $ echo "followcopies = 1" >> .hg/hgrc
5 5
6 6 $ echo foo > a
7 7 $ echo foo > a2
8 8 $ hg add a a2
9 9 $ hg ci -m "start"
10 10
11 11 $ hg mv a b
12 12 $ hg mv a2 b2
13 13 $ hg ci -m "rename"
14 14
15 15 $ hg co 0
16 16 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
17 17
18 18 $ echo blahblah > a
19 19 $ echo blahblah > a2
20 20 $ hg mv a2 c2
21 21 $ hg ci -m "modify"
22 22 created new head
23 23
24 24 $ hg merge -y --debug
25 25 searching for copies back to rev 1
26 26 unmatched files in local:
27 27 c2
28 28 unmatched files in other:
29 29 b
30 30 b2
31 31 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
32 32 src: 'a' -> dst: 'b' *
33 33 src: 'a2' -> dst: 'b2' !
34 34 src: 'a2' -> dst: 'c2' !
35 35 checking for directory renames
36 36 resolving manifests
37 overwrite: False, partial: False
37 branchmerge: True, force: False, partial: False
38 38 ancestor: af1939970a1c, local: 044f8520aeeb+, remote: 85c198ef2f6c
39 39 a: remote moved to b -> m
40 40 preserving a for resolve of b
41 41 a2: divergent renames -> dr
42 42 b2: remote created -> g
43 43 removing a
44 44 updating: a 1/3 files (33.33%)
45 45 picked tool 'internal:merge' for b (binary False symlink False)
46 46 merging a and b to b
47 47 my b@044f8520aeeb+ other b@85c198ef2f6c ancestor a@af1939970a1c
48 48 premerge successful
49 49 updating: a2 2/3 files (66.67%)
50 50 note: possible conflict - a2 was renamed multiple times to:
51 51 c2
52 52 b2
53 53 updating: b2 3/3 files (100.00%)
54 54 getting b2
55 55 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
56 56 (branch merge, don't forget to commit)
57 57
58 58 $ hg status -AC
59 59 M b
60 60 a
61 61 M b2
62 62 R a
63 63 C c2
64 64
65 65 $ cat b
66 66 blahblah
67 67
68 68 $ hg ci -m "merge"
69 69
70 70 $ hg debugindex b
71 71 rev offset length ..... linkrev nodeid p1 p2 (re)
72 72 0 0 67 ..... 1 57eacc201a7f 000000000000 000000000000 (re)
73 73 1 67 72 ..... 3 4727ba907962 000000000000 57eacc201a7f (re)
74 74
75 75 $ hg debugrename b
76 76 b renamed from a:dd03b83622e78778b403775d0d074b9ac7387a66
77 77
78 78 This used to trigger a "divergent renames" warning, despite no renames
79 79
80 80 $ hg cp b b3
81 81 $ hg cp b b4
82 82 $ hg ci -A -m 'copy b twice'
83 83 $ hg up eb92d88a9712
84 84 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
85 85 $ hg up
86 86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 87 $ hg rm b3 b4
88 88 $ hg ci -m 'clean up a bit of our mess'
89 89
90 90 We'd rather not warn on divergent renames done in the same changeset (issue2113)
91 91
92 92 $ hg cp b b3
93 93 $ hg mv b b4
94 94 $ hg ci -A -m 'divergent renames in same changeset'
95 95 $ hg up c761c6948de0
96 96 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
97 97 $ hg up
98 98 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
99 99
100 100 Check for issue2642
101 101
102 102 $ hg init t
103 103 $ cd t
104 104
105 105 $ echo c0 > f1
106 106 $ hg ci -Aqm0
107 107
108 108 $ hg up null -q
109 109 $ echo c1 > f1 # backport
110 110 $ hg ci -Aqm1
111 111 $ hg mv f1 f2
112 112 $ hg ci -qm2
113 113
114 114 $ hg up 0 -q
115 115 $ hg merge 1 -q --tool internal:local
116 116 $ hg ci -qm3
117 117
118 118 $ hg merge 2
119 119 merging f1 and f2 to f2
120 120 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
121 121 (branch merge, don't forget to commit)
122 122
123 123 $ cat f2
124 124 c0
125 125
126 126 $ cd ..
127 127
128 128 Check for issue2089
129 129
130 130 $ hg init repo2089
131 131 $ cd repo2089
132 132
133 133 $ echo c0 > f1
134 134 $ hg ci -Aqm0
135 135
136 136 $ hg up null -q
137 137 $ echo c1 > f1
138 138 $ hg ci -Aqm1
139 139
140 140 $ hg up 0 -q
141 141 $ hg merge 1 -q --tool internal:local
142 142 $ echo c2 > f1
143 143 $ hg ci -qm2
144 144
145 145 $ hg up 1 -q
146 146 $ hg mv f1 f2
147 147 $ hg ci -Aqm3
148 148
149 149 $ hg up 2 -q
150 150 $ hg merge 3
151 151 merging f1 and f2 to f2
152 152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
153 153 (branch merge, don't forget to commit)
154 154
155 155 $ cat f2
156 156 c2
157 157
158 158 $ cd ..
159 159
160 160 Check for issue3074
161 161
162 162 $ hg init repo3074
163 163 $ cd repo3074
164 164 $ echo foo > file
165 165 $ hg add file
166 166 $ hg commit -m "added file"
167 167 $ hg mv file newfile
168 168 $ hg commit -m "renamed file"
169 169 $ hg update 0
170 170 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
171 171 $ hg rm file
172 172 $ hg commit -m "deleted file"
173 173 created new head
174 174 $ hg merge --debug
175 175 searching for copies back to rev 1
176 176 unmatched files in other:
177 177 newfile
178 178 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
179 179 src: 'file' -> dst: 'newfile' %
180 180 checking for directory renames
181 181 resolving manifests
182 overwrite: False, partial: False
182 branchmerge: True, force: False, partial: False
183 183 ancestor: 19d7f95df299, local: 0084274f6b67+, remote: 5d32493049f0
184 184 file: rename and delete -> rd
185 185 newfile: remote created -> g
186 186 updating: file 1/2 files (50.00%)
187 187 note: possible conflict - file was deleted and renamed to:
188 188 newfile
189 189 updating: newfile 2/2 files (100.00%)
190 190 getting newfile
191 191 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 192 (branch merge, don't forget to commit)
193 193 $ hg status
194 194 M newfile
195 195 $ cd ..
@@ -1,754 +1,754 b''
1 1
2 2 $ mkdir -p t
3 3 $ cd t
4 4 $ cat <<EOF > merge
5 5 > import sys, os
6 6 > f = open(sys.argv[1], "wb")
7 7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 8 > f.close()
9 9 > EOF
10 10
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 $ uc() { up $1; hg cp $1 $2; } # update + copy
72 72 $ um() { up $1; hg mv $1 $2; }
73 73 $ nc() { hg cp $1 $2; } # just copy
74 74 $ nm() { hg mv $1 $2; } # just move
75 75 $ tm "up a " "nc a b" " " "1 get local a to b"
76 76 created new head
77 77 --------------
78 78 test L:up a R:nc a b W: - 1 get local a to b
79 79 --------------
80 80 searching for copies back to rev 1
81 81 unmatched files in other:
82 82 b
83 83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 84 src: 'a' -> dst: 'b' *
85 85 checking for directory renames
86 86 resolving manifests
87 overwrite: False, partial: False
87 branchmerge: True, force: False, partial: False
88 88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
89 89 a: remote copied to b -> m
90 90 preserving a for resolve of b
91 91 rev: versions differ -> m
92 92 preserving rev for resolve of rev
93 93 updating: a 1/2 files (50.00%)
94 94 picked tool 'python ../merge' for b (binary False symlink False)
95 95 merging a and b to b
96 96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
97 97 premerge successful
98 98 updating: rev 2/2 files (100.00%)
99 99 picked tool 'python ../merge' for rev (binary False symlink False)
100 100 merging rev
101 101 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 102 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
103 103 (branch merge, don't forget to commit)
104 104 --------------
105 105 M b
106 106 a
107 107 C a
108 108 --------------
109 109
110 110 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
111 111 created new head
112 112 --------------
113 113 test L:nc a b R:up a W: - 2 get rem change to a and b
114 114 --------------
115 115 searching for copies back to rev 1
116 116 unmatched files in local:
117 117 b
118 118 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
119 119 src: 'a' -> dst: 'b' *
120 120 checking for directory renames
121 121 resolving manifests
122 overwrite: False, partial: False
122 branchmerge: True, force: False, partial: False
123 123 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
124 124 a: remote is newer -> g
125 125 b: local copied/moved to a -> m
126 126 preserving b for resolve of b
127 127 rev: versions differ -> m
128 128 preserving rev for resolve of rev
129 129 updating: a 1/3 files (33.33%)
130 130 getting a
131 131 updating: b 2/3 files (66.67%)
132 132 picked tool 'python ../merge' for b (binary False symlink False)
133 133 merging b and a to b
134 134 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
135 135 premerge successful
136 136 updating: rev 3/3 files (100.00%)
137 137 picked tool 'python ../merge' for rev (binary False symlink False)
138 138 merging rev
139 139 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
140 140 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
141 141 (branch merge, don't forget to commit)
142 142 --------------
143 143 M a
144 144 M b
145 145 a
146 146 --------------
147 147
148 148 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
149 149 created new head
150 150 --------------
151 151 test L:up a R:nm a b W: - 3 get local a change to b, remove a
152 152 --------------
153 153 searching for copies back to rev 1
154 154 unmatched files in other:
155 155 b
156 156 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
157 157 src: 'a' -> dst: 'b' *
158 158 checking for directory renames
159 159 resolving manifests
160 overwrite: False, partial: False
160 branchmerge: True, force: False, partial: False
161 161 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
162 162 a: remote moved to b -> m
163 163 preserving a for resolve of b
164 164 rev: versions differ -> m
165 165 preserving rev for resolve of rev
166 166 removing a
167 167 updating: a 1/2 files (50.00%)
168 168 picked tool 'python ../merge' for b (binary False symlink False)
169 169 merging a and b to b
170 170 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
171 171 premerge successful
172 172 updating: rev 2/2 files (100.00%)
173 173 picked tool 'python ../merge' for rev (binary False symlink False)
174 174 merging rev
175 175 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
176 176 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
177 177 (branch merge, don't forget to commit)
178 178 --------------
179 179 M b
180 180 a
181 181 --------------
182 182
183 183 $ tm "nm a b" "up a " " " "4 get remote change to b"
184 184 created new head
185 185 --------------
186 186 test L:nm a b R:up a W: - 4 get remote change to b
187 187 --------------
188 188 searching for copies back to rev 1
189 189 unmatched files in local:
190 190 b
191 191 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
192 192 src: 'a' -> dst: 'b' *
193 193 checking for directory renames
194 194 resolving manifests
195 overwrite: False, partial: False
195 branchmerge: True, force: False, partial: False
196 196 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
197 197 b: local copied/moved to a -> m
198 198 preserving b for resolve of b
199 199 rev: versions differ -> m
200 200 preserving rev for resolve of rev
201 201 updating: b 1/2 files (50.00%)
202 202 picked tool 'python ../merge' for b (binary False symlink False)
203 203 merging b and a to b
204 204 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
205 205 premerge successful
206 206 updating: rev 2/2 files (100.00%)
207 207 picked tool 'python ../merge' for rev (binary False symlink False)
208 208 merging rev
209 209 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
210 210 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
211 211 (branch merge, don't forget to commit)
212 212 --------------
213 213 M b
214 214 a
215 215 --------------
216 216
217 217 $ tm " " "nc a b" " " "5 get b"
218 218 created new head
219 219 --------------
220 220 test L: R:nc a b W: - 5 get b
221 221 --------------
222 222 searching for copies back to rev 1
223 223 unmatched files in other:
224 224 b
225 225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 226 src: 'a' -> dst: 'b'
227 227 checking for directory renames
228 228 resolving manifests
229 overwrite: False, partial: False
229 branchmerge: True, force: False, partial: False
230 230 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
231 231 b: remote created -> g
232 232 rev: versions differ -> m
233 233 preserving rev for resolve of rev
234 234 updating: b 1/2 files (50.00%)
235 235 getting b
236 236 updating: rev 2/2 files (100.00%)
237 237 picked tool 'python ../merge' for rev (binary False symlink False)
238 238 merging rev
239 239 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
240 240 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
241 241 (branch merge, don't forget to commit)
242 242 --------------
243 243 M b
244 244 C a
245 245 --------------
246 246
247 247 $ tm "nc a b" " " " " "6 nothing"
248 248 created new head
249 249 --------------
250 250 test L:nc a b R: W: - 6 nothing
251 251 --------------
252 252 searching for copies back to rev 1
253 253 unmatched files in local:
254 254 b
255 255 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
256 256 src: 'a' -> dst: 'b'
257 257 checking for directory renames
258 258 resolving manifests
259 overwrite: False, partial: False
259 branchmerge: True, force: False, partial: False
260 260 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
261 261 rev: versions differ -> m
262 262 preserving rev for resolve of rev
263 263 updating: rev 1/1 files (100.00%)
264 264 picked tool 'python ../merge' for rev (binary False symlink False)
265 265 merging rev
266 266 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
267 267 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
268 268 (branch merge, don't forget to commit)
269 269 --------------
270 270 C a
271 271 C b
272 272 --------------
273 273
274 274 $ tm " " "nm a b" " " "7 get b"
275 275 created new head
276 276 --------------
277 277 test L: R:nm a b W: - 7 get b
278 278 --------------
279 279 searching for copies back to rev 1
280 280 unmatched files in other:
281 281 b
282 282 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
283 283 src: 'a' -> dst: 'b'
284 284 checking for directory renames
285 285 resolving manifests
286 overwrite: False, partial: False
286 branchmerge: True, force: False, partial: False
287 287 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
288 288 a: other deleted -> r
289 289 b: remote created -> g
290 290 rev: versions differ -> m
291 291 preserving rev for resolve of rev
292 292 updating: a 1/3 files (33.33%)
293 293 removing a
294 294 updating: b 2/3 files (66.67%)
295 295 getting b
296 296 updating: rev 3/3 files (100.00%)
297 297 picked tool 'python ../merge' for rev (binary False symlink False)
298 298 merging rev
299 299 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
300 300 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
301 301 (branch merge, don't forget to commit)
302 302 --------------
303 303 M b
304 304 --------------
305 305
306 306 $ tm "nm a b" " " " " "8 nothing"
307 307 created new head
308 308 --------------
309 309 test L:nm a b R: W: - 8 nothing
310 310 --------------
311 311 searching for copies back to rev 1
312 312 unmatched files in local:
313 313 b
314 314 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
315 315 src: 'a' -> dst: 'b'
316 316 checking for directory renames
317 317 resolving manifests
318 overwrite: False, partial: False
318 branchmerge: True, force: False, partial: False
319 319 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
320 320 rev: versions differ -> m
321 321 preserving rev for resolve of rev
322 322 updating: rev 1/1 files (100.00%)
323 323 picked tool 'python ../merge' for rev (binary False symlink False)
324 324 merging rev
325 325 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
326 326 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
327 327 (branch merge, don't forget to commit)
328 328 --------------
329 329 C b
330 330 --------------
331 331
332 332 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
333 333 created new head
334 334 --------------
335 335 test L:um a b R:um a b W: - 9 do merge with ancestor in a
336 336 --------------
337 337 searching for copies back to rev 1
338 338 resolving manifests
339 overwrite: False, partial: False
339 branchmerge: True, force: False, partial: False
340 340 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
341 341 b: versions differ -> m
342 342 preserving b for resolve of b
343 343 rev: versions differ -> m
344 344 preserving rev for resolve of rev
345 345 updating: b 1/2 files (50.00%)
346 346 picked tool 'python ../merge' for b (binary False symlink False)
347 347 merging b
348 348 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
349 349 updating: rev 2/2 files (100.00%)
350 350 picked tool 'python ../merge' for rev (binary False symlink False)
351 351 merging rev
352 352 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
353 353 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
354 354 (branch merge, don't forget to commit)
355 355 --------------
356 356 M b
357 357 --------------
358 358
359 359
360 360 m "um a c" "um x c" " " "10 do merge with no ancestor"
361 361
362 362 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
363 363 created new head
364 364 --------------
365 365 test L:nm a b R:nm a c W: - 11 get c, keep b
366 366 --------------
367 367 searching for copies back to rev 1
368 368 unmatched files in local:
369 369 b
370 370 unmatched files in other:
371 371 c
372 372 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
373 373 src: 'a' -> dst: 'b' !
374 374 src: 'a' -> dst: 'c' !
375 375 checking for directory renames
376 376 resolving manifests
377 overwrite: False, partial: False
377 branchmerge: True, force: False, partial: False
378 378 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
379 379 a: divergent renames -> dr
380 380 c: remote created -> g
381 381 rev: versions differ -> m
382 382 preserving rev for resolve of rev
383 383 updating: a 1/3 files (33.33%)
384 384 note: possible conflict - a was renamed multiple times to:
385 385 b
386 386 c
387 387 updating: c 2/3 files (66.67%)
388 388 getting c
389 389 updating: rev 3/3 files (100.00%)
390 390 picked tool 'python ../merge' for rev (binary False symlink False)
391 391 merging rev
392 392 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
393 393 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
394 394 (branch merge, don't forget to commit)
395 395 --------------
396 396 M c
397 397 C b
398 398 --------------
399 399
400 400 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
401 401 created new head
402 402 --------------
403 403 test L:nc a b R:up b W: - 12 merge b no ancestor
404 404 --------------
405 405 searching for copies back to rev 1
406 406 resolving manifests
407 overwrite: False, partial: False
407 branchmerge: True, force: False, partial: False
408 408 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
409 409 b: versions differ -> m
410 410 preserving b for resolve of b
411 411 rev: versions differ -> m
412 412 preserving rev for resolve of rev
413 413 updating: b 1/2 files (50.00%)
414 414 picked tool 'python ../merge' for b (binary False symlink False)
415 415 merging b
416 416 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
417 417 updating: rev 2/2 files (100.00%)
418 418 picked tool 'python ../merge' for rev (binary False symlink False)
419 419 merging rev
420 420 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
421 421 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
422 422 (branch merge, don't forget to commit)
423 423 --------------
424 424 M b
425 425 C a
426 426 --------------
427 427
428 428 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
429 429 created new head
430 430 --------------
431 431 test L:up b R:nm a b W: - 13 merge b no ancestor
432 432 --------------
433 433 searching for copies back to rev 1
434 434 resolving manifests
435 overwrite: False, partial: False
435 branchmerge: True, force: False, partial: False
436 436 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
437 437 a: other deleted -> r
438 438 b: versions differ -> m
439 439 preserving b for resolve of b
440 440 rev: versions differ -> m
441 441 preserving rev for resolve of rev
442 442 updating: a 1/3 files (33.33%)
443 443 removing a
444 444 updating: b 2/3 files (66.67%)
445 445 picked tool 'python ../merge' for b (binary False symlink False)
446 446 merging b
447 447 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
448 448 updating: rev 3/3 files (100.00%)
449 449 picked tool 'python ../merge' for rev (binary False symlink False)
450 450 merging rev
451 451 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
452 452 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
453 453 (branch merge, don't forget to commit)
454 454 --------------
455 455 M b
456 456 --------------
457 457
458 458 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
459 459 created new head
460 460 --------------
461 461 test L:nc a b R:up a b W: - 14 merge b no ancestor
462 462 --------------
463 463 searching for copies back to rev 1
464 464 resolving manifests
465 overwrite: False, partial: False
465 branchmerge: True, force: False, partial: False
466 466 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
467 467 a: remote is newer -> g
468 468 b: versions differ -> m
469 469 preserving b for resolve of b
470 470 rev: versions differ -> m
471 471 preserving rev for resolve of rev
472 472 updating: a 1/3 files (33.33%)
473 473 getting a
474 474 updating: b 2/3 files (66.67%)
475 475 picked tool 'python ../merge' for b (binary False symlink False)
476 476 merging b
477 477 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
478 478 updating: rev 3/3 files (100.00%)
479 479 picked tool 'python ../merge' for rev (binary False symlink False)
480 480 merging rev
481 481 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
482 482 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
483 483 (branch merge, don't forget to commit)
484 484 --------------
485 485 M a
486 486 M b
487 487 --------------
488 488
489 489 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
490 490 created new head
491 491 --------------
492 492 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
493 493 --------------
494 494 searching for copies back to rev 1
495 495 resolving manifests
496 overwrite: False, partial: False
496 branchmerge: True, force: False, partial: False
497 497 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
498 498 a: other deleted -> r
499 499 b: versions differ -> m
500 500 preserving b for resolve of b
501 501 rev: versions differ -> m
502 502 preserving rev for resolve of rev
503 503 updating: a 1/3 files (33.33%)
504 504 removing a
505 505 updating: b 2/3 files (66.67%)
506 506 picked tool 'python ../merge' for b (binary False symlink False)
507 507 merging b
508 508 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
509 509 updating: rev 3/3 files (100.00%)
510 510 picked tool 'python ../merge' for rev (binary False symlink False)
511 511 merging rev
512 512 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
513 513 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
514 514 (branch merge, don't forget to commit)
515 515 --------------
516 516 M b
517 517 --------------
518 518
519 519 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
520 520 created new head
521 521 --------------
522 522 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
523 523 --------------
524 524 searching for copies back to rev 1
525 525 resolving manifests
526 overwrite: False, partial: False
526 branchmerge: True, force: False, partial: False
527 527 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
528 528 a: remote is newer -> g
529 529 b: versions differ -> m
530 530 preserving b for resolve of b
531 531 rev: versions differ -> m
532 532 preserving rev for resolve of rev
533 533 updating: a 1/3 files (33.33%)
534 534 getting a
535 535 updating: b 2/3 files (66.67%)
536 536 picked tool 'python ../merge' for b (binary False symlink False)
537 537 merging b
538 538 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
539 539 updating: rev 3/3 files (100.00%)
540 540 picked tool 'python ../merge' for rev (binary False symlink False)
541 541 merging rev
542 542 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
543 543 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
544 544 (branch merge, don't forget to commit)
545 545 --------------
546 546 M a
547 547 M b
548 548 --------------
549 549
550 550 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
551 551 created new head
552 552 --------------
553 553 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
554 554 --------------
555 555 searching for copies back to rev 1
556 556 resolving manifests
557 overwrite: False, partial: False
557 branchmerge: True, force: False, partial: False
558 558 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
559 559 b: versions differ -> m
560 560 preserving b for resolve of b
561 561 rev: versions differ -> m
562 562 preserving rev for resolve of rev
563 563 updating: b 1/2 files (50.00%)
564 564 picked tool 'python ../merge' for b (binary False symlink False)
565 565 merging b
566 566 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
567 567 updating: rev 2/2 files (100.00%)
568 568 picked tool 'python ../merge' for rev (binary False symlink False)
569 569 merging rev
570 570 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
571 571 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
572 572 (branch merge, don't forget to commit)
573 573 --------------
574 574 M b
575 575 C a
576 576 --------------
577 577
578 578 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
579 579 created new head
580 580 --------------
581 581 test L:nm a b R:up a b W: - 18 merge b no ancestor
582 582 --------------
583 583 searching for copies back to rev 1
584 584 resolving manifests
585 overwrite: False, partial: False
585 branchmerge: True, force: False, partial: False
586 586 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
587 587 remote changed a which local deleted
588 588 use (c)hanged version or leave (d)eleted? c
589 589 a: prompt recreating -> g
590 590 b: versions differ -> m
591 591 preserving b for resolve of b
592 592 rev: versions differ -> m
593 593 preserving rev for resolve of rev
594 594 updating: a 1/3 files (33.33%)
595 595 getting a
596 596 updating: b 2/3 files (66.67%)
597 597 picked tool 'python ../merge' for b (binary False symlink False)
598 598 merging b
599 599 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
600 600 updating: rev 3/3 files (100.00%)
601 601 picked tool 'python ../merge' for rev (binary False symlink False)
602 602 merging rev
603 603 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
604 604 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
605 605 (branch merge, don't forget to commit)
606 606 --------------
607 607 M a
608 608 M b
609 609 --------------
610 610
611 611 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
612 612 created new head
613 613 --------------
614 614 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
615 615 --------------
616 616 searching for copies back to rev 1
617 617 resolving manifests
618 overwrite: False, partial: False
618 branchmerge: True, force: False, partial: False
619 619 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
620 620 local changed a which remote deleted
621 621 use (c)hanged version or (d)elete? c
622 622 a: prompt keep -> a
623 623 b: versions differ -> m
624 624 preserving b for resolve of b
625 625 rev: versions differ -> m
626 626 preserving rev for resolve of rev
627 627 updating: a 1/3 files (33.33%)
628 628 updating: b 2/3 files (66.67%)
629 629 picked tool 'python ../merge' for b (binary False symlink False)
630 630 merging b
631 631 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
632 632 updating: rev 3/3 files (100.00%)
633 633 picked tool 'python ../merge' for rev (binary False symlink False)
634 634 merging rev
635 635 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
636 636 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
637 637 (branch merge, don't forget to commit)
638 638 --------------
639 639 M b
640 640 C a
641 641 --------------
642 642
643 643 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
644 644 created new head
645 645 --------------
646 646 test L:up a R:um a b W: - 20 merge a and b to b, remove a
647 647 --------------
648 648 searching for copies back to rev 1
649 649 unmatched files in other:
650 650 b
651 651 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
652 652 src: 'a' -> dst: 'b' *
653 653 checking for directory renames
654 654 resolving manifests
655 overwrite: False, partial: False
655 branchmerge: True, force: False, partial: False
656 656 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
657 657 a: remote moved to b -> m
658 658 preserving a for resolve of b
659 659 rev: versions differ -> m
660 660 preserving rev for resolve of rev
661 661 removing a
662 662 updating: a 1/2 files (50.00%)
663 663 picked tool 'python ../merge' for b (binary False symlink False)
664 664 merging a and b to b
665 665 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
666 666 updating: rev 2/2 files (100.00%)
667 667 picked tool 'python ../merge' for rev (binary False symlink False)
668 668 merging rev
669 669 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
670 670 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
671 671 (branch merge, don't forget to commit)
672 672 --------------
673 673 M b
674 674 a
675 675 --------------
676 676
677 677 $ tm "um a b" "up a " " " "21 merge a and b to b"
678 678 created new head
679 679 --------------
680 680 test L:um a b R:up a W: - 21 merge a and b to b
681 681 --------------
682 682 searching for copies back to rev 1
683 683 unmatched files in local:
684 684 b
685 685 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
686 686 src: 'a' -> dst: 'b' *
687 687 checking for directory renames
688 688 resolving manifests
689 overwrite: False, partial: False
689 branchmerge: True, force: False, partial: False
690 690 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
691 691 b: local copied/moved to a -> m
692 692 preserving b for resolve of b
693 693 rev: versions differ -> m
694 694 preserving rev for resolve of rev
695 695 updating: b 1/2 files (50.00%)
696 696 picked tool 'python ../merge' for b (binary False symlink False)
697 697 merging b and a to b
698 698 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
699 699 updating: rev 2/2 files (100.00%)
700 700 picked tool 'python ../merge' for rev (binary False symlink False)
701 701 merging rev
702 702 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
703 703 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
704 704 (branch merge, don't forget to commit)
705 705 --------------
706 706 M b
707 707 a
708 708 --------------
709 709
710 710
711 711 m "nm a b" "um x a" " " "22 get a, keep b"
712 712
713 713 $ tm "nm a b" "up a c" " " "23 get c, keep b"
714 714 created new head
715 715 --------------
716 716 test L:nm a b R:up a c W: - 23 get c, keep b
717 717 --------------
718 718 searching for copies back to rev 1
719 719 unmatched files in local:
720 720 b
721 721 unmatched files in other:
722 722 c
723 723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
724 724 src: 'a' -> dst: 'b' *
725 725 checking for directory renames
726 726 resolving manifests
727 overwrite: False, partial: False
727 branchmerge: True, force: False, partial: False
728 728 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
729 729 b: local copied/moved to a -> m
730 730 preserving b for resolve of b
731 731 c: remote created -> g
732 732 rev: versions differ -> m
733 733 preserving rev for resolve of rev
734 734 updating: b 1/3 files (33.33%)
735 735 picked tool 'python ../merge' for b (binary False symlink False)
736 736 merging b and a to b
737 737 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
738 738 premerge successful
739 739 updating: c 2/3 files (66.67%)
740 740 getting c
741 741 updating: rev 3/3 files (100.00%)
742 742 picked tool 'python ../merge' for rev (binary False symlink False)
743 743 merging rev
744 744 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
745 745 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
746 746 (branch merge, don't forget to commit)
747 747 --------------
748 748 M b
749 749 a
750 750 M c
751 751 --------------
752 752
753 753
754 754 $ cd ..
@@ -1,1088 +1,1088 b''
1 1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2 2
3 3 $ echo "[ui]" >> $HGRCPATH
4 4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5 5
6 6 $ hg init t
7 7 $ cd t
8 8
9 9 first revision, no sub
10 10
11 11 $ echo a > a
12 12 $ hg ci -Am0
13 13 adding a
14 14
15 15 add first sub
16 16
17 17 $ echo s = s > .hgsub
18 18 $ hg add .hgsub
19 19 $ hg init s
20 20 $ echo a > s/a
21 21
22 22 Issue2232: committing a subrepo without .hgsub
23 23
24 24 $ hg ci -mbad s
25 25 abort: can't commit subrepos without .hgsub
26 26 [255]
27 27
28 28 $ hg -R s ci -Ams0
29 29 adding a
30 30 $ hg sum
31 31 parent: 0:f7b1eb17ad24 tip
32 32 0
33 33 branch: default
34 34 commit: 1 added, 1 subrepos
35 35 update: (current)
36 36 $ hg ci -m1
37 37
38 38 Revert subrepo and test subrepo fileset keyword:
39 39
40 40 $ echo b > s/a
41 41 $ hg revert "set:subrepo('glob:s*')"
42 42 reverting subrepo s
43 43 reverting s/a (glob)
44 44 $ rm s/a.orig
45 45
46 46 Revert subrepo with no backup. The "reverting s/a" line is gone since
47 47 we're really running 'hg update' in the subrepo:
48 48
49 49 $ echo b > s/a
50 50 $ hg revert --no-backup s
51 51 reverting subrepo s
52 52
53 53 Issue2022: update -C
54 54
55 55 $ echo b > s/a
56 56 $ hg sum
57 57 parent: 1:7cf8cfea66e4 tip
58 58 1
59 59 branch: default
60 60 commit: 1 subrepos
61 61 update: (current)
62 62 $ hg co -C 1
63 63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 64 $ hg sum
65 65 parent: 1:7cf8cfea66e4 tip
66 66 1
67 67 branch: default
68 68 commit: (clean)
69 69 update: (current)
70 70
71 71 commands that require a clean repo should respect subrepos
72 72
73 73 $ echo b >> s/a
74 74 $ hg backout tip
75 75 abort: uncommitted changes in subrepo s
76 76 [255]
77 77 $ hg revert -C -R s s/a
78 78
79 79 add sub sub
80 80
81 81 $ echo ss = ss > s/.hgsub
82 82 $ hg init s/ss
83 83 $ echo a > s/ss/a
84 84 $ hg -R s add s/.hgsub
85 85 $ hg -R s/ss add s/ss/a
86 86 $ hg sum
87 87 parent: 1:7cf8cfea66e4 tip
88 88 1
89 89 branch: default
90 90 commit: 1 subrepos
91 91 update: (current)
92 92 $ hg ci -m2
93 93 committing subrepository s
94 94 committing subrepository s/ss (glob)
95 95 $ hg sum
96 96 parent: 2:df30734270ae tip
97 97 2
98 98 branch: default
99 99 commit: (clean)
100 100 update: (current)
101 101
102 102 bump sub rev (and check it is ignored by ui.commitsubrepos)
103 103
104 104 $ echo b > s/a
105 105 $ hg -R s ci -ms1
106 106 $ hg --config ui.commitsubrepos=no ci -m3
107 107
108 108 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
109 109
110 110 $ echo c > s/a
111 111 $ hg --config ui.commitsubrepos=no ci -m4
112 112 abort: uncommitted changes in subrepo s
113 113 (use --subrepos for recursive commit)
114 114 [255]
115 115 $ hg id
116 116 f6affe3fbfaa+ tip
117 117 $ hg -R s ci -mc
118 118 $ hg id
119 119 f6affe3fbfaa+ tip
120 120 $ echo d > s/a
121 121 $ hg ci -m4
122 122 committing subrepository s
123 123 $ hg tip -R s
124 124 changeset: 4:02dcf1d70411
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: 4
129 129
130 130
131 131 check caching
132 132
133 133 $ hg co 0
134 134 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
135 135 $ hg debugsub
136 136
137 137 restore
138 138
139 139 $ hg co
140 140 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 141 $ hg debugsub
142 142 path s
143 143 source s
144 144 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
145 145
146 146 new branch for merge tests
147 147
148 148 $ hg co 1
149 149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 150 $ echo t = t >> .hgsub
151 151 $ hg init t
152 152 $ echo t > t/t
153 153 $ hg -R t add t
154 154 adding t/t (glob)
155 155
156 156 5
157 157
158 158 $ hg ci -m5 # add sub
159 159 committing subrepository t
160 160 created new head
161 161 $ echo t2 > t/t
162 162
163 163 6
164 164
165 165 $ hg st -R s
166 166 $ hg ci -m6 # change sub
167 167 committing subrepository t
168 168 $ hg debugsub
169 169 path s
170 170 source s
171 171 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
172 172 path t
173 173 source t
174 174 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
175 175 $ echo t3 > t/t
176 176
177 177 7
178 178
179 179 $ hg ci -m7 # change sub again for conflict test
180 180 committing subrepository t
181 181 $ hg rm .hgsub
182 182
183 183 8
184 184
185 185 $ hg ci -m8 # remove sub
186 186
187 187 merge tests
188 188
189 189 $ hg co -C 3
190 190 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 191 $ hg merge 5 # test adding
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 (branch merge, don't forget to commit)
194 194 $ hg debugsub
195 195 path s
196 196 source s
197 197 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
198 198 path t
199 199 source t
200 200 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
201 201 $ hg ci -m9
202 202 created new head
203 203 $ hg merge 6 --debug # test change
204 204 searching for copies back to rev 2
205 205 resolving manifests
206 overwrite: False, partial: False
206 branchmerge: True, force: False, partial: False
207 207 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
208 208 .hgsubstate: versions differ -> m
209 209 updating: .hgsubstate 1/1 files (100.00%)
210 210 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
211 211 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
212 212 getting subrepo t
213 213 searching for copies back to rev 1
214 214 resolving manifests
215 overwrite: False, partial: False
215 branchmerge: False, force: False, partial: False
216 216 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
217 217 t: remote is newer -> g
218 218 updating: t 1/1 files (100.00%)
219 219 getting t
220 220 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 221 (branch merge, don't forget to commit)
222 222 $ hg debugsub
223 223 path s
224 224 source s
225 225 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
226 226 path t
227 227 source t
228 228 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
229 229 $ echo conflict > t/t
230 230 $ hg ci -m10
231 231 committing subrepository t
232 232 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
233 233 searching for copies back to rev 2
234 234 resolving manifests
235 overwrite: False, partial: False
235 branchmerge: True, force: False, partial: False
236 236 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
237 237 .hgsubstate: versions differ -> m
238 238 updating: .hgsubstate 1/1 files (100.00%)
239 239 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
240 240 subrepo t: both sides changed, merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
241 241 merging subrepo t
242 242 searching for copies back to rev 2
243 243 resolving manifests
244 overwrite: False, partial: False
244 branchmerge: True, force: False, partial: False
245 245 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
246 246 t: versions differ -> m
247 247 preserving t for resolve of t
248 248 updating: t 1/1 files (100.00%)
249 249 picked tool 'internal:merge' for t (binary False symlink False)
250 250 merging t
251 251 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
252 252 warning: conflicts during merge.
253 253 merging t incomplete! (edit conflicts, then use 'hg resolve --mark')
254 254 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
255 255 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
256 256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 257 (branch merge, don't forget to commit)
258 258
259 259 should conflict
260 260
261 261 $ cat t/t
262 262 <<<<<<< local
263 263 conflict
264 264 =======
265 265 t3
266 266 >>>>>>> other
267 267
268 268 clone
269 269
270 270 $ cd ..
271 271 $ hg clone t tc
272 272 updating to branch default
273 273 cloning subrepo s from $TESTTMP/t/s (glob)
274 274 cloning subrepo s/ss from $TESTTMP/t/s/ss (glob)
275 275 cloning subrepo t from $TESTTMP/t/t (glob)
276 276 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 277 $ cd tc
278 278 $ hg debugsub
279 279 path s
280 280 source s
281 281 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
282 282 path t
283 283 source t
284 284 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
285 285
286 286 push
287 287
288 288 $ echo bah > t/t
289 289 $ hg ci -m11
290 290 committing subrepository t
291 291 $ hg push
292 292 pushing to $TESTTMP/t (glob)
293 293 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
294 294 searching for changes
295 295 no changes found
296 296 pushing subrepo s to $TESTTMP/t/s (glob)
297 297 searching for changes
298 298 no changes found
299 299 pushing subrepo t to $TESTTMP/t/t (glob)
300 300 searching for changes
301 301 adding changesets
302 302 adding manifests
303 303 adding file changes
304 304 added 1 changesets with 1 changes to 1 files
305 305 searching for changes
306 306 adding changesets
307 307 adding manifests
308 308 adding file changes
309 309 added 1 changesets with 1 changes to 1 files
310 310
311 311 push -f
312 312
313 313 $ echo bah > s/a
314 314 $ hg ci -m12
315 315 committing subrepository s
316 316 $ hg push
317 317 pushing to $TESTTMP/t (glob)
318 318 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
319 319 searching for changes
320 320 no changes found
321 321 pushing subrepo s to $TESTTMP/t/s (glob)
322 322 searching for changes
323 323 abort: push creates new remote head 12a213df6fa9! (in subrepo s)
324 324 (did you forget to merge? use push -f to force)
325 325 [255]
326 326 $ hg push -f
327 327 pushing to $TESTTMP/t (glob)
328 328 pushing subrepo s/ss to $TESTTMP/t/s/ss (glob)
329 329 searching for changes
330 330 no changes found
331 331 pushing subrepo s to $TESTTMP/t/s (glob)
332 332 searching for changes
333 333 adding changesets
334 334 adding manifests
335 335 adding file changes
336 336 added 1 changesets with 1 changes to 1 files (+1 heads)
337 337 pushing subrepo t to $TESTTMP/t/t (glob)
338 338 searching for changes
339 339 no changes found
340 340 searching for changes
341 341 adding changesets
342 342 adding manifests
343 343 adding file changes
344 344 added 1 changesets with 1 changes to 1 files
345 345
346 346 update
347 347
348 348 $ cd ../t
349 349 $ hg up -C # discard our earlier merge
350 350 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
351 351 $ echo blah > t/t
352 352 $ hg ci -m13
353 353 committing subrepository t
354 354
355 355 pull
356 356
357 357 $ cd ../tc
358 358 $ hg pull
359 359 pulling from $TESTTMP/t (glob)
360 360 searching for changes
361 361 adding changesets
362 362 adding manifests
363 363 adding file changes
364 364 added 1 changesets with 1 changes to 1 files
365 365 (run 'hg update' to get a working copy)
366 366
367 367 should pull t
368 368
369 369 $ hg up
370 370 pulling subrepo t from $TESTTMP/t/t (glob)
371 371 searching for changes
372 372 adding changesets
373 373 adding manifests
374 374 adding file changes
375 375 added 1 changesets with 1 changes to 1 files
376 376 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
377 377 $ cat t/t
378 378 blah
379 379
380 380 bogus subrepo path aborts
381 381
382 382 $ echo 'bogus=[boguspath' >> .hgsub
383 383 $ hg ci -m 'bogus subrepo path'
384 384 abort: missing ] in subrepo source
385 385 [255]
386 386
387 387 Issue1986: merge aborts when trying to merge a subrepo that
388 388 shouldn't need merging
389 389
390 390 # subrepo layout
391 391 #
392 392 # o 5 br
393 393 # /|
394 394 # o | 4 default
395 395 # | |
396 396 # | o 3 br
397 397 # |/|
398 398 # o | 2 default
399 399 # | |
400 400 # | o 1 br
401 401 # |/
402 402 # o 0 default
403 403
404 404 $ cd ..
405 405 $ rm -rf sub
406 406 $ hg init main
407 407 $ cd main
408 408 $ hg init s
409 409 $ cd s
410 410 $ echo a > a
411 411 $ hg ci -Am1
412 412 adding a
413 413 $ hg branch br
414 414 marked working directory as branch br
415 415 (branches are permanent and global, did you want a bookmark?)
416 416 $ echo a >> a
417 417 $ hg ci -m1
418 418 $ hg up default
419 419 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
420 420 $ echo b > b
421 421 $ hg ci -Am1
422 422 adding b
423 423 $ hg up br
424 424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
425 425 $ hg merge tip
426 426 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 427 (branch merge, don't forget to commit)
428 428 $ hg ci -m1
429 429 $ hg up 2
430 430 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 431 $ echo c > c
432 432 $ hg ci -Am1
433 433 adding c
434 434 $ hg up 3
435 435 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
436 436 $ hg merge 4
437 437 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
438 438 (branch merge, don't forget to commit)
439 439 $ hg ci -m1
440 440
441 441 # main repo layout:
442 442 #
443 443 # * <-- try to merge default into br again
444 444 # .`|
445 445 # . o 5 br --> substate = 5
446 446 # . |
447 447 # o | 4 default --> substate = 4
448 448 # | |
449 449 # | o 3 br --> substate = 2
450 450 # |/|
451 451 # o | 2 default --> substate = 2
452 452 # | |
453 453 # | o 1 br --> substate = 3
454 454 # |/
455 455 # o 0 default --> substate = 2
456 456
457 457 $ cd ..
458 458 $ echo 's = s' > .hgsub
459 459 $ hg -R s up 2
460 460 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
461 461 $ hg ci -Am1
462 462 adding .hgsub
463 463 $ hg branch br
464 464 marked working directory as branch br
465 465 (branches are permanent and global, did you want a bookmark?)
466 466 $ echo b > b
467 467 $ hg -R s up 3
468 468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 469 $ hg ci -Am1
470 470 adding b
471 471 $ hg up default
472 472 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
473 473 $ echo c > c
474 474 $ hg ci -Am1
475 475 adding c
476 476 $ hg up 1
477 477 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
478 478 $ hg merge 2
479 479 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 480 (branch merge, don't forget to commit)
481 481 $ hg ci -m1
482 482 $ hg up 2
483 483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 484 $ hg -R s up 4
485 485 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 486 $ echo d > d
487 487 $ hg ci -Am1
488 488 adding d
489 489 $ hg up 3
490 490 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
491 491 $ hg -R s up 5
492 492 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
493 493 $ echo e > e
494 494 $ hg ci -Am1
495 495 adding e
496 496
497 497 $ hg up 5
498 498 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 499 $ hg merge 4 # try to merge default into br again
500 500 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
501 501 (branch merge, don't forget to commit)
502 502 $ cd ..
503 503
504 504 test subrepo delete from .hgsubstate
505 505
506 506 $ hg init testdelete
507 507 $ mkdir testdelete/nested testdelete/nested2
508 508 $ hg init testdelete/nested
509 509 $ hg init testdelete/nested2
510 510 $ echo test > testdelete/nested/foo
511 511 $ echo test > testdelete/nested2/foo
512 512 $ hg -R testdelete/nested add
513 513 adding testdelete/nested/foo (glob)
514 514 $ hg -R testdelete/nested2 add
515 515 adding testdelete/nested2/foo (glob)
516 516 $ hg -R testdelete/nested ci -m test
517 517 $ hg -R testdelete/nested2 ci -m test
518 518 $ echo nested = nested > testdelete/.hgsub
519 519 $ echo nested2 = nested2 >> testdelete/.hgsub
520 520 $ hg -R testdelete add
521 521 adding testdelete/.hgsub (glob)
522 522 $ hg -R testdelete ci -m "nested 1 & 2 added"
523 523 $ echo nested = nested > testdelete/.hgsub
524 524 $ hg -R testdelete ci -m "nested 2 deleted"
525 525 $ cat testdelete/.hgsubstate
526 526 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
527 527 $ hg -R testdelete remove testdelete/.hgsub
528 528 $ hg -R testdelete ci -m ".hgsub deleted"
529 529 $ cat testdelete/.hgsubstate
530 530 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
531 531
532 532 test repository cloning
533 533
534 534 $ mkdir mercurial mercurial2
535 535 $ hg init nested_absolute
536 536 $ echo test > nested_absolute/foo
537 537 $ hg -R nested_absolute add
538 538 adding nested_absolute/foo (glob)
539 539 $ hg -R nested_absolute ci -mtest
540 540 $ cd mercurial
541 541 $ hg init nested_relative
542 542 $ echo test2 > nested_relative/foo2
543 543 $ hg -R nested_relative add
544 544 adding nested_relative/foo2 (glob)
545 545 $ hg -R nested_relative ci -mtest2
546 546 $ hg init main
547 547 $ echo "nested_relative = ../nested_relative" > main/.hgsub
548 548 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
549 549 $ hg -R main add
550 550 adding main/.hgsub (glob)
551 551 $ hg -R main ci -m "add subrepos"
552 552 $ cd ..
553 553 $ hg clone mercurial/main mercurial2/main
554 554 updating to branch default
555 555 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
556 556 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
557 557 > mercurial2/main/nested_relative/.hg/hgrc
558 558 [paths]
559 559 default = $TESTTMP/mercurial/nested_absolute
560 560 [paths]
561 561 default = $TESTTMP/mercurial/nested_relative
562 562 $ rm -rf mercurial mercurial2
563 563
564 564 Issue1977: multirepo push should fail if subrepo push fails
565 565
566 566 $ hg init repo
567 567 $ hg init repo/s
568 568 $ echo a > repo/s/a
569 569 $ hg -R repo/s ci -Am0
570 570 adding a
571 571 $ echo s = s > repo/.hgsub
572 572 $ hg -R repo ci -Am1
573 573 adding .hgsub
574 574 $ hg clone repo repo2
575 575 updating to branch default
576 576 cloning subrepo s from $TESTTMP/repo/s (glob)
577 577 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
578 578 $ hg -q -R repo2 pull -u
579 579 $ echo 1 > repo2/s/a
580 580 $ hg -R repo2/s ci -m2
581 581 $ hg -q -R repo2/s push
582 582 $ hg -R repo2/s up -C 0
583 583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 584 $ echo 2 > repo2/s/b
585 585 $ hg -R repo2/s ci -m3 -A
586 586 adding b
587 587 created new head
588 588 $ hg -R repo2 ci -m3
589 589 $ hg -q -R repo2 push
590 590 abort: push creates new remote head cc505f09a8b2! (in subrepo s)
591 591 (did you forget to merge? use push -f to force)
592 592 [255]
593 593 $ hg -R repo update
594 594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 595
596 596 test if untracked file is not overwritten
597 597
598 598 $ echo issue3276_ok > repo/s/b
599 599 $ hg -R repo2 push -f -q
600 600 $ hg -R repo update
601 601 b: untracked file differs
602 602 abort: untracked files in working directory differ from files in requested revision (in subrepo s)
603 603 [255]
604 604
605 605 $ cat repo/s/b
606 606 issue3276_ok
607 607 $ rm repo/s/b
608 608 $ hg -R repo revert --all
609 609 reverting repo/.hgsubstate (glob)
610 610 reverting subrepo s
611 611 $ hg -R repo update
612 612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 613 $ cat repo/s/b
614 614 2
615 615 $ rm -rf repo2 repo
616 616
617 617
618 618 Issue1852 subrepos with relative paths always push/pull relative to default
619 619
620 620 Prepare a repo with subrepo
621 621
622 622 $ hg init issue1852a
623 623 $ cd issue1852a
624 624 $ hg init sub/repo
625 625 $ echo test > sub/repo/foo
626 626 $ hg -R sub/repo add sub/repo/foo
627 627 $ echo sub/repo = sub/repo > .hgsub
628 628 $ hg add .hgsub
629 629 $ hg ci -mtest
630 630 committing subrepository sub/repo (glob)
631 631 $ echo test >> sub/repo/foo
632 632 $ hg ci -mtest
633 633 committing subrepository sub/repo (glob)
634 634 $ cd ..
635 635
636 636 Create repo without default path, pull top repo, and see what happens on update
637 637
638 638 $ hg init issue1852b
639 639 $ hg -R issue1852b pull issue1852a
640 640 pulling from issue1852a
641 641 requesting all changes
642 642 adding changesets
643 643 adding manifests
644 644 adding file changes
645 645 added 2 changesets with 3 changes to 2 files
646 646 (run 'hg update' to get a working copy)
647 647 $ hg -R issue1852b update
648 648 abort: default path for subrepository not found (in subrepo sub/repo) (glob)
649 649 [255]
650 650
651 651 Pull -u now doesn't help
652 652
653 653 $ hg -R issue1852b pull -u issue1852a
654 654 pulling from issue1852a
655 655 searching for changes
656 656 no changes found
657 657
658 658 Try the same, but with pull -u
659 659
660 660 $ hg init issue1852c
661 661 $ hg -R issue1852c pull -r0 -u issue1852a
662 662 pulling from issue1852a
663 663 adding changesets
664 664 adding manifests
665 665 adding file changes
666 666 added 1 changesets with 2 changes to 2 files
667 667 cloning subrepo sub/repo from issue1852a/sub/repo (glob)
668 668 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
669 669
670 670 Try to push from the other side
671 671
672 672 $ hg -R issue1852a push `pwd`/issue1852c
673 673 pushing to $TESTTMP/issue1852c
674 674 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo (glob)
675 675 searching for changes
676 676 no changes found
677 677 searching for changes
678 678 adding changesets
679 679 adding manifests
680 680 adding file changes
681 681 added 1 changesets with 1 changes to 1 files
682 682
683 683 Incoming and outgoing should not use the default path:
684 684
685 685 $ hg clone -q issue1852a issue1852d
686 686 $ hg -R issue1852d outgoing --subrepos issue1852c
687 687 comparing with issue1852c
688 688 searching for changes
689 689 no changes found
690 690 comparing with issue1852c/sub/repo
691 691 searching for changes
692 692 no changes found
693 693 [1]
694 694 $ hg -R issue1852d incoming --subrepos issue1852c
695 695 comparing with issue1852c
696 696 searching for changes
697 697 no changes found
698 698 comparing with issue1852c/sub/repo
699 699 searching for changes
700 700 no changes found
701 701 [1]
702 702
703 703 Check status of files when none of them belong to the first
704 704 subrepository:
705 705
706 706 $ hg init subrepo-status
707 707 $ cd subrepo-status
708 708 $ hg init subrepo-1
709 709 $ hg init subrepo-2
710 710 $ cd subrepo-2
711 711 $ touch file
712 712 $ hg add file
713 713 $ cd ..
714 714 $ echo subrepo-1 = subrepo-1 > .hgsub
715 715 $ echo subrepo-2 = subrepo-2 >> .hgsub
716 716 $ hg add .hgsub
717 717 $ hg ci -m 'Added subrepos'
718 718 committing subrepository subrepo-2
719 719 $ hg st subrepo-2/file
720 720
721 721 Check that share works with subrepo
722 722 $ hg --config extensions.share= share . ../shared
723 723 updating working directory
724 724 cloning subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
725 725 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
726 726 $ test -f ../shared/subrepo-1/.hg/sharedpath
727 727 [1]
728 728 $ hg -R ../shared in
729 729 abort: repository default not found!
730 730 [255]
731 731 $ hg -R ../shared/subrepo-2 showconfig paths
732 732 paths.default=$TESTTMP/subrepo-status/subrepo-2
733 733 $ hg -R ../shared/subrepo-1 sum --remote
734 734 parent: -1:000000000000 tip (empty repository)
735 735 branch: default
736 736 commit: (clean)
737 737 update: (current)
738 738 remote: (synced)
739 739
740 740 Check hg update --clean
741 741 $ cd $TESTTMP/t
742 742 $ rm -r t/t.orig
743 743 $ hg status -S --all
744 744 C .hgsub
745 745 C .hgsubstate
746 746 C a
747 747 C s/.hgsub
748 748 C s/.hgsubstate
749 749 C s/a
750 750 C s/ss/a
751 751 C t/t
752 752 $ echo c1 > s/a
753 753 $ cd s
754 754 $ echo c1 > b
755 755 $ echo c1 > c
756 756 $ hg add b
757 757 $ cd ..
758 758 $ hg status -S
759 759 M s/a
760 760 A s/b
761 761 ? s/c
762 762 $ hg update -C
763 763 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
764 764 $ hg status -S
765 765 ? s/b
766 766 ? s/c
767 767
768 768 Sticky subrepositories, no changes
769 769 $ cd $TESTTMP/t
770 770 $ hg id
771 771 925c17564ef8 tip
772 772 $ hg -R s id
773 773 12a213df6fa9 tip
774 774 $ hg -R t id
775 775 52c0adc0515a tip
776 776 $ hg update 11
777 777 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 778 $ hg id
779 779 365661e5936a
780 780 $ hg -R s id
781 781 fc627a69481f
782 782 $ hg -R t id
783 783 e95bcfa18a35
784 784
785 785 Sticky subrepositorys, file changes
786 786 $ touch s/f1
787 787 $ touch t/f1
788 788 $ hg add -S s/f1
789 789 $ hg add -S t/f1
790 790 $ hg id
791 791 365661e5936a+
792 792 $ hg -R s id
793 793 fc627a69481f+
794 794 $ hg -R t id
795 795 e95bcfa18a35+
796 796 $ hg update tip
797 797 subrepository sources for s differ
798 798 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
799 799 l
800 800 subrepository sources for t differ
801 801 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)?
802 802 l
803 803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
804 804 $ hg id
805 805 925c17564ef8+ tip
806 806 $ hg -R s id
807 807 fc627a69481f+
808 808 $ hg -R t id
809 809 e95bcfa18a35+
810 810 $ hg update --clean tip
811 811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 812
813 813 Sticky subrepository, revision updates
814 814 $ hg id
815 815 925c17564ef8 tip
816 816 $ hg -R s id
817 817 12a213df6fa9 tip
818 818 $ hg -R t id
819 819 52c0adc0515a tip
820 820 $ cd s
821 821 $ hg update -r -2
822 822 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
823 823 $ cd ../t
824 824 $ hg update -r 2
825 825 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
826 826 $ cd ..
827 827 $ hg update 10
828 828 subrepository sources for t differ (in checked out version)
829 829 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)?
830 830 l
831 831 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 832 $ hg id
833 833 e45c8b14af55+
834 834 $ hg -R s id
835 835 02dcf1d70411
836 836 $ hg -R t id
837 837 7af322bc1198
838 838
839 839 Sticky subrepository, file changes and revision updates
840 840 $ touch s/f1
841 841 $ touch t/f1
842 842 $ hg add -S s/f1
843 843 $ hg add -S t/f1
844 844 $ hg id
845 845 e45c8b14af55+
846 846 $ hg -R s id
847 847 02dcf1d70411+
848 848 $ hg -R t id
849 849 7af322bc1198+
850 850 $ hg update tip
851 851 subrepository sources for s differ
852 852 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)?
853 853 l
854 854 subrepository sources for t differ
855 855 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)?
856 856 l
857 857 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
858 858 $ hg id
859 859 925c17564ef8+ tip
860 860 $ hg -R s id
861 861 02dcf1d70411+
862 862 $ hg -R t id
863 863 7af322bc1198+
864 864
865 865 Sticky repository, update --clean
866 866 $ hg update --clean tip
867 867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
868 868 $ hg id
869 869 925c17564ef8 tip
870 870 $ hg -R s id
871 871 12a213df6fa9 tip
872 872 $ hg -R t id
873 873 52c0adc0515a tip
874 874
875 875 Test subrepo already at intended revision:
876 876 $ cd s
877 877 $ hg update fc627a69481f
878 878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 879 $ cd ..
880 880 $ hg update 11
881 881 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 882 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
883 883 $ hg id -n
884 884 11+
885 885 $ hg -R s id
886 886 fc627a69481f
887 887 $ hg -R t id
888 888 e95bcfa18a35
889 889
890 890 Test that removing .hgsubstate doesn't break anything:
891 891
892 892 $ hg rm -f .hgsubstate
893 893 $ hg ci -mrm
894 894 nothing changed
895 895 [1]
896 896 $ hg log -vr tip
897 897 changeset: 13:925c17564ef8
898 898 tag: tip
899 899 user: test
900 900 date: Thu Jan 01 00:00:00 1970 +0000
901 901 files: .hgsubstate
902 902 description:
903 903 13
904 904
905 905
906 906
907 907 Test that removing .hgsub removes .hgsubstate:
908 908
909 909 $ hg rm .hgsub
910 910 $ hg ci -mrm2
911 911 created new head
912 912 $ hg log -vr tip
913 913 changeset: 14:2400bccd50af
914 914 tag: tip
915 915 parent: 11:365661e5936a
916 916 user: test
917 917 date: Thu Jan 01 00:00:00 1970 +0000
918 918 files: .hgsub .hgsubstate
919 919 description:
920 920 rm2
921 921
922 922
923 923 Test issue3153: diff -S with deleted subrepos
924 924
925 925 $ hg diff --nodates -S -c .
926 926 diff -r 365661e5936a -r 2400bccd50af .hgsub
927 927 --- a/.hgsub
928 928 +++ /dev/null
929 929 @@ -1,2 +0,0 @@
930 930 -s = s
931 931 -t = t
932 932 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
933 933 --- a/.hgsubstate
934 934 +++ /dev/null
935 935 @@ -1,2 +0,0 @@
936 936 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
937 937 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
938 938
939 939 Test behavior of add for explicit path in subrepo:
940 940 $ cd ..
941 941 $ hg init explicit
942 942 $ cd explicit
943 943 $ echo s = s > .hgsub
944 944 $ hg add .hgsub
945 945 $ hg init s
946 946 $ hg ci -m0
947 947 Adding with an explicit path in a subrepo adds the file
948 948 $ echo c1 > f1
949 949 $ echo c2 > s/f2
950 950 $ hg st -S
951 951 ? f1
952 952 ? s/f2
953 953 $ hg add s/f2
954 954 $ hg st -S
955 955 A s/f2
956 956 ? f1
957 957 $ hg ci -R s -m0
958 958 $ hg ci -Am1
959 959 adding f1
960 960 Adding with an explicit path in a subrepo with -S has the same behavior
961 961 $ echo c3 > f3
962 962 $ echo c4 > s/f4
963 963 $ hg st -S
964 964 ? f3
965 965 ? s/f4
966 966 $ hg add -S s/f4
967 967 $ hg st -S
968 968 A s/f4
969 969 ? f3
970 970 $ hg ci -R s -m1
971 971 $ hg ci -Ama2
972 972 adding f3
973 973 Adding without a path or pattern silently ignores subrepos
974 974 $ echo c5 > f5
975 975 $ echo c6 > s/f6
976 976 $ echo c7 > s/f7
977 977 $ hg st -S
978 978 ? f5
979 979 ? s/f6
980 980 ? s/f7
981 981 $ hg add
982 982 adding f5
983 983 $ hg st -S
984 984 A f5
985 985 ? s/f6
986 986 ? s/f7
987 987 $ hg ci -R s -Am2
988 988 adding f6
989 989 adding f7
990 990 $ hg ci -m3
991 991 Adding without a path or pattern with -S also adds files in subrepos
992 992 $ echo c8 > f8
993 993 $ echo c9 > s/f9
994 994 $ echo c10 > s/f10
995 995 $ hg st -S
996 996 ? f8
997 997 ? s/f10
998 998 ? s/f9
999 999 $ hg add -S
1000 1000 adding f8
1001 1001 adding s/f10 (glob)
1002 1002 adding s/f9 (glob)
1003 1003 $ hg st -S
1004 1004 A f8
1005 1005 A s/f10
1006 1006 A s/f9
1007 1007 $ hg ci -R s -m3
1008 1008 $ hg ci -m4
1009 1009 Adding with a pattern silently ignores subrepos
1010 1010 $ echo c11 > fm11
1011 1011 $ echo c12 > fn12
1012 1012 $ echo c13 > s/fm13
1013 1013 $ echo c14 > s/fn14
1014 1014 $ hg st -S
1015 1015 ? fm11
1016 1016 ? fn12
1017 1017 ? s/fm13
1018 1018 ? s/fn14
1019 1019 $ hg add 'glob:**fm*'
1020 1020 adding fm11
1021 1021 $ hg st -S
1022 1022 A fm11
1023 1023 ? fn12
1024 1024 ? s/fm13
1025 1025 ? s/fn14
1026 1026 $ hg ci -R s -Am4
1027 1027 adding fm13
1028 1028 adding fn14
1029 1029 $ hg ci -Am5
1030 1030 adding fn12
1031 1031 Adding with a pattern with -S also adds matches in subrepos
1032 1032 $ echo c15 > fm15
1033 1033 $ echo c16 > fn16
1034 1034 $ echo c17 > s/fm17
1035 1035 $ echo c18 > s/fn18
1036 1036 $ hg st -S
1037 1037 ? fm15
1038 1038 ? fn16
1039 1039 ? s/fm17
1040 1040 ? s/fn18
1041 1041 $ hg add -S 'glob:**fm*'
1042 1042 adding fm15
1043 1043 adding s/fm17 (glob)
1044 1044 $ hg st -S
1045 1045 A fm15
1046 1046 A s/fm17
1047 1047 ? fn16
1048 1048 ? s/fn18
1049 1049 $ hg ci -R s -Am5
1050 1050 adding fn18
1051 1051 $ hg ci -Am6
1052 1052 adding fn16
1053 1053
1054 1054 Test behavior of forget for explicit path in subrepo:
1055 1055 Forgetting an explicit path in a subrepo untracks the file
1056 1056 $ echo c19 > s/f19
1057 1057 $ hg add s/f19
1058 1058 $ hg st -S
1059 1059 A s/f19
1060 1060 $ hg forget s/f19
1061 1061 $ hg st -S
1062 1062 ? s/f19
1063 1063 $ rm s/f19
1064 1064 $ cd ..
1065 1065
1066 1066 Courtesy phases synchronisation to publishing server does not block the push
1067 1067 (issue3781)
1068 1068
1069 1069 $ cp -r main issue3781
1070 1070 $ cp -r main issue3781-dest
1071 1071 $ cd issue3781-dest/s
1072 1072 $ hg phase tip # show we have draft changeset
1073 1073 5: draft
1074 1074 $ chmod a-w .hg/store/phaseroots # prevent phase push
1075 1075 $ cd ../../issue3781
1076 1076 $ cat >> .hg/hgrc << EOF
1077 1077 > [paths]
1078 1078 > default=../issue3781-dest/
1079 1079 > EOF
1080 1080 $ hg push
1081 1081 pushing to $TESTTMP/issue3781-dest (glob)
1082 1082 pushing subrepo s to $TESTTMP/issue3781-dest/s
1083 1083 searching for changes
1084 1084 no changes found
1085 1085 searching for changes
1086 1086 no changes found
1087 1087 [1]
1088 1088
@@ -1,238 +1,238 b''
1 1 $ HGMERGE=true; export HGMERGE
2 2
3 3 $ hg init r1
4 4 $ cd r1
5 5 $ echo a > a
6 6 $ hg addremove
7 7 adding a
8 8 $ hg commit -m "1"
9 9
10 10 $ hg clone . ../r2
11 11 updating to branch default
12 12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 13 $ cd ../r2
14 14 $ hg up
15 15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 16 $ echo abc > a
17 17 $ hg diff --nodates
18 18 diff -r c19d34741b0a a
19 19 --- a/a
20 20 +++ b/a
21 21 @@ -1,1 +1,1 @@
22 22 -a
23 23 +abc
24 24
25 25 $ cd ../r1
26 26 $ echo b > b
27 27 $ echo a2 > a
28 28 $ hg addremove
29 29 adding b
30 30 $ hg commit -m "2"
31 31
32 32 $ cd ../r2
33 33 $ hg -q pull ../r1
34 34 $ hg status
35 35 M a
36 36 $ hg parents
37 37 changeset: 0:c19d34741b0a
38 38 user: test
39 39 date: Thu Jan 01 00:00:00 1970 +0000
40 40 summary: 1
41 41
42 42 $ hg --debug up
43 43 searching for copies back to rev 1
44 44 unmatched files in other:
45 45 b
46 46 resolving manifests
47 overwrite: False, partial: False
47 branchmerge: False, force: False, partial: False
48 48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
49 49 a: versions differ -> m
50 50 preserving a for resolve of a
51 51 b: remote created -> g
52 52 updating: a 1/2 files (50.00%)
53 53 picked tool 'true' for a (binary False symlink False)
54 54 merging a
55 55 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
56 56 updating: b 2/2 files (100.00%)
57 57 getting b
58 58 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
59 59 $ hg parents
60 60 changeset: 1:1e71731e6fbb
61 61 tag: tip
62 62 user: test
63 63 date: Thu Jan 01 00:00:00 1970 +0000
64 64 summary: 2
65 65
66 66 $ hg --debug up 0
67 67 resolving manifests
68 overwrite: False, partial: False
68 branchmerge: False, force: False, partial: False
69 69 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
70 70 b: other deleted -> r
71 71 a: versions differ -> m
72 72 preserving a for resolve of a
73 73 updating: b 1/2 files (50.00%)
74 74 removing b
75 75 updating: a 2/2 files (100.00%)
76 76 picked tool 'true' for a (binary False symlink False)
77 77 merging a
78 78 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
79 79 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
80 80 $ hg parents
81 81 changeset: 0:c19d34741b0a
82 82 user: test
83 83 date: Thu Jan 01 00:00:00 1970 +0000
84 84 summary: 1
85 85
86 86 $ hg --debug merge
87 87 abort: nothing to merge
88 88 (use 'hg update' instead)
89 89 [255]
90 90 $ hg parents
91 91 changeset: 0:c19d34741b0a
92 92 user: test
93 93 date: Thu Jan 01 00:00:00 1970 +0000
94 94 summary: 1
95 95
96 96 $ hg --debug up
97 97 searching for copies back to rev 1
98 98 unmatched files in other:
99 99 b
100 100 resolving manifests
101 overwrite: False, partial: False
101 branchmerge: False, force: False, partial: False
102 102 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
103 103 a: versions differ -> m
104 104 preserving a for resolve of a
105 105 b: remote created -> g
106 106 updating: a 1/2 files (50.00%)
107 107 picked tool 'true' for a (binary False symlink False)
108 108 merging a
109 109 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
110 110 updating: b 2/2 files (100.00%)
111 111 getting b
112 112 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
113 113 $ hg parents
114 114 changeset: 1:1e71731e6fbb
115 115 tag: tip
116 116 user: test
117 117 date: Thu Jan 01 00:00:00 1970 +0000
118 118 summary: 2
119 119
120 120 $ hg -v history
121 121 changeset: 1:1e71731e6fbb
122 122 tag: tip
123 123 user: test
124 124 date: Thu Jan 01 00:00:00 1970 +0000
125 125 files: a b
126 126 description:
127 127 2
128 128
129 129
130 130 changeset: 0:c19d34741b0a
131 131 user: test
132 132 date: Thu Jan 01 00:00:00 1970 +0000
133 133 files: a
134 134 description:
135 135 1
136 136
137 137
138 138 $ hg diff --nodates
139 139 diff -r 1e71731e6fbb a
140 140 --- a/a
141 141 +++ b/a
142 142 @@ -1,1 +1,1 @@
143 143 -a2
144 144 +abc
145 145
146 146
147 147 create a second head
148 148
149 149 $ cd ../r1
150 150 $ hg up 0
151 151 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
152 152 $ echo b2 > b
153 153 $ echo a3 > a
154 154 $ hg addremove
155 155 adding b
156 156 $ hg commit -m "3"
157 157 created new head
158 158
159 159 $ cd ../r2
160 160 $ hg -q pull ../r1
161 161 $ hg status
162 162 M a
163 163 $ hg parents
164 164 changeset: 1:1e71731e6fbb
165 165 user: test
166 166 date: Thu Jan 01 00:00:00 1970 +0000
167 167 summary: 2
168 168
169 169 $ hg --debug up
170 170 abort: crosses branches (merge branches or use --clean to discard changes)
171 171 [255]
172 172 $ hg --debug merge
173 173 abort: outstanding uncommitted changes
174 174 (use 'hg status' to list changes)
175 175 [255]
176 176 $ hg --debug merge -f
177 177 searching for copies back to rev 1
178 178 resolving manifests
179 overwrite: False, partial: False
179 branchmerge: True, force: True, partial: False
180 180 ancestor: c19d34741b0a, local: 1e71731e6fbb+, remote: 83c51d0caff4
181 181 a: versions differ -> m
182 182 preserving a for resolve of a
183 183 b: versions differ -> m
184 184 preserving b for resolve of b
185 185 updating: a 1/2 files (50.00%)
186 186 picked tool 'true' for a (binary False symlink False)
187 187 merging a
188 188 my a@1e71731e6fbb+ other a@83c51d0caff4 ancestor a@c19d34741b0a
189 189 updating: b 2/2 files (100.00%)
190 190 picked tool 'true' for b (binary False symlink False)
191 191 merging b
192 192 my b@1e71731e6fbb+ other b@83c51d0caff4 ancestor b@000000000000
193 193 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
194 194 (branch merge, don't forget to commit)
195 195 $ hg parents
196 196 changeset: 1:1e71731e6fbb
197 197 user: test
198 198 date: Thu Jan 01 00:00:00 1970 +0000
199 199 summary: 2
200 200
201 201 changeset: 2:83c51d0caff4
202 202 tag: tip
203 203 parent: 0:c19d34741b0a
204 204 user: test
205 205 date: Thu Jan 01 00:00:00 1970 +0000
206 206 summary: 3
207 207
208 208 $ hg diff --nodates
209 209 diff -r 1e71731e6fbb a
210 210 --- a/a
211 211 +++ b/a
212 212 @@ -1,1 +1,1 @@
213 213 -a2
214 214 +abc
215 215
216 216
217 217 test a local add
218 218
219 219 $ cd ..
220 220 $ hg init a
221 221 $ hg init b
222 222 $ echo a > a/a
223 223 $ echo a > b/a
224 224 $ hg --cwd a commit -A -m a
225 225 adding a
226 226 $ cd b
227 227 $ hg add a
228 228 $ hg pull -u ../a
229 229 pulling from ../a
230 230 requesting all changes
231 231 adding changesets
232 232 adding manifests
233 233 adding file changes
234 234 added 1 changesets with 1 changes to 1 files
235 235 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
236 236 $ hg st
237 237
238 238 $ cd ..
@@ -1,85 +1,85 b''
1 1 $ hg init
2 2
3 3 $ touch a
4 4 $ hg add a
5 5 $ hg commit -m "Added a"
6 6
7 7 $ touch main
8 8 $ hg add main
9 9 $ hg commit -m "Added main"
10 10 $ hg checkout 0
11 11 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
12 12
13 13 'main' should be gone:
14 14
15 15 $ ls
16 16 a
17 17
18 18 $ touch side1
19 19 $ hg add side1
20 20 $ hg commit -m "Added side1"
21 21 created new head
22 22 $ touch side2
23 23 $ hg add side2
24 24 $ hg commit -m "Added side2"
25 25
26 26 $ hg log
27 27 changeset: 3:91ebc10ed028
28 28 tag: tip
29 29 user: test
30 30 date: Thu Jan 01 00:00:00 1970 +0000
31 31 summary: Added side2
32 32
33 33 changeset: 2:b932d7dbb1e1
34 34 parent: 0:c2eda428b523
35 35 user: test
36 36 date: Thu Jan 01 00:00:00 1970 +0000
37 37 summary: Added side1
38 38
39 39 changeset: 1:71a760306caf
40 40 user: test
41 41 date: Thu Jan 01 00:00:00 1970 +0000
42 42 summary: Added main
43 43
44 44 changeset: 0:c2eda428b523
45 45 user: test
46 46 date: Thu Jan 01 00:00:00 1970 +0000
47 47 summary: Added a
48 48
49 49
50 50 $ hg heads
51 51 changeset: 3:91ebc10ed028
52 52 tag: tip
53 53 user: test
54 54 date: Thu Jan 01 00:00:00 1970 +0000
55 55 summary: Added side2
56 56
57 57 changeset: 1:71a760306caf
58 58 user: test
59 59 date: Thu Jan 01 00:00:00 1970 +0000
60 60 summary: Added main
61 61
62 62 $ ls
63 63 a
64 64 side1
65 65 side2
66 66
67 67 $ hg update --debug -C 1
68 68 resolving manifests
69 overwrite: True, partial: False
69 branchmerge: False, force: True, partial: False
70 70 ancestor: 91ebc10ed028+, local: 91ebc10ed028+, remote: 71a760306caf
71 71 side1: other deleted -> r
72 72 side2: other deleted -> r
73 73 main: remote created -> g
74 74 updating: side1 1/3 files (33.33%)
75 75 removing side1
76 76 updating: side2 2/3 files (66.67%)
77 77 removing side2
78 78 updating: main 3/3 files (100.00%)
79 79 getting main
80 80 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
81 81
82 82 $ ls
83 83 a
84 84 main
85 85
General Comments 0
You need to be logged in to leave comments. Login now