##// END OF EJS Templates
merge: make error message consistent with other commands...
Martin von Zweigbergk -
r22841:18b38691 default
parent child Browse files
Show More
@@ -1,1151 +1,1151 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 import struct
9 9
10 10 from node import nullid, nullrev, hex, bin
11 11 from i18n import _
12 12 from mercurial import obsolete
13 13 import error as errormod, util, filemerge, copies, subrepo, worker, dicthelpers
14 14 import errno, os, shutil
15 15
16 16 _pack = struct.pack
17 17 _unpack = struct.unpack
18 18
19 19 def _droponode(data):
20 20 # used for compatibility for v1
21 21 bits = data.split("\0")
22 22 bits = bits[:-2] + bits[-1:]
23 23 return "\0".join(bits)
24 24
25 25 class mergestate(object):
26 26 '''track 3-way merge state of individual files
27 27
28 28 it is stored on disk when needed. Two file are used, one with an old
29 29 format, one with a new format. Both contains similar data, but the new
30 30 format can store new kind of field.
31 31
32 32 Current new format is a list of arbitrary record of the form:
33 33
34 34 [type][length][content]
35 35
36 36 Type is a single character, length is a 4 bytes integer, content is an
37 37 arbitrary suites of bytes of length `length`.
38 38
39 39 Type should be a letter. Capital letter are mandatory record, Mercurial
40 40 should abort if they are unknown. lower case record can be safely ignored.
41 41
42 42 Currently known record:
43 43
44 44 L: the node of the "local" part of the merge (hexified version)
45 45 O: the node of the "other" part of the merge (hexified version)
46 46 F: a file to be merged entry
47 47 '''
48 48 statepathv1 = "merge/state"
49 49 statepathv2 = "merge/state2"
50 50
51 51 def __init__(self, repo):
52 52 self._repo = repo
53 53 self._dirty = False
54 54 self._read()
55 55
56 56 def reset(self, node=None, other=None):
57 57 self._state = {}
58 58 self._local = None
59 59 self._other = None
60 60 if node:
61 61 self._local = node
62 62 self._other = other
63 63 shutil.rmtree(self._repo.join("merge"), True)
64 64 self._dirty = False
65 65
66 66 def _read(self):
67 67 """Analyse each record content to restore a serialized state from disk
68 68
69 69 This function process "record" entry produced by the de-serialization
70 70 of on disk file.
71 71 """
72 72 self._state = {}
73 73 self._local = None
74 74 self._other = None
75 75 records = self._readrecords()
76 76 for rtype, record in records:
77 77 if rtype == 'L':
78 78 self._local = bin(record)
79 79 elif rtype == 'O':
80 80 self._other = bin(record)
81 81 elif rtype == "F":
82 82 bits = record.split("\0")
83 83 self._state[bits[0]] = bits[1:]
84 84 elif not rtype.islower():
85 85 raise util.Abort(_('unsupported merge state record: %s')
86 86 % rtype)
87 87 self._dirty = False
88 88
89 89 def _readrecords(self):
90 90 """Read merge state from disk and return a list of record (TYPE, data)
91 91
92 92 We read data from both v1 and v2 files and decide which one to use.
93 93
94 94 V1 has been used by version prior to 2.9.1 and contains less data than
95 95 v2. We read both versions and check if no data in v2 contradicts
96 96 v1. If there is not contradiction we can safely assume that both v1
97 97 and v2 were written at the same time and use the extract data in v2. If
98 98 there is contradiction we ignore v2 content as we assume an old version
99 99 of Mercurial has overwritten the mergestate file and left an old v2
100 100 file around.
101 101
102 102 returns list of record [(TYPE, data), ...]"""
103 103 v1records = self._readrecordsv1()
104 104 v2records = self._readrecordsv2()
105 105 oldv2 = set() # old format version of v2 record
106 106 for rec in v2records:
107 107 if rec[0] == 'L':
108 108 oldv2.add(rec)
109 109 elif rec[0] == 'F':
110 110 # drop the onode data (not contained in v1)
111 111 oldv2.add(('F', _droponode(rec[1])))
112 112 for rec in v1records:
113 113 if rec not in oldv2:
114 114 # v1 file is newer than v2 file, use it
115 115 # we have to infer the "other" changeset of the merge
116 116 # we cannot do better than that with v1 of the format
117 117 mctx = self._repo[None].parents()[-1]
118 118 v1records.append(('O', mctx.hex()))
119 119 # add place holder "other" file node information
120 120 # nobody is using it yet so we do no need to fetch the data
121 121 # if mctx was wrong `mctx[bits[-2]]` may fails.
122 122 for idx, r in enumerate(v1records):
123 123 if r[0] == 'F':
124 124 bits = r[1].split("\0")
125 125 bits.insert(-2, '')
126 126 v1records[idx] = (r[0], "\0".join(bits))
127 127 return v1records
128 128 else:
129 129 return v2records
130 130
131 131 def _readrecordsv1(self):
132 132 """read on disk merge state for version 1 file
133 133
134 134 returns list of record [(TYPE, data), ...]
135 135
136 136 Note: the "F" data from this file are one entry short
137 137 (no "other file node" entry)
138 138 """
139 139 records = []
140 140 try:
141 141 f = self._repo.opener(self.statepathv1)
142 142 for i, l in enumerate(f):
143 143 if i == 0:
144 144 records.append(('L', l[:-1]))
145 145 else:
146 146 records.append(('F', l[:-1]))
147 147 f.close()
148 148 except IOError, err:
149 149 if err.errno != errno.ENOENT:
150 150 raise
151 151 return records
152 152
153 153 def _readrecordsv2(self):
154 154 """read on disk merge state for version 2 file
155 155
156 156 returns list of record [(TYPE, data), ...]
157 157 """
158 158 records = []
159 159 try:
160 160 f = self._repo.opener(self.statepathv2)
161 161 data = f.read()
162 162 off = 0
163 163 end = len(data)
164 164 while off < end:
165 165 rtype = data[off]
166 166 off += 1
167 167 length = _unpack('>I', data[off:(off + 4)])[0]
168 168 off += 4
169 169 record = data[off:(off + length)]
170 170 off += length
171 171 records.append((rtype, record))
172 172 f.close()
173 173 except IOError, err:
174 174 if err.errno != errno.ENOENT:
175 175 raise
176 176 return records
177 177
178 178 def active(self):
179 179 """Whether mergestate is active.
180 180
181 181 Returns True if there appears to be mergestate. This is a rough proxy
182 182 for "is a merge in progress."
183 183 """
184 184 # Check local variables before looking at filesystem for performance
185 185 # reasons.
186 186 return bool(self._local) or bool(self._state) or \
187 187 self._repo.opener.exists(self.statepathv1) or \
188 188 self._repo.opener.exists(self.statepathv2)
189 189
190 190 def commit(self):
191 191 """Write current state on disk (if necessary)"""
192 192 if self._dirty:
193 193 records = []
194 194 records.append(("L", hex(self._local)))
195 195 records.append(("O", hex(self._other)))
196 196 for d, v in self._state.iteritems():
197 197 records.append(("F", "\0".join([d] + v)))
198 198 self._writerecords(records)
199 199 self._dirty = False
200 200
201 201 def _writerecords(self, records):
202 202 """Write current state on disk (both v1 and v2)"""
203 203 self._writerecordsv1(records)
204 204 self._writerecordsv2(records)
205 205
206 206 def _writerecordsv1(self, records):
207 207 """Write current state on disk in a version 1 file"""
208 208 f = self._repo.opener(self.statepathv1, "w")
209 209 irecords = iter(records)
210 210 lrecords = irecords.next()
211 211 assert lrecords[0] == 'L'
212 212 f.write(hex(self._local) + "\n")
213 213 for rtype, data in irecords:
214 214 if rtype == "F":
215 215 f.write("%s\n" % _droponode(data))
216 216 f.close()
217 217
218 218 def _writerecordsv2(self, records):
219 219 """Write current state on disk in a version 2 file"""
220 220 f = self._repo.opener(self.statepathv2, "w")
221 221 for key, data in records:
222 222 assert len(key) == 1
223 223 format = ">sI%is" % len(data)
224 224 f.write(_pack(format, key, len(data), data))
225 225 f.close()
226 226
227 227 def add(self, fcl, fco, fca, fd):
228 228 """add a new (potentially?) conflicting file the merge state
229 229 fcl: file context for local,
230 230 fco: file context for remote,
231 231 fca: file context for ancestors,
232 232 fd: file path of the resulting merge.
233 233
234 234 note: also write the local version to the `.hg/merge` directory.
235 235 """
236 236 hash = util.sha1(fcl.path()).hexdigest()
237 237 self._repo.opener.write("merge/" + hash, fcl.data())
238 238 self._state[fd] = ['u', hash, fcl.path(),
239 239 fca.path(), hex(fca.filenode()),
240 240 fco.path(), hex(fco.filenode()),
241 241 fcl.flags()]
242 242 self._dirty = True
243 243
244 244 def __contains__(self, dfile):
245 245 return dfile in self._state
246 246
247 247 def __getitem__(self, dfile):
248 248 return self._state[dfile][0]
249 249
250 250 def __iter__(self):
251 251 return iter(sorted(self._state))
252 252
253 253 def files(self):
254 254 return self._state.keys()
255 255
256 256 def mark(self, dfile, state):
257 257 self._state[dfile][0] = state
258 258 self._dirty = True
259 259
260 260 def unresolved(self):
261 261 """Obtain the paths of unresolved files."""
262 262
263 263 for f, entry in self._state.items():
264 264 if entry[0] == 'u':
265 265 yield f
266 266
267 267 def resolve(self, dfile, wctx, labels=None):
268 268 """rerun merge process for file path `dfile`"""
269 269 if self[dfile] == 'r':
270 270 return 0
271 271 stateentry = self._state[dfile]
272 272 state, hash, lfile, afile, anode, ofile, onode, flags = stateentry
273 273 octx = self._repo[self._other]
274 274 fcd = wctx[dfile]
275 275 fco = octx[ofile]
276 276 fca = self._repo.filectx(afile, fileid=anode)
277 277 # "premerge" x flags
278 278 flo = fco.flags()
279 279 fla = fca.flags()
280 280 if 'x' in flags + flo + fla and 'l' not in flags + flo + fla:
281 281 if fca.node() == nullid:
282 282 self._repo.ui.warn(_('warning: cannot merge flags for %s\n') %
283 283 afile)
284 284 elif flags == fla:
285 285 flags = flo
286 286 # restore local
287 287 f = self._repo.opener("merge/" + hash)
288 288 self._repo.wwrite(dfile, f.read(), flags)
289 289 f.close()
290 290 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca,
291 291 labels=labels)
292 292 if r is None:
293 293 # no real conflict
294 294 del self._state[dfile]
295 295 self._dirty = True
296 296 elif not r:
297 297 self.mark(dfile, 'r')
298 298 return r
299 299
300 300 def _checkunknownfile(repo, wctx, mctx, f):
301 301 return (not repo.dirstate._ignore(f)
302 302 and os.path.isfile(repo.wjoin(f))
303 303 and repo.wopener.audit.check(f)
304 304 and repo.dirstate.normalize(f) not in repo.dirstate
305 305 and mctx[f].cmp(wctx[f]))
306 306
307 307 def _checkunknown(repo, wctx, mctx):
308 308 "check for collisions between unknown files and files in mctx"
309 309
310 310 error = False
311 311 for f in mctx:
312 312 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
313 313 error = True
314 314 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
315 315 if error:
316 316 raise util.Abort(_("untracked files in working directory differ "
317 317 "from files in requested revision"))
318 318
319 319 def _forgetremoved(wctx, mctx, branchmerge):
320 320 """
321 321 Forget removed files
322 322
323 323 If we're jumping between revisions (as opposed to merging), and if
324 324 neither the working directory nor the target rev has the file,
325 325 then we need to remove it from the dirstate, to prevent the
326 326 dirstate from listing the file when it is no longer in the
327 327 manifest.
328 328
329 329 If we're merging, and the other revision has removed a file
330 330 that is not present in the working directory, we need to mark it
331 331 as removed.
332 332 """
333 333
334 334 ractions = []
335 335 factions = xactions = []
336 336 if branchmerge:
337 337 xactions = ractions
338 338 for f in wctx.deleted():
339 339 if f not in mctx:
340 340 xactions.append((f, None, "forget deleted"))
341 341
342 342 if not branchmerge:
343 343 for f in wctx.removed():
344 344 if f not in mctx:
345 345 factions.append((f, None, "forget removed"))
346 346
347 347 return ractions, factions
348 348
349 349 def _checkcollision(repo, wmf, actions):
350 350 # build provisional merged manifest up
351 351 pmmf = set(wmf)
352 352
353 353 if actions:
354 354 # k, dr, e and rd are no-op
355 355 for m in 'a', 'f', 'g', 'cd', 'dc':
356 356 for f, args, msg in actions[m]:
357 357 pmmf.add(f)
358 358 for f, args, msg in actions['r']:
359 359 pmmf.discard(f)
360 360 for f, args, msg in actions['dm']:
361 361 f2, flags = args
362 362 pmmf.discard(f2)
363 363 pmmf.add(f)
364 364 for f, args, msg in actions['dg']:
365 365 f2, flags = args
366 366 pmmf.add(f)
367 367 for f, args, msg in actions['m']:
368 368 f1, f2, fa, move, anc = args
369 369 if move:
370 370 pmmf.discard(f1)
371 371 pmmf.add(f)
372 372
373 373 # check case-folding collision in provisional merged manifest
374 374 foldmap = {}
375 375 for f in sorted(pmmf):
376 376 fold = util.normcase(f)
377 377 if fold in foldmap:
378 378 raise util.Abort(_("case-folding collision between %s and %s")
379 379 % (f, foldmap[fold]))
380 380 foldmap[fold] = f
381 381
382 382 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial,
383 383 acceptremote, followcopies):
384 384 """
385 385 Merge p1 and p2 with ancestor pa and generate merge action list
386 386
387 387 branchmerge and force are as passed in to update
388 388 partial = function to filter file lists
389 389 acceptremote = accept the incoming changes without prompting
390 390 """
391 391
392 392 actions = dict((m, []) for m in 'a f g cd dc r dm dg m dr e rd k'.split())
393 393 copy, movewithdir = {}, {}
394 394
395 395 # manifests fetched in order are going to be faster, so prime the caches
396 396 [x.manifest() for x in
397 397 sorted(wctx.parents() + [p2, pa], key=lambda x: x.rev())]
398 398
399 399 if followcopies:
400 400 ret = copies.mergecopies(repo, wctx, p2, pa)
401 401 copy, movewithdir, diverge, renamedelete = ret
402 402 for of, fl in diverge.iteritems():
403 403 actions['dr'].append((of, (fl,), "divergent renames"))
404 404 for of, fl in renamedelete.iteritems():
405 405 actions['rd'].append((of, (fl,), "rename and delete"))
406 406
407 407 repo.ui.note(_("resolving manifests\n"))
408 408 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n"
409 409 % (bool(branchmerge), bool(force), bool(partial)))
410 410 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2))
411 411
412 412 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest()
413 413 copied = set(copy.values())
414 414 copied.update(movewithdir.values())
415 415
416 416 if '.hgsubstate' in m1:
417 417 # check whether sub state is modified
418 418 for s in sorted(wctx.substate):
419 419 if wctx.sub(s).dirty():
420 420 m1['.hgsubstate'] += "+"
421 421 break
422 422
423 423 aborts = []
424 424 # Compare manifests
425 425 fdiff = dicthelpers.diff(m1, m2)
426 426 flagsdiff = m1.flagsdiff(m2)
427 427 diff12 = dicthelpers.join(fdiff, flagsdiff)
428 428
429 429 for f, (n12, fl12) in diff12.iteritems():
430 430 if n12:
431 431 n1, n2 = n12
432 432 else: # file contents didn't change, but flags did
433 433 n1 = n2 = m1.get(f, None)
434 434 if n1 is None:
435 435 # Since n1 == n2, the file isn't present in m2 either. This
436 436 # means that the file was removed or deleted locally and
437 437 # removed remotely, but that residual entries remain in flags.
438 438 # This can happen in manifests generated by workingctx.
439 439 continue
440 440 if fl12:
441 441 fl1, fl2 = fl12
442 442 else: # flags didn't change, file contents did
443 443 fl1 = fl2 = m1.flags(f)
444 444
445 445 if partial and not partial(f):
446 446 continue
447 447 if n1 and n2:
448 448 fa = f
449 449 a = ma.get(f, nullid)
450 450 if a == nullid:
451 451 fa = copy.get(f, f)
452 452 # Note: f as default is wrong - we can't really make a 3-way
453 453 # merge without an ancestor file.
454 454 fla = ma.flags(fa)
455 455 nol = 'l' not in fl1 + fl2 + fla
456 456 if n2 == a and fl2 == fla:
457 457 actions['k'].append((f, (), "keep")) # remote unchanged
458 458 elif n1 == a and fl1 == fla: # local unchanged - use remote
459 459 if n1 == n2: # optimization: keep local content
460 460 actions['e'].append((f, (fl2,), "update permissions"))
461 461 else:
462 462 actions['g'].append((f, (fl2,), "remote is newer"))
463 463 elif nol and n2 == a: # remote only changed 'x'
464 464 actions['e'].append((f, (fl2,), "update permissions"))
465 465 elif nol and n1 == a: # local only changed 'x'
466 466 actions['g'].append((f, (fl1,), "remote is newer"))
467 467 else: # both changed something
468 468 actions['m'].append((f, (f, f, fa, False, pa.node()),
469 469 "versions differ"))
470 470 elif f in copied: # files we'll deal with on m2 side
471 471 pass
472 472 elif n1 and f in movewithdir: # directory rename, move local
473 473 f2 = movewithdir[f]
474 474 actions['dm'].append((f2, (f, fl1),
475 475 "remote directory rename - move from " + f))
476 476 elif n1 and f in copy:
477 477 f2 = copy[f]
478 478 actions['m'].append((f, (f, f2, f2, False, pa.node()),
479 479 "local copied/moved from " + f2))
480 480 elif n1 and f in ma: # clean, a different, no remote
481 481 if n1 != ma[f]:
482 482 if acceptremote:
483 483 actions['r'].append((f, None, "remote delete"))
484 484 else:
485 485 actions['cd'].append((f, None, "prompt changed/deleted"))
486 486 elif n1[20:] == "a": # added, no remote
487 487 actions['f'].append((f, None, "remote deleted"))
488 488 else:
489 489 actions['r'].append((f, None, "other deleted"))
490 490 elif n2 and f in movewithdir:
491 491 f2 = movewithdir[f]
492 492 actions['dg'].append((f2, (f, fl2),
493 493 "local directory rename - get from " + f))
494 494 elif n2 and f in copy:
495 495 f2 = copy[f]
496 496 if f2 in m2:
497 497 actions['m'].append((f, (f2, f, f2, False, pa.node()),
498 498 "remote copied from " + f2))
499 499 else:
500 500 actions['m'].append((f, (f2, f, f2, True, pa.node()),
501 501 "remote moved from " + f2))
502 502 elif n2 and f not in ma:
503 503 # local unknown, remote created: the logic is described by the
504 504 # following table:
505 505 #
506 506 # force branchmerge different | action
507 507 # n * n | get
508 508 # n * y | abort
509 509 # y n * | get
510 510 # y y n | get
511 511 # y y y | merge
512 512 #
513 513 # Checking whether the files are different is expensive, so we
514 514 # don't do that when we can avoid it.
515 515 if force and not branchmerge:
516 516 actions['g'].append((f, (fl2,), "remote created"))
517 517 else:
518 518 different = _checkunknownfile(repo, wctx, p2, f)
519 519 if force and branchmerge and different:
520 520 # FIXME: This is wrong - f is not in ma ...
521 521 actions['m'].append((f, (f, f, f, False, pa.node()),
522 522 "remote differs from untracked local"))
523 523 elif not force and different:
524 524 aborts.append((f, "ud"))
525 525 else:
526 526 actions['g'].append((f, (fl2,), "remote created"))
527 527 elif n2 and n2 != ma[f]:
528 528 different = _checkunknownfile(repo, wctx, p2, f)
529 529 if not force and different:
530 530 aborts.append((f, "ud"))
531 531 else:
532 532 # if different: old untracked f may be overwritten and lost
533 533 if acceptremote:
534 534 actions['g'].append((f, (m2.flags(f),),
535 535 "remote recreating"))
536 536 else:
537 537 actions['dc'].append((f, (m2.flags(f),),
538 538 "prompt deleted/changed"))
539 539
540 540 for f, m in sorted(aborts):
541 541 if m == "ud":
542 542 repo.ui.warn(_("%s: untracked file differs\n") % f)
543 543 else: assert False, m
544 544 if aborts:
545 545 raise util.Abort(_("untracked files in working directory differ "
546 546 "from files in requested revision"))
547 547
548 548 if not util.checkcase(repo.path):
549 549 # check collision between files only in p2 for clean update
550 550 if (not branchmerge and
551 551 (force or not wctx.dirty(missing=True, branch=False))):
552 552 _checkcollision(repo, m2, None)
553 553 else:
554 554 _checkcollision(repo, m1, actions)
555 555
556 556 return actions
557 557
558 558 def batchremove(repo, actions):
559 559 """apply removes to the working directory
560 560
561 561 yields tuples for progress updates
562 562 """
563 563 verbose = repo.ui.verbose
564 564 unlink = util.unlinkpath
565 565 wjoin = repo.wjoin
566 566 audit = repo.wopener.audit
567 567 i = 0
568 568 for f, args, msg in actions:
569 569 repo.ui.debug(" %s: %s -> r\n" % (f, msg))
570 570 if verbose:
571 571 repo.ui.note(_("removing %s\n") % f)
572 572 audit(f)
573 573 try:
574 574 unlink(wjoin(f), ignoremissing=True)
575 575 except OSError, inst:
576 576 repo.ui.warn(_("update failed to remove %s: %s!\n") %
577 577 (f, inst.strerror))
578 578 if i == 100:
579 579 yield i, f
580 580 i = 0
581 581 i += 1
582 582 if i > 0:
583 583 yield i, f
584 584
585 585 def batchget(repo, mctx, actions):
586 586 """apply gets to the working directory
587 587
588 588 mctx is the context to get from
589 589
590 590 yields tuples for progress updates
591 591 """
592 592 verbose = repo.ui.verbose
593 593 fctx = mctx.filectx
594 594 wwrite = repo.wwrite
595 595 i = 0
596 596 for f, args, msg in actions:
597 597 repo.ui.debug(" %s: %s -> g\n" % (f, msg))
598 598 if verbose:
599 599 repo.ui.note(_("getting %s\n") % f)
600 600 wwrite(f, fctx(f).data(), args[0])
601 601 if i == 100:
602 602 yield i, f
603 603 i = 0
604 604 i += 1
605 605 if i > 0:
606 606 yield i, f
607 607
608 608 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None):
609 609 """apply the merge action list to the working directory
610 610
611 611 wctx is the working copy context
612 612 mctx is the context to be merged into the working copy
613 613
614 614 Return a tuple of counts (updated, merged, removed, unresolved) that
615 615 describes how many files were affected by the update.
616 616 """
617 617
618 618 updated, merged, removed, unresolved = 0, 0, 0, 0
619 619 ms = mergestate(repo)
620 620 ms.reset(wctx.p1().node(), mctx.node())
621 621 moves = []
622 622 for m, l in actions.items():
623 623 l.sort()
624 624
625 625 # prescan for merges
626 626 for f, args, msg in actions['m']:
627 627 f1, f2, fa, move, anc = args
628 628 if f == '.hgsubstate': # merged internally
629 629 continue
630 630 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f))
631 631 fcl = wctx[f1]
632 632 fco = mctx[f2]
633 633 actx = repo[anc]
634 634 if fa in actx:
635 635 fca = actx[fa]
636 636 else:
637 637 fca = repo.filectx(f1, fileid=nullrev)
638 638 ms.add(fcl, fco, fca, f)
639 639 if f1 != f and move:
640 640 moves.append(f1)
641 641
642 642 audit = repo.wopener.audit
643 643 _updating = _('updating')
644 644 _files = _('files')
645 645 progress = repo.ui.progress
646 646
647 647 # remove renamed files after safely stored
648 648 for f in moves:
649 649 if os.path.lexists(repo.wjoin(f)):
650 650 repo.ui.debug("removing %s\n" % f)
651 651 audit(f)
652 652 util.unlinkpath(repo.wjoin(f))
653 653
654 654 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
655 655
656 656 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
657 657 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
658 658
659 659 # remove in parallel (must come first)
660 660 z = 0
661 661 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r'])
662 662 for i, item in prog:
663 663 z += i
664 664 progress(_updating, z, item=item, total=numupdates, unit=_files)
665 665 removed = len(actions['r'])
666 666
667 667 # get in parallel
668 668 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g'])
669 669 for i, item in prog:
670 670 z += i
671 671 progress(_updating, z, item=item, total=numupdates, unit=_files)
672 672 updated = len(actions['g'])
673 673
674 674 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
675 675 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
676 676
677 677 # forget (manifest only, just log it) (must come first)
678 678 for f, args, msg in actions['f']:
679 679 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
680 680 z += 1
681 681 progress(_updating, z, item=f, total=numupdates, unit=_files)
682 682
683 683 # re-add (manifest only, just log it)
684 684 for f, args, msg in actions['a']:
685 685 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
686 686 z += 1
687 687 progress(_updating, z, item=f, total=numupdates, unit=_files)
688 688
689 689 # keep (noop, just log it)
690 690 for f, args, msg in actions['k']:
691 691 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
692 692 # no progress
693 693
694 694 # merge
695 695 for f, args, msg in actions['m']:
696 696 repo.ui.debug(" %s: %s -> m\n" % (f, msg))
697 697 z += 1
698 698 progress(_updating, z, item=f, total=numupdates, unit=_files)
699 699 f1, f2, fa, move, anc = args
700 700 if f == '.hgsubstate': # subrepo states need updating
701 701 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
702 702 overwrite)
703 703 continue
704 704 audit(f)
705 705 r = ms.resolve(f, wctx, labels=labels)
706 706 if r is not None and r > 0:
707 707 unresolved += 1
708 708 else:
709 709 if r is None:
710 710 updated += 1
711 711 else:
712 712 merged += 1
713 713
714 714 # directory rename, move local
715 715 for f, args, msg in actions['dm']:
716 716 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
717 717 z += 1
718 718 progress(_updating, z, item=f, total=numupdates, unit=_files)
719 719 f0, flags = args
720 720 repo.ui.note(_("moving %s to %s\n") % (f0, f))
721 721 audit(f)
722 722 repo.wwrite(f, wctx.filectx(f0).data(), flags)
723 723 util.unlinkpath(repo.wjoin(f0))
724 724 updated += 1
725 725
726 726 # local directory rename, get
727 727 for f, args, msg in actions['dg']:
728 728 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
729 729 z += 1
730 730 progress(_updating, z, item=f, total=numupdates, unit=_files)
731 731 f0, flags = args
732 732 repo.ui.note(_("getting %s to %s\n") % (f0, f))
733 733 repo.wwrite(f, mctx.filectx(f0).data(), flags)
734 734 updated += 1
735 735
736 736 # divergent renames
737 737 for f, args, msg in actions['dr']:
738 738 repo.ui.debug(" %s: %s -> dr\n" % (f, msg))
739 739 z += 1
740 740 progress(_updating, z, item=f, total=numupdates, unit=_files)
741 741 fl, = args
742 742 repo.ui.warn(_("note: possible conflict - %s was renamed "
743 743 "multiple times to:\n") % f)
744 744 for nf in fl:
745 745 repo.ui.warn(" %s\n" % nf)
746 746
747 747 # rename and delete
748 748 for f, args, msg in actions['rd']:
749 749 repo.ui.debug(" %s: %s -> rd\n" % (f, msg))
750 750 z += 1
751 751 progress(_updating, z, item=f, total=numupdates, unit=_files)
752 752 fl, = args
753 753 repo.ui.warn(_("note: possible conflict - %s was deleted "
754 754 "and renamed to:\n") % f)
755 755 for nf in fl:
756 756 repo.ui.warn(" %s\n" % nf)
757 757
758 758 # exec
759 759 for f, args, msg in actions['e']:
760 760 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
761 761 z += 1
762 762 progress(_updating, z, item=f, total=numupdates, unit=_files)
763 763 flags, = args
764 764 audit(f)
765 765 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
766 766 updated += 1
767 767
768 768 ms.commit()
769 769 progress(_updating, None, total=numupdates, unit=_files)
770 770
771 771 return updated, merged, removed, unresolved
772 772
773 773 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial,
774 774 acceptremote, followcopies):
775 775 "Calculate the actions needed to merge mctx into wctx using ancestors"
776 776
777 777 if len(ancestors) == 1: # default
778 778 actions = manifestmerge(repo, wctx, mctx, ancestors[0],
779 779 branchmerge, force,
780 780 partial, acceptremote, followcopies)
781 781
782 782 else: # only when merge.preferancestor=* - the default
783 783 repo.ui.note(
784 784 _("note: merging %s and %s using bids from ancestors %s\n") %
785 785 (wctx, mctx, _(' and ').join(str(anc) for anc in ancestors)))
786 786
787 787 # Call for bids
788 788 fbids = {} # mapping filename to bids (action method to list af actions)
789 789 for ancestor in ancestors:
790 790 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor)
791 791 actions = manifestmerge(repo, wctx, mctx, ancestor,
792 792 branchmerge, force,
793 793 partial, acceptremote, followcopies)
794 794 for m, l in sorted(actions.items()):
795 795 for a in l:
796 796 f, args, msg = a
797 797 repo.ui.debug(' %s: %s -> %s\n' % (f, msg, m))
798 798 if f in fbids:
799 799 d = fbids[f]
800 800 if m in d:
801 801 d[m].append(a)
802 802 else:
803 803 d[m] = [a]
804 804 else:
805 805 fbids[f] = {m: [a]}
806 806
807 807 # Pick the best bid for each file
808 808 repo.ui.note(_('\nauction for merging merge bids\n'))
809 809 actions = dict((m, []) for m in actions.keys())
810 810 for f, bids in sorted(fbids.items()):
811 811 # bids is a mapping from action method to list af actions
812 812 # Consensus?
813 813 if len(bids) == 1: # all bids are the same kind of method
814 814 m, l = bids.items()[0]
815 815 if util.all(a == l[0] for a in l[1:]): # len(bids) is > 1
816 816 repo.ui.note(" %s: consensus for %s\n" % (f, m))
817 817 actions[m].append(l[0])
818 818 continue
819 819 # If keep is an option, just do it.
820 820 if "k" in bids:
821 821 repo.ui.note(" %s: picking 'keep' action\n" % f)
822 822 actions['k'].append(bids["k"][0])
823 823 continue
824 824 # If there are gets and they all agree [how could they not?], do it.
825 825 if "g" in bids:
826 826 ga0 = bids["g"][0]
827 827 if util.all(a == ga0 for a in bids["g"][1:]):
828 828 repo.ui.note(" %s: picking 'get' action\n" % f)
829 829 actions['g'].append(ga0)
830 830 continue
831 831 # TODO: Consider other simple actions such as mode changes
832 832 # Handle inefficient democrazy.
833 833 repo.ui.note(_(' %s: multiple bids for merge action:\n') % f)
834 834 for m, l in sorted(bids.items()):
835 835 for _f, args, msg in l:
836 836 repo.ui.note(' %s -> %s\n' % (msg, m))
837 837 # Pick random action. TODO: Instead, prompt user when resolving
838 838 m, l = bids.items()[0]
839 839 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
840 840 (f, m))
841 841 actions[m].append(l[0])
842 842 continue
843 843 repo.ui.note(_('end of auction\n\n'))
844 844
845 845 # Prompt and create actions. TODO: Move this towards resolve phase.
846 846 for f, args, msg in actions['cd']:
847 847 if repo.ui.promptchoice(
848 848 _("local changed %s which remote deleted\n"
849 849 "use (c)hanged version or (d)elete?"
850 850 "$$ &Changed $$ &Delete") % f, 0):
851 851 actions['r'].append((f, None, "prompt delete"))
852 852 else:
853 853 actions['a'].append((f, None, "prompt keep"))
854 854 del actions['cd'][:]
855 855
856 856 for f, args, msg in actions['dc']:
857 857 flags, = args
858 858 if repo.ui.promptchoice(
859 859 _("remote changed %s which local deleted\n"
860 860 "use (c)hanged version or leave (d)eleted?"
861 861 "$$ &Changed $$ &Deleted") % f, 0) == 0:
862 862 actions['g'].append((f, (flags,), "prompt recreating"))
863 863 del actions['dc'][:]
864 864
865 865 if wctx.rev() is None:
866 866 ractions, factions = _forgetremoved(wctx, mctx, branchmerge)
867 867 actions['r'].extend(ractions)
868 868 actions['f'].extend(factions)
869 869
870 870 return actions
871 871
872 872 def recordupdates(repo, actions, branchmerge):
873 873 "record merge actions to the dirstate"
874 874 # remove (must come first)
875 875 for f, args, msg in actions['r']:
876 876 if branchmerge:
877 877 repo.dirstate.remove(f)
878 878 else:
879 879 repo.dirstate.drop(f)
880 880
881 881 # forget (must come first)
882 882 for f, args, msg in actions['f']:
883 883 repo.dirstate.drop(f)
884 884
885 885 # re-add
886 886 for f, args, msg in actions['a']:
887 887 if not branchmerge:
888 888 repo.dirstate.add(f)
889 889
890 890 # exec change
891 891 for f, args, msg in actions['e']:
892 892 repo.dirstate.normallookup(f)
893 893
894 894 # keep
895 895 for f, args, msg in actions['k']:
896 896 pass
897 897
898 898 # get
899 899 for f, args, msg in actions['g']:
900 900 if branchmerge:
901 901 repo.dirstate.otherparent(f)
902 902 else:
903 903 repo.dirstate.normal(f)
904 904
905 905 # merge
906 906 for f, args, msg in actions['m']:
907 907 f1, f2, fa, move, anc = args
908 908 if branchmerge:
909 909 # We've done a branch merge, mark this file as merged
910 910 # so that we properly record the merger later
911 911 repo.dirstate.merge(f)
912 912 if f1 != f2: # copy/rename
913 913 if move:
914 914 repo.dirstate.remove(f1)
915 915 if f1 != f:
916 916 repo.dirstate.copy(f1, f)
917 917 else:
918 918 repo.dirstate.copy(f2, f)
919 919 else:
920 920 # We've update-merged a locally modified file, so
921 921 # we set the dirstate to emulate a normal checkout
922 922 # of that file some time in the past. Thus our
923 923 # merge will appear as a normal local file
924 924 # modification.
925 925 if f2 == f: # file not locally copied/moved
926 926 repo.dirstate.normallookup(f)
927 927 if move:
928 928 repo.dirstate.drop(f1)
929 929
930 930 # directory rename, move local
931 931 for f, args, msg in actions['dm']:
932 932 f0, flag = args
933 933 if f0 not in repo.dirstate:
934 934 # untracked file moved
935 935 continue
936 936 if branchmerge:
937 937 repo.dirstate.add(f)
938 938 repo.dirstate.remove(f0)
939 939 repo.dirstate.copy(f0, f)
940 940 else:
941 941 repo.dirstate.normal(f)
942 942 repo.dirstate.drop(f0)
943 943
944 944 # directory rename, get
945 945 for f, args, msg in actions['dg']:
946 946 f0, flag = args
947 947 if branchmerge:
948 948 repo.dirstate.add(f)
949 949 repo.dirstate.copy(f0, f)
950 950 else:
951 951 repo.dirstate.normal(f)
952 952
953 953 def update(repo, node, branchmerge, force, partial, ancestor=None,
954 954 mergeancestor=False, labels=None):
955 955 """
956 956 Perform a merge between the working directory and the given node
957 957
958 958 node = the node to update to, or None if unspecified
959 959 branchmerge = whether to merge between branches
960 960 force = whether to force branch merging or file overwriting
961 961 partial = a function to filter file lists (dirstate not updated)
962 962 mergeancestor = whether it is merging with an ancestor. If true,
963 963 we should accept the incoming changes for any prompts that occur.
964 964 If false, merging with an ancestor (fast-forward) is only allowed
965 965 between different named branches. This flag is used by rebase extension
966 966 as a temporary fix and should be avoided in general.
967 967
968 968 The table below shows all the behaviors of the update command
969 969 given the -c and -C or no options, whether the working directory
970 970 is dirty, whether a revision is specified, and the relationship of
971 971 the parent rev to the target rev (linear, on the same named
972 972 branch, or on another named branch).
973 973
974 974 This logic is tested by test-update-branches.t.
975 975
976 976 -c -C dirty rev | linear same cross
977 977 n n n n | ok (1) x
978 978 n n n y | ok ok ok
979 979 n n y n | merge (2) (2)
980 980 n n y y | merge (3) (3)
981 981 n y * * | --- discard ---
982 982 y n y * | --- (4) ---
983 983 y n n * | --- ok ---
984 984 y y * * | --- (5) ---
985 985
986 986 x = can't happen
987 987 * = don't-care
988 988 1 = abort: not a linear update (merge or update --check to force update)
989 989 2 = abort: uncommitted changes (commit and merge, or update --clean to
990 990 discard changes)
991 991 3 = abort: uncommitted changes (commit or update --clean to discard changes)
992 992 4 = abort: uncommitted changes (checked in commands.py)
993 993 5 = incompatible options (checked in commands.py)
994 994
995 995 Return the same tuple as applyupdates().
996 996 """
997 997
998 998 onode = node
999 999 wlock = repo.wlock()
1000 1000 try:
1001 1001 wc = repo[None]
1002 1002 pl = wc.parents()
1003 1003 p1 = pl[0]
1004 1004 pas = [None]
1005 1005 if ancestor:
1006 1006 pas = [repo[ancestor]]
1007 1007
1008 1008 if node is None:
1009 1009 # Here is where we should consider bookmarks, divergent bookmarks,
1010 1010 # foreground changesets (successors), and tip of current branch;
1011 1011 # but currently we are only checking the branch tips.
1012 1012 try:
1013 1013 node = repo.branchtip(wc.branch())
1014 1014 except errormod.RepoLookupError:
1015 1015 if wc.branch() == "default": # no default branch!
1016 1016 node = repo.lookup("tip") # update to tip
1017 1017 else:
1018 1018 raise util.Abort(_("branch %s not found") % wc.branch())
1019 1019
1020 1020 if p1.obsolete() and not p1.children():
1021 1021 # allow updating to successors
1022 1022 successors = obsolete.successorssets(repo, p1.node())
1023 1023
1024 1024 # behavior of certain cases is as follows,
1025 1025 #
1026 1026 # divergent changesets: update to highest rev, similar to what
1027 1027 # is currently done when there are more than one head
1028 1028 # (i.e. 'tip')
1029 1029 #
1030 1030 # replaced changesets: same as divergent except we know there
1031 1031 # is no conflict
1032 1032 #
1033 1033 # pruned changeset: no update is done; though, we could
1034 1034 # consider updating to the first non-obsolete parent,
1035 1035 # similar to what is current done for 'hg prune'
1036 1036
1037 1037 if successors:
1038 1038 # flatten the list here handles both divergent (len > 1)
1039 1039 # and the usual case (len = 1)
1040 1040 successors = [n for sub in successors for n in sub]
1041 1041
1042 1042 # get the max revision for the given successors set,
1043 1043 # i.e. the 'tip' of a set
1044 1044 node = repo.revs("max(%ln)", successors).first()
1045 1045 pas = [p1]
1046 1046
1047 1047 overwrite = force and not branchmerge
1048 1048
1049 1049 p2 = repo[node]
1050 1050 if pas[0] is None:
1051 1051 if repo.ui.config("merge", "preferancestor", '*') == '*':
1052 1052 cahs = repo.changelog.commonancestorsheads(p1.node(), p2.node())
1053 1053 pas = [repo[anc] for anc in (sorted(cahs) or [nullid])]
1054 1054 else:
1055 1055 pas = [p1.ancestor(p2, warn=branchmerge)]
1056 1056
1057 1057 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
1058 1058
1059 1059 ### check phase
1060 1060 if not overwrite and len(pl) > 1:
1061 raise util.Abort(_("outstanding uncommitted merges"))
1061 raise util.Abort(_("outstanding uncommitted merge"))
1062 1062 if branchmerge:
1063 1063 if pas == [p2]:
1064 1064 raise util.Abort(_("merging with a working directory ancestor"
1065 1065 " has no effect"))
1066 1066 elif pas == [p1]:
1067 1067 if not mergeancestor and p1.branch() == p2.branch():
1068 1068 raise util.Abort(_("nothing to merge"),
1069 1069 hint=_("use 'hg update' "
1070 1070 "or check 'hg heads'"))
1071 1071 if not force and (wc.files() or wc.deleted()):
1072 1072 raise util.Abort(_("uncommitted changes"),
1073 1073 hint=_("use 'hg status' to list changes"))
1074 1074 for s in sorted(wc.substate):
1075 1075 if wc.sub(s).dirty():
1076 1076 raise util.Abort(_("uncommitted changes in "
1077 1077 "subrepository '%s'") % s)
1078 1078
1079 1079 elif not overwrite:
1080 1080 if p1 == p2: # no-op update
1081 1081 # call the hooks and exit early
1082 1082 repo.hook('preupdate', throw=True, parent1=xp2, parent2='')
1083 1083 repo.hook('update', parent1=xp2, parent2='', error=0)
1084 1084 return 0, 0, 0, 0
1085 1085
1086 1086 if pas not in ([p1], [p2]): # nonlinear
1087 1087 dirty = wc.dirty(missing=True)
1088 1088 if dirty or onode is None:
1089 1089 # Branching is a bit strange to ensure we do the minimal
1090 1090 # amount of call to obsolete.background.
1091 1091 foreground = obsolete.foreground(repo, [p1.node()])
1092 1092 # note: the <node> variable contains a random identifier
1093 1093 if repo[node].node() in foreground:
1094 1094 pas = [p1] # allow updating to successors
1095 1095 elif dirty:
1096 1096 msg = _("uncommitted changes")
1097 1097 if onode is None:
1098 1098 hint = _("commit and merge, or update --clean to"
1099 1099 " discard changes")
1100 1100 else:
1101 1101 hint = _("commit or update --clean to discard"
1102 1102 " changes")
1103 1103 raise util.Abort(msg, hint=hint)
1104 1104 else: # node is none
1105 1105 msg = _("not a linear update")
1106 1106 hint = _("merge or update --check to force update")
1107 1107 raise util.Abort(msg, hint=hint)
1108 1108 else:
1109 1109 # Allow jumping branches if clean and specific rev given
1110 1110 pas = [p1]
1111 1111
1112 1112 followcopies = False
1113 1113 if overwrite:
1114 1114 pas = [wc]
1115 1115 elif pas == [p2]: # backwards
1116 1116 pas = [wc.p1()]
1117 1117 elif not branchmerge and not wc.dirty(missing=True):
1118 1118 pass
1119 1119 elif pas[0] and repo.ui.configbool("merge", "followcopies", True):
1120 1120 followcopies = True
1121 1121
1122 1122 ### calculate phase
1123 1123 actions = calculateupdates(repo, wc, p2, pas, branchmerge, force,
1124 1124 partial, mergeancestor, followcopies)
1125 1125
1126 1126 ### apply phase
1127 1127 if not branchmerge: # just jump to the new rev
1128 1128 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
1129 1129 if not partial:
1130 1130 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
1131 1131 # note that we're in the middle of an update
1132 1132 repo.vfs.write('updatestate', p2.hex())
1133 1133
1134 1134 stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels)
1135 1135
1136 1136 if not partial:
1137 1137 repo.dirstate.beginparentchange()
1138 1138 repo.setparents(fp1, fp2)
1139 1139 recordupdates(repo, actions, branchmerge)
1140 1140 # update completed, clear state
1141 1141 util.unlink(repo.join('updatestate'))
1142 1142
1143 1143 if not branchmerge:
1144 1144 repo.dirstate.setbranch(p2.branch())
1145 1145 repo.dirstate.endparentchange()
1146 1146 finally:
1147 1147 wlock.release()
1148 1148
1149 1149 if not partial:
1150 1150 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
1151 1151 return stats
@@ -1,1824 +1,1824 b''
1 1 This file used to contains all largefile tests.
2 2 Do not add any new tests in this file as it his already far too long to run.
3 3
4 4 It contains all the testing of the basic concepts of large file in a single block.
5 5
6 6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
7 7 $ mkdir "${USERCACHE}"
8 8 $ cat >> $HGRCPATH <<EOF
9 9 > [extensions]
10 10 > largefiles=
11 11 > purge=
12 12 > rebase=
13 13 > transplant=
14 14 > [phases]
15 15 > publish=False
16 16 > [largefiles]
17 17 > minsize=2
18 18 > patterns=glob:**.dat
19 19 > usercache=${USERCACHE}
20 20 > [hooks]
21 21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
22 22 > EOF
23 23
24 24 Create the repo with a couple of revisions of both large and normal
25 25 files.
26 26 Test status and dirstate of largefiles and that summary output is correct.
27 27
28 28 $ hg init a
29 29 $ cd a
30 30 $ mkdir sub
31 31 $ echo normal1 > normal1
32 32 $ echo normal2 > sub/normal2
33 33 $ echo large1 > large1
34 34 $ echo large2 > sub/large2
35 35 $ hg add normal1 sub/normal2
36 36 $ hg add --large large1 sub/large2
37 37 $ hg commit -m "add files"
38 38 Invoking status precommit hook
39 39 A large1
40 40 A normal1
41 41 A sub/large2
42 42 A sub/normal2
43 43 $ touch large1 sub/large2
44 44 $ sleep 1
45 45 $ hg st
46 46 $ hg debugstate --nodates
47 47 n 644 41 .hglf/large1
48 48 n 644 41 .hglf/sub/large2
49 49 n 644 8 normal1
50 50 n 644 8 sub/normal2
51 51 $ hg debugstate --large --nodates
52 52 n 644 7 large1
53 53 n 644 7 sub/large2
54 54 $ echo normal11 > normal1
55 55 $ echo normal22 > sub/normal2
56 56 $ echo large11 > large1
57 57 $ echo large22 > sub/large2
58 58 $ hg commit -m "edit files"
59 59 Invoking status precommit hook
60 60 M large1
61 61 M normal1
62 62 M sub/large2
63 63 M sub/normal2
64 64 $ hg sum --large
65 65 parent: 1:ce8896473775 tip
66 66 edit files
67 67 branch: default
68 68 commit: (clean)
69 69 update: (current)
70 70 largefiles: (no remote repo)
71 71
72 72 Commit preserved largefile contents.
73 73
74 74 $ cat normal1
75 75 normal11
76 76 $ cat large1
77 77 large11
78 78 $ cat sub/normal2
79 79 normal22
80 80 $ cat sub/large2
81 81 large22
82 82
83 83 Test status, subdir and unknown files
84 84
85 85 $ echo unknown > sub/unknown
86 86 $ hg st --all
87 87 ? sub/unknown
88 88 C large1
89 89 C normal1
90 90 C sub/large2
91 91 C sub/normal2
92 92 $ hg st --all sub
93 93 ? sub/unknown
94 94 C sub/large2
95 95 C sub/normal2
96 96 $ rm sub/unknown
97 97
98 98 Test messages and exit codes for remove warning cases
99 99
100 100 $ hg remove -A large1
101 101 not removing large1: file still exists
102 102 [1]
103 103 $ echo 'modified' > large1
104 104 $ hg remove large1
105 105 not removing large1: file is modified (use -f to force removal)
106 106 [1]
107 107 $ echo 'new' > normalnew
108 108 $ hg add normalnew
109 109 $ echo 'new' > largenew
110 110 $ hg add --large normalnew
111 111 normalnew already tracked!
112 112 $ hg remove normalnew largenew
113 113 not removing largenew: file is untracked
114 114 not removing normalnew: file has been marked for add (use forget to undo)
115 115 [1]
116 116 $ rm normalnew largenew
117 117 $ hg up -Cq
118 118
119 119 Remove both largefiles and normal files.
120 120
121 121 $ hg remove normal1 large1
122 122 $ hg status large1
123 123 R large1
124 124 $ hg commit -m "remove files"
125 125 Invoking status precommit hook
126 126 R large1
127 127 R normal1
128 128 $ ls
129 129 sub
130 130 $ echo "testlargefile" > large1-test
131 131 $ hg add --large large1-test
132 132 $ hg st
133 133 A large1-test
134 134 $ hg rm large1-test
135 135 not removing large1-test: file has been marked for add (use forget to undo)
136 136 [1]
137 137 $ hg st
138 138 A large1-test
139 139 $ hg forget large1-test
140 140 $ hg st
141 141 ? large1-test
142 142 $ hg remove large1-test
143 143 not removing large1-test: file is untracked
144 144 [1]
145 145 $ hg forget large1-test
146 146 not removing large1-test: file is already untracked
147 147 [1]
148 148 $ rm large1-test
149 149
150 150 Copy both largefiles and normal files (testing that status output is correct).
151 151
152 152 $ hg cp sub/normal2 normal1
153 153 $ hg cp sub/large2 large1
154 154 $ hg commit -m "copy files"
155 155 Invoking status precommit hook
156 156 A large1
157 157 A normal1
158 158 $ cat normal1
159 159 normal22
160 160 $ cat large1
161 161 large22
162 162
163 163 Test moving largefiles and verify that normal files are also unaffected.
164 164
165 165 $ hg mv normal1 normal3
166 166 $ hg mv large1 large3
167 167 $ hg mv sub/normal2 sub/normal4
168 168 $ hg mv sub/large2 sub/large4
169 169 $ hg commit -m "move files"
170 170 Invoking status precommit hook
171 171 A large3
172 172 A normal3
173 173 A sub/large4
174 174 A sub/normal4
175 175 R large1
176 176 R normal1
177 177 R sub/large2
178 178 R sub/normal2
179 179 $ cat normal3
180 180 normal22
181 181 $ cat large3
182 182 large22
183 183 $ cat sub/normal4
184 184 normal22
185 185 $ cat sub/large4
186 186 large22
187 187
188 188
189 189 #if serve
190 190 Test display of largefiles in hgweb
191 191
192 192 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
193 193 $ cat ../hg.pid >> $DAEMON_PIDS
194 194 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
195 195 200 Script output follows
196 196
197 197
198 198 drwxr-xr-x sub
199 199 -rw-r--r-- 41 large3
200 200 -rw-r--r-- 9 normal3
201 201
202 202
203 203 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
204 204 200 Script output follows
205 205
206 206
207 207 -rw-r--r-- 41 large4
208 208 -rw-r--r-- 9 normal4
209 209
210 210
211 211 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
212 212 #endif
213 213
214 214 Test archiving the various revisions. These hit corner cases known with
215 215 archiving.
216 216
217 217 $ hg archive -r 0 ../archive0
218 218 $ hg archive -r 1 ../archive1
219 219 $ hg archive -r 2 ../archive2
220 220 $ hg archive -r 3 ../archive3
221 221 $ hg archive -r 4 ../archive4
222 222 $ cd ../archive0
223 223 $ cat normal1
224 224 normal1
225 225 $ cat large1
226 226 large1
227 227 $ cat sub/normal2
228 228 normal2
229 229 $ cat sub/large2
230 230 large2
231 231 $ cd ../archive1
232 232 $ cat normal1
233 233 normal11
234 234 $ cat large1
235 235 large11
236 236 $ cat sub/normal2
237 237 normal22
238 238 $ cat sub/large2
239 239 large22
240 240 $ cd ../archive2
241 241 $ ls
242 242 sub
243 243 $ cat sub/normal2
244 244 normal22
245 245 $ cat sub/large2
246 246 large22
247 247 $ cd ../archive3
248 248 $ cat normal1
249 249 normal22
250 250 $ cat large1
251 251 large22
252 252 $ cat sub/normal2
253 253 normal22
254 254 $ cat sub/large2
255 255 large22
256 256 $ cd ../archive4
257 257 $ cat normal3
258 258 normal22
259 259 $ cat large3
260 260 large22
261 261 $ cat sub/normal4
262 262 normal22
263 263 $ cat sub/large4
264 264 large22
265 265
266 266 Commit corner case: specify files to commit.
267 267
268 268 $ cd ../a
269 269 $ echo normal3 > normal3
270 270 $ echo large3 > large3
271 271 $ echo normal4 > sub/normal4
272 272 $ echo large4 > sub/large4
273 273 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
274 274 Invoking status precommit hook
275 275 M large3
276 276 M normal3
277 277 M sub/large4
278 278 M sub/normal4
279 279 $ cat normal3
280 280 normal3
281 281 $ cat large3
282 282 large3
283 283 $ cat sub/normal4
284 284 normal4
285 285 $ cat sub/large4
286 286 large4
287 287
288 288 One more commit corner case: commit from a subdirectory.
289 289
290 290 $ cd ../a
291 291 $ echo normal33 > normal3
292 292 $ echo large33 > large3
293 293 $ echo normal44 > sub/normal4
294 294 $ echo large44 > sub/large4
295 295 $ cd sub
296 296 $ hg commit -m "edit files yet again"
297 297 Invoking status precommit hook
298 298 M large3
299 299 M normal3
300 300 M sub/large4
301 301 M sub/normal4
302 302 $ cat ../normal3
303 303 normal33
304 304 $ cat ../large3
305 305 large33
306 306 $ cat normal4
307 307 normal44
308 308 $ cat large4
309 309 large44
310 310
311 311 Committing standins is not allowed.
312 312
313 313 $ cd ..
314 314 $ echo large3 > large3
315 315 $ hg commit .hglf/large3 -m "try to commit standin"
316 316 abort: file ".hglf/large3" is a largefile standin
317 317 (commit the largefile itself instead)
318 318 [255]
319 319
320 320 Corner cases for adding largefiles.
321 321
322 322 $ echo large5 > large5
323 323 $ hg add --large large5
324 324 $ hg add --large large5
325 325 large5 already a largefile
326 326 $ mkdir sub2
327 327 $ echo large6 > sub2/large6
328 328 $ echo large7 > sub2/large7
329 329 $ hg add --large sub2
330 330 adding sub2/large6 as a largefile (glob)
331 331 adding sub2/large7 as a largefile (glob)
332 332 $ hg st
333 333 M large3
334 334 A large5
335 335 A sub2/large6
336 336 A sub2/large7
337 337
338 338 Committing directories containing only largefiles.
339 339
340 340 $ mkdir -p z/y/x/m
341 341 $ touch z/y/x/m/large1
342 342 $ touch z/y/x/large2
343 343 $ hg add --large z/y/x/m/large1 z/y/x/large2
344 344 $ hg commit -m "Subdir with directory only containing largefiles" z
345 345 Invoking status precommit hook
346 346 M large3
347 347 A large5
348 348 A sub2/large6
349 349 A sub2/large7
350 350 A z/y/x/large2
351 351 A z/y/x/m/large1
352 352
353 353 (and a bit of log testing)
354 354
355 355 $ hg log -T '{rev}\n' z/y/x/m/large1
356 356 7
357 357 $ hg log -T '{rev}\n' z/y/x/m # with only a largefile
358 358 7
359 359
360 360 $ hg rollback --quiet
361 361 $ touch z/y/x/m/normal
362 362 $ hg add z/y/x/m/normal
363 363 $ hg commit -m "Subdir with mixed contents" z
364 364 Invoking status precommit hook
365 365 M large3
366 366 A large5
367 367 A sub2/large6
368 368 A sub2/large7
369 369 A z/y/x/large2
370 370 A z/y/x/m/large1
371 371 A z/y/x/m/normal
372 372 $ hg st
373 373 M large3
374 374 A large5
375 375 A sub2/large6
376 376 A sub2/large7
377 377 $ hg rollback --quiet
378 378 $ hg revert z/y/x/large2 z/y/x/m/large1
379 379 $ rm z/y/x/large2 z/y/x/m/large1
380 380 $ hg commit -m "Subdir with normal contents" z
381 381 Invoking status precommit hook
382 382 M large3
383 383 A large5
384 384 A sub2/large6
385 385 A sub2/large7
386 386 A z/y/x/m/normal
387 387 $ hg st
388 388 M large3
389 389 A large5
390 390 A sub2/large6
391 391 A sub2/large7
392 392 $ hg rollback --quiet
393 393 $ hg revert --quiet z
394 394 $ hg commit -m "Empty subdir" z
395 395 abort: z: no match under directory!
396 396 [255]
397 397 $ rm -rf z
398 398 $ hg ci -m "standin" .hglf
399 399 abort: file ".hglf" is a largefile standin
400 400 (commit the largefile itself instead)
401 401 [255]
402 402
403 403 Test "hg status" with combination of 'file pattern' and 'directory
404 404 pattern' for largefiles:
405 405
406 406 $ hg status sub2/large6 sub2
407 407 A sub2/large6
408 408 A sub2/large7
409 409
410 410 Config settings (pattern **.dat, minsize 2 MB) are respected.
411 411
412 412 $ echo testdata > test.dat
413 413 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
414 414 $ hg add
415 415 adding reallylarge as a largefile
416 416 adding test.dat as a largefile
417 417
418 418 Test that minsize and --lfsize handle float values;
419 419 also tests that --lfsize overrides largefiles.minsize.
420 420 (0.250 MB = 256 kB = 262144 B)
421 421
422 422 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
423 423 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
424 424 $ hg --config largefiles.minsize=.25 add
425 425 adding ratherlarge as a largefile
426 426 adding medium
427 427 $ hg forget medium
428 428 $ hg --config largefiles.minsize=.25 add --lfsize=.125
429 429 adding medium as a largefile
430 430 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
431 431 $ hg --config largefiles.minsize=.25 add --lfsize=.125
432 432 adding notlarge
433 433 $ hg forget notlarge
434 434
435 435 Test forget on largefiles.
436 436
437 437 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
438 438 $ hg commit -m "add/edit more largefiles"
439 439 Invoking status precommit hook
440 440 A sub2/large6
441 441 A sub2/large7
442 442 R large3
443 443 ? large5
444 444 ? medium
445 445 ? notlarge
446 446 ? ratherlarge
447 447 ? reallylarge
448 448 ? test.dat
449 449 $ hg st
450 450 ? large3
451 451 ? large5
452 452 ? medium
453 453 ? notlarge
454 454 ? ratherlarge
455 455 ? reallylarge
456 456 ? test.dat
457 457
458 458 Purge with largefiles: verify that largefiles are still in the working
459 459 dir after a purge.
460 460
461 461 $ hg purge --all
462 462 $ cat sub/large4
463 463 large44
464 464 $ cat sub2/large6
465 465 large6
466 466 $ cat sub2/large7
467 467 large7
468 468
469 469 Test addremove: verify that files that should be added as largefiles are added as
470 470 such and that already-existing largefiles are not added as normal files by
471 471 accident.
472 472
473 473 $ rm normal3
474 474 $ rm sub/large4
475 475 $ echo "testing addremove with patterns" > testaddremove.dat
476 476 $ echo "normaladdremove" > normaladdremove
477 477 $ hg addremove
478 478 removing sub/large4
479 479 adding testaddremove.dat as a largefile
480 480 removing normal3
481 481 adding normaladdremove
482 482
483 483 Test addremove with -R
484 484
485 485 $ hg up -C
486 486 getting changed largefiles
487 487 1 largefiles updated, 0 removed
488 488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 489 $ rm normal3
490 490 $ rm sub/large4
491 491 $ echo "testing addremove with patterns" > testaddremove.dat
492 492 $ echo "normaladdremove" > normaladdremove
493 493 $ cd ..
494 494 $ hg -R a addremove
495 495 removing sub/large4
496 496 adding a/testaddremove.dat as a largefile (glob)
497 497 removing normal3
498 498 adding normaladdremove
499 499 $ cd a
500 500
501 501 Test 3364
502 502 $ hg clone . ../addrm
503 503 updating to branch default
504 504 getting changed largefiles
505 505 3 largefiles updated, 0 removed
506 506 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
507 507 $ cd ../addrm
508 508 $ cat >> .hg/hgrc <<EOF
509 509 > [hooks]
510 510 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
511 511 > EOF
512 512 $ touch foo
513 513 $ hg add --large foo
514 514 $ hg ci -m "add foo"
515 515 Invoking status precommit hook
516 516 A foo
517 517 Invoking status postcommit hook
518 518 C foo
519 519 C normal3
520 520 C sub/large4
521 521 C sub/normal4
522 522 C sub2/large6
523 523 C sub2/large7
524 524 $ rm foo
525 525 $ hg st
526 526 ! foo
527 527 hmm.. no precommit invoked, but there is a postcommit??
528 528 $ hg ci -m "will not checkin"
529 529 nothing changed
530 530 Invoking status postcommit hook
531 531 ! foo
532 532 C normal3
533 533 C sub/large4
534 534 C sub/normal4
535 535 C sub2/large6
536 536 C sub2/large7
537 537 [1]
538 538 $ hg addremove
539 539 removing foo
540 540 $ hg st
541 541 R foo
542 542 $ hg ci -m "used to say nothing changed"
543 543 Invoking status precommit hook
544 544 R foo
545 545 Invoking status postcommit hook
546 546 C normal3
547 547 C sub/large4
548 548 C sub/normal4
549 549 C sub2/large6
550 550 C sub2/large7
551 551 $ hg st
552 552
553 553 Test 3507 (both normal files and largefiles were a problem)
554 554
555 555 $ touch normal
556 556 $ touch large
557 557 $ hg add normal
558 558 $ hg add --large large
559 559 $ hg ci -m "added"
560 560 Invoking status precommit hook
561 561 A large
562 562 A normal
563 563 Invoking status postcommit hook
564 564 C large
565 565 C normal
566 566 C normal3
567 567 C sub/large4
568 568 C sub/normal4
569 569 C sub2/large6
570 570 C sub2/large7
571 571 $ hg remove normal
572 572 $ hg addremove --traceback
573 573 $ hg ci -m "addremoved normal"
574 574 Invoking status precommit hook
575 575 R normal
576 576 Invoking status postcommit hook
577 577 C large
578 578 C normal3
579 579 C sub/large4
580 580 C sub/normal4
581 581 C sub2/large6
582 582 C sub2/large7
583 583 $ hg up -C '.^'
584 584 getting changed largefiles
585 585 0 largefiles updated, 0 removed
586 586 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
587 587 $ hg remove large
588 588 $ hg addremove --traceback
589 589 $ hg ci -m "removed large"
590 590 Invoking status precommit hook
591 591 R large
592 592 created new head
593 593 Invoking status postcommit hook
594 594 C normal
595 595 C normal3
596 596 C sub/large4
597 597 C sub/normal4
598 598 C sub2/large6
599 599 C sub2/large7
600 600
601 601 Test commit -A (issue3542)
602 602 $ echo large8 > large8
603 603 $ hg add --large large8
604 604 $ hg ci -Am 'this used to add large8 as normal and commit both'
605 605 Invoking status precommit hook
606 606 A large8
607 607 Invoking status postcommit hook
608 608 C large8
609 609 C normal
610 610 C normal3
611 611 C sub/large4
612 612 C sub/normal4
613 613 C sub2/large6
614 614 C sub2/large7
615 615 $ rm large8
616 616 $ hg ci -Am 'this used to not notice the rm'
617 617 removing large8
618 618 Invoking status precommit hook
619 619 R large8
620 620 Invoking status postcommit hook
621 621 C normal
622 622 C normal3
623 623 C sub/large4
624 624 C sub/normal4
625 625 C sub2/large6
626 626 C sub2/large7
627 627
628 628 Test that a standin can't be added as a large file
629 629
630 630 $ touch large
631 631 $ hg add --large large
632 632 $ hg ci -m "add"
633 633 Invoking status precommit hook
634 634 A large
635 635 Invoking status postcommit hook
636 636 C large
637 637 C normal
638 638 C normal3
639 639 C sub/large4
640 640 C sub/normal4
641 641 C sub2/large6
642 642 C sub2/large7
643 643 $ hg remove large
644 644 $ touch large
645 645 $ hg addremove --config largefiles.patterns=**large --traceback
646 646 adding large as a largefile
647 647
648 648 Test that outgoing --large works (with revsets too)
649 649 $ hg outgoing --rev '.^' --large
650 650 comparing with $TESTTMP/a (glob)
651 651 searching for changes
652 652 changeset: 8:c02fd3b77ec4
653 653 user: test
654 654 date: Thu Jan 01 00:00:00 1970 +0000
655 655 summary: add foo
656 656
657 657 changeset: 9:289dd08c9bbb
658 658 user: test
659 659 date: Thu Jan 01 00:00:00 1970 +0000
660 660 summary: used to say nothing changed
661 661
662 662 changeset: 10:34f23ac6ac12
663 663 user: test
664 664 date: Thu Jan 01 00:00:00 1970 +0000
665 665 summary: added
666 666
667 667 changeset: 12:710c1b2f523c
668 668 parent: 10:34f23ac6ac12
669 669 user: test
670 670 date: Thu Jan 01 00:00:00 1970 +0000
671 671 summary: removed large
672 672
673 673 changeset: 13:0a3e75774479
674 674 user: test
675 675 date: Thu Jan 01 00:00:00 1970 +0000
676 676 summary: this used to add large8 as normal and commit both
677 677
678 678 changeset: 14:84f3d378175c
679 679 user: test
680 680 date: Thu Jan 01 00:00:00 1970 +0000
681 681 summary: this used to not notice the rm
682 682
683 683 largefiles to upload (1 entities):
684 684 large8
685 685
686 686 $ cd ../a
687 687
688 688 Clone a largefiles repo.
689 689
690 690 $ hg clone . ../b
691 691 updating to branch default
692 692 getting changed largefiles
693 693 3 largefiles updated, 0 removed
694 694 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
695 695 $ cd ../b
696 696 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
697 697 7:daea875e9014 add/edit more largefiles
698 698 6:4355d653f84f edit files yet again
699 699 5:9d5af5072dbd edit files again
700 700 4:74c02385b94c move files
701 701 3:9e8fbc4bce62 copy files
702 702 2:51a0ae4d5864 remove files
703 703 1:ce8896473775 edit files
704 704 0:30d30fe6a5be add files
705 705 $ cat normal3
706 706 normal33
707 707
708 708 Test graph log
709 709
710 710 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
711 711 @ 7:daea875e9014 add/edit more largefiles
712 712 |
713 713 o 6:4355d653f84f edit files yet again
714 714 |
715 715 o 5:9d5af5072dbd edit files again
716 716 |
717 717 o 4:74c02385b94c move files
718 718 |
719 719 o 3:9e8fbc4bce62 copy files
720 720 |
721 721 o 2:51a0ae4d5864 remove files
722 722 |
723 723 o 1:ce8896473775 edit files
724 724 |
725 725 o 0:30d30fe6a5be add files
726 726
727 727
728 728 Test log with --patch
729 729
730 730 $ hg log --patch -r 6::7
731 731 changeset: 6:4355d653f84f
732 732 user: test
733 733 date: Thu Jan 01 00:00:00 1970 +0000
734 734 summary: edit files yet again
735 735
736 736 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
737 737 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
738 738 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
739 739 @@ -1,1 +1,1 @@
740 740 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
741 741 +7838695e10da2bb75ac1156565f40a2595fa2fa0
742 742 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
743 743 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
744 744 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
745 745 @@ -1,1 +1,1 @@
746 746 -aeb2210d19f02886dde00dac279729a48471e2f9
747 747 +971fb41e78fea4f8e0ba5244784239371cb00591
748 748 diff -r 9d5af5072dbd -r 4355d653f84f normal3
749 749 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
750 750 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
751 751 @@ -1,1 +1,1 @@
752 752 -normal3
753 753 +normal33
754 754 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
755 755 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
756 756 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
757 757 @@ -1,1 +1,1 @@
758 758 -normal4
759 759 +normal44
760 760
761 761 changeset: 7:daea875e9014
762 762 tag: tip
763 763 user: test
764 764 date: Thu Jan 01 00:00:00 1970 +0000
765 765 summary: add/edit more largefiles
766 766
767 767 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
768 768 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
769 769 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
770 770 @@ -1,1 +0,0 @@
771 771 -7838695e10da2bb75ac1156565f40a2595fa2fa0
772 772 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
773 773 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
774 774 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
775 775 @@ -0,0 +1,1 @@
776 776 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
777 777 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
778 778 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
779 779 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
780 780 @@ -0,0 +1,1 @@
781 781 +bb3151689acb10f0c3125c560d5e63df914bc1af
782 782
783 783
784 784 $ hg log --patch -r 6::7 sub/
785 785 changeset: 6:4355d653f84f
786 786 user: test
787 787 date: Thu Jan 01 00:00:00 1970 +0000
788 788 summary: edit files yet again
789 789
790 790 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
791 791 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
792 792 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
793 793 @@ -1,1 +1,1 @@
794 794 -aeb2210d19f02886dde00dac279729a48471e2f9
795 795 +971fb41e78fea4f8e0ba5244784239371cb00591
796 796 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
797 797 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
798 798 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
799 799 @@ -1,1 +1,1 @@
800 800 -normal4
801 801 +normal44
802 802
803 803
804 804 log with both --follow and --patch
805 805
806 806 $ hg log --follow --patch --limit 2
807 807 changeset: 7:daea875e9014
808 808 tag: tip
809 809 user: test
810 810 date: Thu Jan 01 00:00:00 1970 +0000
811 811 summary: add/edit more largefiles
812 812
813 813 diff -r 4355d653f84f -r daea875e9014 .hglf/large3
814 814 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
815 815 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
816 816 @@ -1,1 +0,0 @@
817 817 -7838695e10da2bb75ac1156565f40a2595fa2fa0
818 818 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large6
819 819 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
820 820 +++ b/.hglf/sub2/large6 Thu Jan 01 00:00:00 1970 +0000
821 821 @@ -0,0 +1,1 @@
822 822 +0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30
823 823 diff -r 4355d653f84f -r daea875e9014 .hglf/sub2/large7
824 824 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
825 825 +++ b/.hglf/sub2/large7 Thu Jan 01 00:00:00 1970 +0000
826 826 @@ -0,0 +1,1 @@
827 827 +bb3151689acb10f0c3125c560d5e63df914bc1af
828 828
829 829 changeset: 6:4355d653f84f
830 830 user: test
831 831 date: Thu Jan 01 00:00:00 1970 +0000
832 832 summary: edit files yet again
833 833
834 834 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/large3
835 835 --- a/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
836 836 +++ b/.hglf/large3 Thu Jan 01 00:00:00 1970 +0000
837 837 @@ -1,1 +1,1 @@
838 838 -baaf12afde9d8d67f25dab6dced0d2bf77dba47c
839 839 +7838695e10da2bb75ac1156565f40a2595fa2fa0
840 840 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
841 841 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
842 842 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
843 843 @@ -1,1 +1,1 @@
844 844 -aeb2210d19f02886dde00dac279729a48471e2f9
845 845 +971fb41e78fea4f8e0ba5244784239371cb00591
846 846 diff -r 9d5af5072dbd -r 4355d653f84f normal3
847 847 --- a/normal3 Thu Jan 01 00:00:00 1970 +0000
848 848 +++ b/normal3 Thu Jan 01 00:00:00 1970 +0000
849 849 @@ -1,1 +1,1 @@
850 850 -normal3
851 851 +normal33
852 852 diff -r 9d5af5072dbd -r 4355d653f84f sub/normal4
853 853 --- a/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
854 854 +++ b/sub/normal4 Thu Jan 01 00:00:00 1970 +0000
855 855 @@ -1,1 +1,1 @@
856 856 -normal4
857 857 +normal44
858 858
859 859 $ hg log --follow --patch sub/large4
860 860 changeset: 6:4355d653f84f
861 861 user: test
862 862 date: Thu Jan 01 00:00:00 1970 +0000
863 863 summary: edit files yet again
864 864
865 865 diff -r 9d5af5072dbd -r 4355d653f84f .hglf/sub/large4
866 866 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
867 867 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
868 868 @@ -1,1 +1,1 @@
869 869 -aeb2210d19f02886dde00dac279729a48471e2f9
870 870 +971fb41e78fea4f8e0ba5244784239371cb00591
871 871
872 872 changeset: 5:9d5af5072dbd
873 873 user: test
874 874 date: Thu Jan 01 00:00:00 1970 +0000
875 875 summary: edit files again
876 876
877 877 diff -r 74c02385b94c -r 9d5af5072dbd .hglf/sub/large4
878 878 --- a/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
879 879 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
880 880 @@ -1,1 +1,1 @@
881 881 -eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
882 882 +aeb2210d19f02886dde00dac279729a48471e2f9
883 883
884 884 changeset: 4:74c02385b94c
885 885 user: test
886 886 date: Thu Jan 01 00:00:00 1970 +0000
887 887 summary: move files
888 888
889 889 diff -r 9e8fbc4bce62 -r 74c02385b94c .hglf/sub/large4
890 890 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
891 891 +++ b/.hglf/sub/large4 Thu Jan 01 00:00:00 1970 +0000
892 892 @@ -0,0 +1,1 @@
893 893 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
894 894
895 895 changeset: 1:ce8896473775
896 896 user: test
897 897 date: Thu Jan 01 00:00:00 1970 +0000
898 898 summary: edit files
899 899
900 900 diff -r 30d30fe6a5be -r ce8896473775 .hglf/sub/large2
901 901 --- a/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
902 902 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
903 903 @@ -1,1 +1,1 @@
904 904 -1deebade43c8c498a3c8daddac0244dc55d1331d
905 905 +eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
906 906
907 907 changeset: 0:30d30fe6a5be
908 908 user: test
909 909 date: Thu Jan 01 00:00:00 1970 +0000
910 910 summary: add files
911 911
912 912 diff -r 000000000000 -r 30d30fe6a5be .hglf/sub/large2
913 913 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
914 914 +++ b/.hglf/sub/large2 Thu Jan 01 00:00:00 1970 +0000
915 915 @@ -0,0 +1,1 @@
916 916 +1deebade43c8c498a3c8daddac0244dc55d1331d
917 917
918 918 $ cat sub/normal4
919 919 normal44
920 920 $ cat sub/large4
921 921 large44
922 922 $ cat sub2/large6
923 923 large6
924 924 $ cat sub2/large7
925 925 large7
926 926 $ hg log -qf sub2/large7
927 927 7:daea875e9014
928 928 $ hg log -Gqf sub2/large7
929 929 @ 7:daea875e9014
930 930 |
931 931 $ cd ..
932 932
933 933 Test log from outside repo
934 934
935 935 $ hg log b/sub -T '{rev}:{node|short} {desc|firstline}\n'
936 936 6:4355d653f84f edit files yet again
937 937 5:9d5af5072dbd edit files again
938 938 4:74c02385b94c move files
939 939 1:ce8896473775 edit files
940 940 0:30d30fe6a5be add files
941 941
942 942 Test clone at revision
943 943
944 944 $ hg clone a -r 3 c
945 945 adding changesets
946 946 adding manifests
947 947 adding file changes
948 948 added 4 changesets with 10 changes to 4 files
949 949 updating to branch default
950 950 getting changed largefiles
951 951 2 largefiles updated, 0 removed
952 952 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
953 953 $ cd c
954 954 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
955 955 3:9e8fbc4bce62 copy files
956 956 2:51a0ae4d5864 remove files
957 957 1:ce8896473775 edit files
958 958 0:30d30fe6a5be add files
959 959 $ cat normal1
960 960 normal22
961 961 $ cat large1
962 962 large22
963 963 $ cat sub/normal2
964 964 normal22
965 965 $ cat sub/large2
966 966 large22
967 967
968 968 Old revisions of a clone have correct largefiles content (this also
969 969 tests update).
970 970
971 971 $ hg update -r 1
972 972 getting changed largefiles
973 973 1 largefiles updated, 0 removed
974 974 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
975 975 $ cat large1
976 976 large11
977 977 $ cat sub/large2
978 978 large22
979 979 $ cd ..
980 980
981 981 Test cloning with --all-largefiles flag
982 982
983 983 $ rm "${USERCACHE}"/*
984 984 $ hg clone --all-largefiles a a-backup
985 985 updating to branch default
986 986 getting changed largefiles
987 987 3 largefiles updated, 0 removed
988 988 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
989 989 8 additional largefiles cached
990 990
991 991 $ rm "${USERCACHE}"/*
992 992 $ hg clone --all-largefiles -u 0 a a-clone0
993 993 updating to branch default
994 994 getting changed largefiles
995 995 2 largefiles updated, 0 removed
996 996 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
997 997 9 additional largefiles cached
998 998 $ hg -R a-clone0 sum
999 999 parent: 0:30d30fe6a5be
1000 1000 add files
1001 1001 branch: default
1002 1002 commit: (clean)
1003 1003 update: 7 new changesets (update)
1004 1004
1005 1005 $ rm "${USERCACHE}"/*
1006 1006 $ hg clone --all-largefiles -u 1 a a-clone1
1007 1007 updating to branch default
1008 1008 getting changed largefiles
1009 1009 2 largefiles updated, 0 removed
1010 1010 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1011 1011 8 additional largefiles cached
1012 1012 $ hg -R a-clone1 verify --large --lfa --lfc
1013 1013 checking changesets
1014 1014 checking manifests
1015 1015 crosschecking files in changesets and manifests
1016 1016 checking files
1017 1017 10 files, 8 changesets, 24 total revisions
1018 1018 searching 8 changesets for largefiles
1019 1019 verified contents of 13 revisions of 6 largefiles
1020 1020 $ hg -R a-clone1 sum
1021 1021 parent: 1:ce8896473775
1022 1022 edit files
1023 1023 branch: default
1024 1024 commit: (clean)
1025 1025 update: 6 new changesets (update)
1026 1026
1027 1027 $ rm "${USERCACHE}"/*
1028 1028 $ hg clone --all-largefiles -U a a-clone-u
1029 1029 11 additional largefiles cached
1030 1030 $ hg -R a-clone-u sum
1031 1031 parent: -1:000000000000 (no revision checked out)
1032 1032 branch: default
1033 1033 commit: (clean)
1034 1034 update: 8 new changesets (update)
1035 1035
1036 1036 Show computed destination directory:
1037 1037
1038 1038 $ mkdir xyz
1039 1039 $ cd xyz
1040 1040 $ hg clone ../a
1041 1041 destination directory: a
1042 1042 updating to branch default
1043 1043 getting changed largefiles
1044 1044 3 largefiles updated, 0 removed
1045 1045 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1046 1046 $ cd ..
1047 1047
1048 1048 Clone URL without path:
1049 1049
1050 1050 $ hg clone file://
1051 1051 abort: repository / not found!
1052 1052 [255]
1053 1053
1054 1054 Ensure base clone command argument validation
1055 1055
1056 1056 $ hg clone -U -u 0 a a-clone-failure
1057 1057 abort: cannot specify both --noupdate and --updaterev
1058 1058 [255]
1059 1059
1060 1060 $ hg clone --all-largefiles a ssh://localhost/a
1061 1061 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
1062 1062 [255]
1063 1063
1064 1064 Test pulling with --all-largefiles flag. Also test that the largefiles are
1065 1065 downloaded from 'default' instead of 'default-push' when no source is specified
1066 1066 (issue3584)
1067 1067
1068 1068 $ rm -Rf a-backup
1069 1069 $ hg clone -r 1 a a-backup
1070 1070 adding changesets
1071 1071 adding manifests
1072 1072 adding file changes
1073 1073 added 2 changesets with 8 changes to 4 files
1074 1074 updating to branch default
1075 1075 getting changed largefiles
1076 1076 2 largefiles updated, 0 removed
1077 1077 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1078 1078 $ rm "${USERCACHE}"/*
1079 1079 $ cd a-backup
1080 1080 $ hg pull --all-largefiles --config paths.default-push=bogus/path
1081 1081 pulling from $TESTTMP/a (glob)
1082 1082 searching for changes
1083 1083 adding changesets
1084 1084 adding manifests
1085 1085 adding file changes
1086 1086 added 6 changesets with 16 changes to 8 files
1087 1087 (run 'hg update' to get a working copy)
1088 1088 6 largefiles cached
1089 1089
1090 1090 redo pull with --lfrev and check it pulls largefiles for the right revs
1091 1091
1092 1092 $ hg rollback
1093 1093 repository tip rolled back to revision 1 (undo pull)
1094 1094 $ hg pull -v --lfrev 'heads(pulled())+min(pulled())'
1095 1095 pulling from $TESTTMP/a (glob)
1096 1096 searching for changes
1097 1097 all local heads known remotely
1098 1098 6 changesets found
1099 1099 adding changesets
1100 1100 adding manifests
1101 1101 adding file changes
1102 1102 added 6 changesets with 16 changes to 8 files
1103 1103 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
1104 1104 (run 'hg update' to get a working copy)
1105 1105 pulling largefiles for revision 7
1106 1106 found 971fb41e78fea4f8e0ba5244784239371cb00591 in store
1107 1107 found 0d6d75887db61b2c7e6c74b5dd8fc6ad50c0cc30 in store
1108 1108 found bb3151689acb10f0c3125c560d5e63df914bc1af in store
1109 1109 pulling largefiles for revision 2
1110 1110 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1111 1111 0 largefiles cached
1112 1112
1113 1113 lfpull
1114 1114
1115 1115 $ hg lfpull -r : --config largefiles.usercache=usercache-lfpull
1116 1116 2 largefiles cached
1117 1117 $ hg lfpull -v -r 4+2 --config largefiles.usercache=usercache-lfpull
1118 1118 pulling largefiles for revision 4
1119 1119 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1120 1120 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1121 1121 pulling largefiles for revision 2
1122 1122 found eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 in store
1123 1123 0 largefiles cached
1124 1124
1125 1125 $ ls usercache-lfpull/* | sort
1126 1126 usercache-lfpull/1deebade43c8c498a3c8daddac0244dc55d1331d
1127 1127 usercache-lfpull/4669e532d5b2c093a78eca010077e708a071bb64
1128 1128
1129 1129 $ cd ..
1130 1130
1131 1131 Rebasing between two repositories does not revert largefiles to old
1132 1132 revisions (this was a very bad bug that took a lot of work to fix).
1133 1133
1134 1134 $ hg clone a d
1135 1135 updating to branch default
1136 1136 getting changed largefiles
1137 1137 3 largefiles updated, 0 removed
1138 1138 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1139 1139 $ cd b
1140 1140 $ echo large4-modified > sub/large4
1141 1141 $ echo normal3-modified > normal3
1142 1142 $ hg commit -m "modify normal file and largefile in repo b"
1143 1143 Invoking status precommit hook
1144 1144 M normal3
1145 1145 M sub/large4
1146 1146 $ cd ../d
1147 1147 $ echo large6-modified > sub2/large6
1148 1148 $ echo normal4-modified > sub/normal4
1149 1149 $ hg commit -m "modify normal file largefile in repo d"
1150 1150 Invoking status precommit hook
1151 1151 M sub/normal4
1152 1152 M sub2/large6
1153 1153 $ cd ..
1154 1154 $ hg clone d e
1155 1155 updating to branch default
1156 1156 getting changed largefiles
1157 1157 3 largefiles updated, 0 removed
1158 1158 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1159 1159 $ cd d
1160 1160
1161 1161 More rebase testing, but also test that the largefiles are downloaded from
1162 1162 'default-push' when no source is specified (issue3584). (The largefile from the
1163 1163 pulled revision is however not downloaded but found in the local cache.)
1164 1164 Largefiles are fetched for the new pulled revision, not for existing revisions,
1165 1165 rebased or not.
1166 1166
1167 1167 $ [ ! -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1168 1168 $ hg pull --rebase --all-largefiles --config paths.default-push=bogus/path --config paths.default=../b
1169 1169 pulling from $TESTTMP/b (glob)
1170 1170 searching for changes
1171 1171 adding changesets
1172 1172 adding manifests
1173 1173 adding file changes
1174 1174 added 1 changesets with 2 changes to 2 files (+1 heads)
1175 1175 Invoking status precommit hook
1176 1176 M sub/normal4
1177 1177 M sub2/large6
1178 1178 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
1179 1179 0 largefiles cached
1180 1180 nothing to rebase - working directory parent is also destination
1181 1181 $ [ -f .hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 ]
1182 1182 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1183 1183 9:598410d3eb9a modify normal file largefile in repo d
1184 1184 8:a381d2c8c80e modify normal file and largefile in repo b
1185 1185 7:daea875e9014 add/edit more largefiles
1186 1186 6:4355d653f84f edit files yet again
1187 1187 5:9d5af5072dbd edit files again
1188 1188 4:74c02385b94c move files
1189 1189 3:9e8fbc4bce62 copy files
1190 1190 2:51a0ae4d5864 remove files
1191 1191 1:ce8896473775 edit files
1192 1192 0:30d30fe6a5be add files
1193 1193 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
1194 1194 @ 9:598410d3eb9a modify normal file largefile in repo d
1195 1195 |
1196 1196 o 8:a381d2c8c80e modify normal file and largefile in repo b
1197 1197 |
1198 1198 o 7:daea875e9014 add/edit more largefiles
1199 1199 |
1200 1200 o 6:4355d653f84f edit files yet again
1201 1201 |
1202 1202 o 5:9d5af5072dbd edit files again
1203 1203 |
1204 1204 o 4:74c02385b94c move files
1205 1205 |
1206 1206 o 3:9e8fbc4bce62 copy files
1207 1207 |
1208 1208 o 2:51a0ae4d5864 remove files
1209 1209 |
1210 1210 o 1:ce8896473775 edit files
1211 1211 |
1212 1212 o 0:30d30fe6a5be add files
1213 1213
1214 1214 $ cat normal3
1215 1215 normal3-modified
1216 1216 $ cat sub/normal4
1217 1217 normal4-modified
1218 1218 $ cat sub/large4
1219 1219 large4-modified
1220 1220 $ cat sub2/large6
1221 1221 large6-modified
1222 1222 $ cat sub2/large7
1223 1223 large7
1224 1224 $ cd ../e
1225 1225 $ hg pull ../b
1226 1226 pulling from ../b
1227 1227 searching for changes
1228 1228 adding changesets
1229 1229 adding manifests
1230 1230 adding file changes
1231 1231 added 1 changesets with 2 changes to 2 files (+1 heads)
1232 1232 (run 'hg heads' to see heads, 'hg merge' to merge)
1233 1233 $ hg rebase
1234 1234 Invoking status precommit hook
1235 1235 M sub/normal4
1236 1236 M sub2/large6
1237 1237 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
1238 1238 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1239 1239 9:598410d3eb9a modify normal file largefile in repo d
1240 1240 8:a381d2c8c80e modify normal file and largefile in repo b
1241 1241 7:daea875e9014 add/edit more largefiles
1242 1242 6:4355d653f84f edit files yet again
1243 1243 5:9d5af5072dbd edit files again
1244 1244 4:74c02385b94c move files
1245 1245 3:9e8fbc4bce62 copy files
1246 1246 2:51a0ae4d5864 remove files
1247 1247 1:ce8896473775 edit files
1248 1248 0:30d30fe6a5be add files
1249 1249 $ cat normal3
1250 1250 normal3-modified
1251 1251 $ cat sub/normal4
1252 1252 normal4-modified
1253 1253 $ cat sub/large4
1254 1254 large4-modified
1255 1255 $ cat sub2/large6
1256 1256 large6-modified
1257 1257 $ cat sub2/large7
1258 1258 large7
1259 1259
1260 1260 Log on largefiles
1261 1261
1262 1262 - same output
1263 1263 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1264 1264 8:a381d2c8c80e modify normal file and largefile in repo b
1265 1265 6:4355d653f84f edit files yet again
1266 1266 5:9d5af5072dbd edit files again
1267 1267 4:74c02385b94c move files
1268 1268 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1269 1269 o 8:a381d2c8c80e modify normal file and largefile in repo b
1270 1270 |
1271 1271 o 6:4355d653f84f edit files yet again
1272 1272 |
1273 1273 o 5:9d5af5072dbd edit files again
1274 1274 |
1275 1275 o 4:74c02385b94c move files
1276 1276 |
1277 1277 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub/large4
1278 1278 8:a381d2c8c80e modify normal file and largefile in repo b
1279 1279 6:4355d653f84f edit files yet again
1280 1280 5:9d5af5072dbd edit files again
1281 1281 4:74c02385b94c move files
1282 1282 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub/large4
1283 1283 o 8:a381d2c8c80e modify normal file and largefile in repo b
1284 1284 |
1285 1285 o 6:4355d653f84f edit files yet again
1286 1286 |
1287 1287 o 5:9d5af5072dbd edit files again
1288 1288 |
1289 1289 o 4:74c02385b94c move files
1290 1290 |
1291 1291
1292 1292 - .hglf only matches largefiles, without .hglf it matches 9 bco sub/normal
1293 1293 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1294 1294 8:a381d2c8c80e modify normal file and largefile in repo b
1295 1295 6:4355d653f84f edit files yet again
1296 1296 5:9d5af5072dbd edit files again
1297 1297 4:74c02385b94c move files
1298 1298 1:ce8896473775 edit files
1299 1299 0:30d30fe6a5be add files
1300 1300 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' .hglf/sub
1301 1301 o 8:a381d2c8c80e modify normal file and largefile in repo b
1302 1302 |
1303 1303 o 6:4355d653f84f edit files yet again
1304 1304 |
1305 1305 o 5:9d5af5072dbd edit files again
1306 1306 |
1307 1307 o 4:74c02385b94c move files
1308 1308 |
1309 1309 o 1:ce8896473775 edit files
1310 1310 |
1311 1311 o 0:30d30fe6a5be add files
1312 1312
1313 1313 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' sub
1314 1314 9:598410d3eb9a modify normal file largefile in repo d
1315 1315 8:a381d2c8c80e modify normal file and largefile in repo b
1316 1316 6:4355d653f84f edit files yet again
1317 1317 5:9d5af5072dbd edit files again
1318 1318 4:74c02385b94c move files
1319 1319 1:ce8896473775 edit files
1320 1320 0:30d30fe6a5be add files
1321 1321 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' sub
1322 1322 @ 9:598410d3eb9a modify normal file largefile in repo d
1323 1323 |
1324 1324 o 8:a381d2c8c80e modify normal file and largefile in repo b
1325 1325 |
1326 1326 o 6:4355d653f84f edit files yet again
1327 1327 |
1328 1328 o 5:9d5af5072dbd edit files again
1329 1329 |
1330 1330 o 4:74c02385b94c move files
1331 1331 |
1332 1332 o 1:ce8896473775 edit files
1333 1333 |
1334 1334 o 0:30d30fe6a5be add files
1335 1335
1336 1336 - globbing gives same result
1337 1337 $ hg log --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1338 1338 9:598410d3eb9a modify normal file largefile in repo d
1339 1339 8:a381d2c8c80e modify normal file and largefile in repo b
1340 1340 6:4355d653f84f edit files yet again
1341 1341 5:9d5af5072dbd edit files again
1342 1342 4:74c02385b94c move files
1343 1343 1:ce8896473775 edit files
1344 1344 0:30d30fe6a5be add files
1345 1345 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n' 'glob:sub/*'
1346 1346 @ 9:598410d3eb9a modify normal file largefile in repo d
1347 1347 |
1348 1348 o 8:a381d2c8c80e modify normal file and largefile in repo b
1349 1349 |
1350 1350 o 6:4355d653f84f edit files yet again
1351 1351 |
1352 1352 o 5:9d5af5072dbd edit files again
1353 1353 |
1354 1354 o 4:74c02385b94c move files
1355 1355 |
1356 1356 o 1:ce8896473775 edit files
1357 1357 |
1358 1358 o 0:30d30fe6a5be add files
1359 1359
1360 1360 Rollback on largefiles.
1361 1361
1362 1362 $ echo large4-modified-again > sub/large4
1363 1363 $ hg commit -m "Modify large4 again"
1364 1364 Invoking status precommit hook
1365 1365 M sub/large4
1366 1366 $ hg rollback
1367 1367 repository tip rolled back to revision 9 (undo commit)
1368 1368 working directory now based on revision 9
1369 1369 $ hg st
1370 1370 M sub/large4
1371 1371 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1372 1372 9:598410d3eb9a modify normal file largefile in repo d
1373 1373 8:a381d2c8c80e modify normal file and largefile in repo b
1374 1374 7:daea875e9014 add/edit more largefiles
1375 1375 6:4355d653f84f edit files yet again
1376 1376 5:9d5af5072dbd edit files again
1377 1377 4:74c02385b94c move files
1378 1378 3:9e8fbc4bce62 copy files
1379 1379 2:51a0ae4d5864 remove files
1380 1380 1:ce8896473775 edit files
1381 1381 0:30d30fe6a5be add files
1382 1382 $ cat sub/large4
1383 1383 large4-modified-again
1384 1384
1385 1385 "update --check" refuses to update with uncommitted changes.
1386 1386 $ hg update --check 8
1387 1387 abort: uncommitted changes
1388 1388 [255]
1389 1389
1390 1390 "update --clean" leaves correct largefiles in working copy, even when there is
1391 1391 .orig files from revert in .hglf.
1392 1392
1393 1393 $ echo mistake > sub2/large7
1394 1394 $ hg revert sub2/large7
1395 1395 $ cat sub2/large7
1396 1396 large7
1397 1397 $ cat sub2/large7.orig
1398 1398 mistake
1399 1399 $ test ! -f .hglf/sub2/large7.orig
1400 1400
1401 1401 $ hg -q update --clean -r null
1402 1402 $ hg update --clean
1403 1403 getting changed largefiles
1404 1404 3 largefiles updated, 0 removed
1405 1405 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1406 1406 $ cat normal3
1407 1407 normal3-modified
1408 1408 $ cat sub/normal4
1409 1409 normal4-modified
1410 1410 $ cat sub/large4
1411 1411 large4-modified
1412 1412 $ cat sub2/large6
1413 1413 large6-modified
1414 1414 $ cat sub2/large7
1415 1415 large7
1416 1416 $ cat sub2/large7.orig
1417 1417 mistake
1418 1418 $ test ! -f .hglf/sub2/large7.orig
1419 1419
1420 1420 verify that largefile .orig file no longer is overwritten on every update -C:
1421 1421 $ hg update --clean
1422 1422 getting changed largefiles
1423 1423 0 largefiles updated, 0 removed
1424 1424 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1425 1425 $ cat sub2/large7.orig
1426 1426 mistake
1427 1427 $ rm sub2/large7.orig
1428 1428
1429 1429 Now "update check" is happy.
1430 1430 $ hg update --check 8
1431 1431 getting changed largefiles
1432 1432 1 largefiles updated, 0 removed
1433 1433 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1434 1434 $ hg update --check
1435 1435 getting changed largefiles
1436 1436 1 largefiles updated, 0 removed
1437 1437 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1438 1438
1439 1439 Test removing empty largefiles directories on update
1440 1440 $ test -d sub2 && echo "sub2 exists"
1441 1441 sub2 exists
1442 1442 $ hg update -q null
1443 1443 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1444 1444 [1]
1445 1445 $ hg update -q
1446 1446
1447 1447 Test hg remove removes empty largefiles directories
1448 1448 $ test -d sub2 && echo "sub2 exists"
1449 1449 sub2 exists
1450 1450 $ hg remove sub2/*
1451 1451 $ test -d sub2 && echo "error: sub2 should not exist anymore"
1452 1452 [1]
1453 1453 $ hg revert sub2/large6 sub2/large7
1454 1454
1455 1455 "revert" works on largefiles (and normal files too).
1456 1456 $ echo hack3 >> normal3
1457 1457 $ echo hack4 >> sub/normal4
1458 1458 $ echo hack4 >> sub/large4
1459 1459 $ rm sub2/large6
1460 1460 $ hg revert sub2/large6
1461 1461 $ hg rm sub2/large6
1462 1462 $ echo new >> sub2/large8
1463 1463 $ hg add --large sub2/large8
1464 1464 # XXX we don't really want to report that we're reverting the standin;
1465 1465 # that's just an implementation detail. But I don't see an obvious fix. ;-(
1466 1466 $ hg revert sub
1467 1467 reverting .hglf/sub/large4 (glob)
1468 1468 reverting sub/normal4 (glob)
1469 1469 $ hg status
1470 1470 M normal3
1471 1471 A sub2/large8
1472 1472 R sub2/large6
1473 1473 ? sub/large4.orig
1474 1474 ? sub/normal4.orig
1475 1475 $ cat sub/normal4
1476 1476 normal4-modified
1477 1477 $ cat sub/large4
1478 1478 large4-modified
1479 1479 $ hg revert -a --no-backup
1480 1480 undeleting .hglf/sub2/large6 (glob)
1481 1481 forgetting .hglf/sub2/large8 (glob)
1482 1482 reverting normal3
1483 1483 $ hg status
1484 1484 ? sub/large4.orig
1485 1485 ? sub/normal4.orig
1486 1486 ? sub2/large8
1487 1487 $ cat normal3
1488 1488 normal3-modified
1489 1489 $ cat sub2/large6
1490 1490 large6-modified
1491 1491 $ rm sub/*.orig sub2/large8
1492 1492
1493 1493 revert some files to an older revision
1494 1494 $ hg revert --no-backup -r 8 sub2
1495 1495 reverting .hglf/sub2/large6 (glob)
1496 1496 $ cat sub2/large6
1497 1497 large6
1498 1498 $ hg revert --no-backup -C -r '.^' sub2
1499 1499 $ hg revert --no-backup sub2
1500 1500 reverting .hglf/sub2/large6 (glob)
1501 1501 $ hg status
1502 1502
1503 1503 "verify --large" actually verifies largefiles
1504 1504
1505 1505 - Where Do We Come From? What Are We? Where Are We Going?
1506 1506 $ pwd
1507 1507 $TESTTMP/e
1508 1508 $ hg paths
1509 1509 default = $TESTTMP/d (glob)
1510 1510
1511 1511 $ hg verify --large
1512 1512 checking changesets
1513 1513 checking manifests
1514 1514 crosschecking files in changesets and manifests
1515 1515 checking files
1516 1516 10 files, 10 changesets, 28 total revisions
1517 1517 searching 1 changesets for largefiles
1518 1518 verified existence of 3 revisions of 3 largefiles
1519 1519
1520 1520 - introduce missing blob in local store repo and make sure that this is caught:
1521 1521 $ mv $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 .
1522 1522 $ hg verify --large
1523 1523 checking changesets
1524 1524 checking manifests
1525 1525 crosschecking files in changesets and manifests
1526 1526 checking files
1527 1527 10 files, 10 changesets, 28 total revisions
1528 1528 searching 1 changesets for largefiles
1529 1529 changeset 9:598410d3eb9a: sub/large4 references missing $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1530 1530 verified existence of 3 revisions of 3 largefiles
1531 1531 [1]
1532 1532
1533 1533 - introduce corruption and make sure that it is caught when checking content:
1534 1534 $ echo '5 cents' > $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928
1535 1535 $ hg verify -q --large --lfc
1536 1536 changeset 9:598410d3eb9a: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/e166e74c7303192238d60af5a9c4ce9bef0b7928 (glob)
1537 1537 [1]
1538 1538
1539 1539 - cleanup
1540 1540 $ mv e166e74c7303192238d60af5a9c4ce9bef0b7928 $TESTTMP/d/.hg/largefiles/
1541 1541
1542 1542 - verifying all revisions will fail because we didn't clone all largefiles to d:
1543 1543 $ echo 'T-shirt' > $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1544 1544 $ hg verify -q --lfa --lfc
1545 1545 changeset 0:30d30fe6a5be: large1 references missing $TESTTMP/d/.hg/largefiles/4669e532d5b2c093a78eca010077e708a071bb64 (glob)
1546 1546 changeset 0:30d30fe6a5be: sub/large2 references missing $TESTTMP/d/.hg/largefiles/1deebade43c8c498a3c8daddac0244dc55d1331d (glob)
1547 1547 changeset 1:ce8896473775: large1 references missing $TESTTMP/d/.hg/largefiles/5f78770c0e77ba4287ad6ef3071c9bf9c379742f (glob)
1548 1548 changeset 1:ce8896473775: sub/large2 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1549 1549 changeset 3:9e8fbc4bce62: large1 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1550 1550 changeset 4:74c02385b94c: large3 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1551 1551 changeset 4:74c02385b94c: sub/large4 references corrupted $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4 (glob)
1552 1552 changeset 5:9d5af5072dbd: large3 references missing $TESTTMP/d/.hg/largefiles/baaf12afde9d8d67f25dab6dced0d2bf77dba47c (glob)
1553 1553 changeset 5:9d5af5072dbd: sub/large4 references missing $TESTTMP/d/.hg/largefiles/aeb2210d19f02886dde00dac279729a48471e2f9 (glob)
1554 1554 changeset 6:4355d653f84f: large3 references missing $TESTTMP/d/.hg/largefiles/7838695e10da2bb75ac1156565f40a2595fa2fa0 (glob)
1555 1555 [1]
1556 1556
1557 1557 - cleanup
1558 1558 $ rm $TESTTMP/d/.hg/largefiles/eb7338044dc27f9bc59b8dd5a246b065ead7a9c4
1559 1559 $ rm -f .hglf/sub/*.orig
1560 1560
1561 1561 Update to revision with missing largefile - and make sure it really is missing
1562 1562
1563 1563 $ rm ${USERCACHE}/7838695e10da2bb75ac1156565f40a2595fa2fa0
1564 1564 $ hg up -r 6
1565 1565 getting changed largefiles
1566 1566 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1567 1567 1 largefiles updated, 2 removed
1568 1568 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
1569 1569 $ rm normal3
1570 1570 $ echo >> sub/normal4
1571 1571 $ hg ci -m 'commit with missing files'
1572 1572 Invoking status precommit hook
1573 1573 M sub/normal4
1574 1574 ! large3
1575 1575 ! normal3
1576 1576 created new head
1577 1577 $ hg st
1578 1578 ! large3
1579 1579 ! normal3
1580 1580 $ hg up -r.
1581 1581 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1582 1582 $ hg st
1583 1583 ! large3
1584 1584 ! normal3
1585 1585 $ hg up -Cr.
1586 1586 getting changed largefiles
1587 1587 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1588 1588 0 largefiles updated, 0 removed
1589 1589 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1590 1590 $ hg st
1591 1591 ! large3
1592 1592 $ hg rollback
1593 1593 repository tip rolled back to revision 9 (undo commit)
1594 1594 working directory now based on revision 6
1595 1595
1596 1596 Merge with revision with missing largefile - and make sure it tries to fetch it.
1597 1597
1598 1598 $ hg up -Cqr null
1599 1599 $ echo f > f
1600 1600 $ hg ci -Am branch
1601 1601 adding f
1602 1602 Invoking status precommit hook
1603 1603 A f
1604 1604 created new head
1605 1605 $ hg merge -r 6
1606 1606 getting changed largefiles
1607 1607 large3: largefile 7838695e10da2bb75ac1156565f40a2595fa2fa0 not available from file:/*/$TESTTMP/d (glob)
1608 1608 1 largefiles updated, 0 removed
1609 1609 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1610 1610 (branch merge, don't forget to commit)
1611 1611
1612 1612 $ hg rollback -q
1613 1613 $ hg up -Cq
1614 1614
1615 1615 Pulling 0 revisions with --all-largefiles should not fetch for all revisions
1616 1616
1617 1617 $ hg pull --all-largefiles
1618 1618 pulling from $TESTTMP/d (glob)
1619 1619 searching for changes
1620 1620 no changes found
1621 1621
1622 1622 Merging does not revert to old versions of largefiles and also check
1623 1623 that merging after having pulled from a non-default remote works
1624 1624 correctly.
1625 1625
1626 1626 $ cd ..
1627 1627 $ hg clone -r 7 e temp
1628 1628 adding changesets
1629 1629 adding manifests
1630 1630 adding file changes
1631 1631 added 8 changesets with 24 changes to 10 files
1632 1632 updating to branch default
1633 1633 getting changed largefiles
1634 1634 3 largefiles updated, 0 removed
1635 1635 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1636 1636 $ hg clone temp f
1637 1637 updating to branch default
1638 1638 getting changed largefiles
1639 1639 3 largefiles updated, 0 removed
1640 1640 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1641 1641 # Delete the largefiles in the largefiles system cache so that we have an
1642 1642 # opportunity to test that caching after a pull works.
1643 1643 $ rm "${USERCACHE}"/*
1644 1644 $ cd f
1645 1645 $ echo "large4-merge-test" > sub/large4
1646 1646 $ hg commit -m "Modify large4 to test merge"
1647 1647 Invoking status precommit hook
1648 1648 M sub/large4
1649 1649 # Test --cache-largefiles flag
1650 1650 $ hg pull --lfrev 'heads(pulled())' ../e
1651 1651 pulling from ../e
1652 1652 searching for changes
1653 1653 adding changesets
1654 1654 adding manifests
1655 1655 adding file changes
1656 1656 added 2 changesets with 4 changes to 4 files (+1 heads)
1657 1657 (run 'hg heads' to see heads, 'hg merge' to merge)
1658 1658 2 largefiles cached
1659 1659 $ hg merge
1660 1660 largefile sub/large4 has a merge conflict
1661 1661 ancestor was 971fb41e78fea4f8e0ba5244784239371cb00591
1662 1662 keep (l)ocal d846f26643bfa8ec210be40cc93cc6b7ff1128ea or
1663 1663 take (o)ther e166e74c7303192238d60af5a9c4ce9bef0b7928? l
1664 1664 getting changed largefiles
1665 1665 1 largefiles updated, 0 removed
1666 1666 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1667 1667 (branch merge, don't forget to commit)
1668 1668 $ hg commit -m "Merge repos e and f"
1669 1669 Invoking status precommit hook
1670 1670 M normal3
1671 1671 M sub/normal4
1672 1672 M sub2/large6
1673 1673 $ cat normal3
1674 1674 normal3-modified
1675 1675 $ cat sub/normal4
1676 1676 normal4-modified
1677 1677 $ cat sub/large4
1678 1678 large4-merge-test
1679 1679 $ cat sub2/large6
1680 1680 large6-modified
1681 1681 $ cat sub2/large7
1682 1682 large7
1683 1683
1684 1684 Test status after merging with a branch that introduces a new largefile:
1685 1685
1686 1686 $ echo large > large
1687 1687 $ hg add --large large
1688 1688 $ hg commit -m 'add largefile'
1689 1689 Invoking status precommit hook
1690 1690 A large
1691 1691 $ hg update -q ".^"
1692 1692 $ echo change >> normal3
1693 1693 $ hg commit -m 'some change'
1694 1694 Invoking status precommit hook
1695 1695 M normal3
1696 1696 created new head
1697 1697 $ hg merge
1698 1698 getting changed largefiles
1699 1699 1 largefiles updated, 0 removed
1700 1700 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1701 1701 (branch merge, don't forget to commit)
1702 1702 $ hg status
1703 1703 M large
1704 1704
1705 1705 - make sure update of merge with removed largefiles fails as expected
1706 1706 $ hg rm sub2/large6
1707 1707 $ hg up -r.
1708 abort: outstanding uncommitted merges
1708 abort: outstanding uncommitted merge
1709 1709 [255]
1710 1710
1711 1711 - revert should be able to revert files introduced in a pending merge
1712 1712 $ hg revert --all -r .
1713 1713 removing .hglf/large (glob)
1714 1714 undeleting .hglf/sub2/large6 (glob)
1715 1715
1716 1716 Test that a normal file and a largefile with the same name and path cannot
1717 1717 coexist.
1718 1718
1719 1719 $ rm sub2/large7
1720 1720 $ echo "largeasnormal" > sub2/large7
1721 1721 $ hg add sub2/large7
1722 1722 sub2/large7 already a largefile
1723 1723
1724 1724 Test that transplanting a largefile change works correctly.
1725 1725
1726 1726 $ cd ..
1727 1727 $ hg clone -r 8 d g
1728 1728 adding changesets
1729 1729 adding manifests
1730 1730 adding file changes
1731 1731 added 9 changesets with 26 changes to 10 files
1732 1732 updating to branch default
1733 1733 getting changed largefiles
1734 1734 3 largefiles updated, 0 removed
1735 1735 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1736 1736 $ cd g
1737 1737 $ hg transplant -s ../d 598410d3eb9a
1738 1738 searching for changes
1739 1739 searching for changes
1740 1740 adding changesets
1741 1741 adding manifests
1742 1742 adding file changes
1743 1743 added 1 changesets with 2 changes to 2 files
1744 1744 getting changed largefiles
1745 1745 0 largefiles updated, 0 removed
1746 1746 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1747 1747 9:598410d3eb9a modify normal file largefile in repo d
1748 1748 8:a381d2c8c80e modify normal file and largefile in repo b
1749 1749 7:daea875e9014 add/edit more largefiles
1750 1750 6:4355d653f84f edit files yet again
1751 1751 5:9d5af5072dbd edit files again
1752 1752 4:74c02385b94c move files
1753 1753 3:9e8fbc4bce62 copy files
1754 1754 2:51a0ae4d5864 remove files
1755 1755 1:ce8896473775 edit files
1756 1756 0:30d30fe6a5be add files
1757 1757 $ cat normal3
1758 1758 normal3-modified
1759 1759 $ cat sub/normal4
1760 1760 normal4-modified
1761 1761 $ cat sub/large4
1762 1762 large4-modified
1763 1763 $ cat sub2/large6
1764 1764 large6-modified
1765 1765 $ cat sub2/large7
1766 1766 large7
1767 1767
1768 1768 Cat a largefile
1769 1769 $ hg cat normal3
1770 1770 normal3-modified
1771 1771 $ hg cat sub/large4
1772 1772 large4-modified
1773 1773 $ rm "${USERCACHE}"/*
1774 1774 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1775 1775 $ cat cat.out
1776 1776 large4-modified
1777 1777 $ rm cat.out
1778 1778 $ hg cat -r a381d2c8c80e normal3
1779 1779 normal3-modified
1780 1780 $ hg cat -r '.^' normal3
1781 1781 normal3-modified
1782 1782 $ hg cat -r '.^' sub/large4 doesntexist
1783 1783 large4-modified
1784 1784 doesntexist: no such file in rev a381d2c8c80e
1785 1785 $ hg --cwd sub cat -r '.^' large4
1786 1786 large4-modified
1787 1787 $ hg --cwd sub cat -r '.^' ../normal3
1788 1788 normal3-modified
1789 1789 Cat a standin
1790 1790 $ hg cat .hglf/sub/large4
1791 1791 e166e74c7303192238d60af5a9c4ce9bef0b7928
1792 1792 $ hg cat .hglf/normal3
1793 1793 .hglf/normal3: no such file in rev 598410d3eb9a
1794 1794 [1]
1795 1795
1796 1796 Test that renaming a largefile results in correct output for status
1797 1797
1798 1798 $ hg rename sub/large4 large4-renamed
1799 1799 $ hg commit -m "test rename output"
1800 1800 Invoking status precommit hook
1801 1801 A large4-renamed
1802 1802 R sub/large4
1803 1803 $ cat large4-renamed
1804 1804 large4-modified
1805 1805 $ cd sub2
1806 1806 $ hg rename large6 large6-renamed
1807 1807 $ hg st
1808 1808 A sub2/large6-renamed
1809 1809 R sub2/large6
1810 1810 $ cd ..
1811 1811
1812 1812 Test --normal flag
1813 1813
1814 1814 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1815 1815 $ hg add --normal --large new-largefile
1816 1816 abort: --normal cannot be used with --large
1817 1817 [255]
1818 1818 $ hg add --normal new-largefile
1819 1819 new-largefile: up to 69 MB of RAM may be required to manage this file
1820 1820 (use 'hg revert new-largefile' to cancel the pending addition)
1821 1821 $ cd ..
1822 1822
1823 1823
1824 1824
General Comments 0
You need to be logged in to leave comments. Login now