##// END OF EJS Templates
posix: give the cached symlink a real target...
Martijn Pieters -
r30555:6a672c3b default
parent child Browse files
Show More
@@ -1,642 +1,651
1 1 # posix.py - Posix utility function implementations for Mercurial
2 2 #
3 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import errno
11 11 import fcntl
12 12 import getpass
13 13 import grp
14 14 import os
15 15 import pwd
16 16 import re
17 17 import select
18 18 import stat
19 19 import sys
20 20 import tempfile
21 21 import unicodedata
22 22
23 23 from .i18n import _
24 24 from . import (
25 25 encoding,
26 26 )
27 27
28 28 posixfile = open
29 29 normpath = os.path.normpath
30 30 samestat = os.path.samestat
31 31 try:
32 32 oslink = os.link
33 33 except AttributeError:
34 34 # Some platforms build Python without os.link on systems that are
35 35 # vaguely unix-like but don't have hardlink support. For those
36 36 # poor souls, just say we tried and that it failed so we fall back
37 37 # to copies.
38 38 def oslink(src, dst):
39 39 raise OSError(errno.EINVAL,
40 40 'hardlinks not supported: %s to %s' % (src, dst))
41 41 unlink = os.unlink
42 42 rename = os.rename
43 43 removedirs = os.removedirs
44 44 expandglobs = False
45 45
46 46 umask = os.umask(0)
47 47 os.umask(umask)
48 48
49 49 def split(p):
50 50 '''Same as posixpath.split, but faster
51 51
52 52 >>> import posixpath
53 53 >>> for f in ['/absolute/path/to/file',
54 54 ... 'relative/path/to/file',
55 55 ... 'file_alone',
56 56 ... 'path/to/directory/',
57 57 ... '/multiple/path//separators',
58 58 ... '/file_at_root',
59 59 ... '///multiple_leading_separators_at_root',
60 60 ... '']:
61 61 ... assert split(f) == posixpath.split(f), f
62 62 '''
63 63 ht = p.rsplit('/', 1)
64 64 if len(ht) == 1:
65 65 return '', p
66 66 nh = ht[0].rstrip('/')
67 67 if nh:
68 68 return nh, ht[1]
69 69 return ht[0] + '/', ht[1]
70 70
71 71 def openhardlinks():
72 72 '''return true if it is safe to hold open file handles to hardlinks'''
73 73 return True
74 74
75 75 def nlinks(name):
76 76 '''return number of hardlinks for the given file'''
77 77 return os.lstat(name).st_nlink
78 78
79 79 def parsepatchoutput(output_line):
80 80 """parses the output produced by patch and returns the filename"""
81 81 pf = output_line[14:]
82 82 if os.sys.platform == 'OpenVMS':
83 83 if pf[0] == '`':
84 84 pf = pf[1:-1] # Remove the quotes
85 85 else:
86 86 if pf.startswith("'") and pf.endswith("'") and " " in pf:
87 87 pf = pf[1:-1] # Remove the quotes
88 88 return pf
89 89
90 90 def sshargs(sshcmd, host, user, port):
91 91 '''Build argument list for ssh'''
92 92 args = user and ("%s@%s" % (user, host)) or host
93 93 return port and ("%s -p %s" % (args, port)) or args
94 94
95 95 def isexec(f):
96 96 """check whether a file is executable"""
97 97 return (os.lstat(f).st_mode & 0o100 != 0)
98 98
99 99 def setflags(f, l, x):
100 100 s = os.lstat(f).st_mode
101 101 if l:
102 102 if not stat.S_ISLNK(s):
103 103 # switch file to link
104 104 fp = open(f)
105 105 data = fp.read()
106 106 fp.close()
107 107 os.unlink(f)
108 108 try:
109 109 os.symlink(data, f)
110 110 except OSError:
111 111 # failed to make a link, rewrite file
112 112 fp = open(f, "w")
113 113 fp.write(data)
114 114 fp.close()
115 115 # no chmod needed at this point
116 116 return
117 117 if stat.S_ISLNK(s):
118 118 # switch link to file
119 119 data = os.readlink(f)
120 120 os.unlink(f)
121 121 fp = open(f, "w")
122 122 fp.write(data)
123 123 fp.close()
124 124 s = 0o666 & ~umask # avoid restatting for chmod
125 125
126 126 sx = s & 0o100
127 127 if x and not sx:
128 128 # Turn on +x for every +r bit when making a file executable
129 129 # and obey umask.
130 130 os.chmod(f, s | (s & 0o444) >> 2 & ~umask)
131 131 elif not x and sx:
132 132 # Turn off all +x bits
133 133 os.chmod(f, s & 0o666)
134 134
135 135 def copymode(src, dst, mode=None):
136 136 '''Copy the file mode from the file at path src to dst.
137 137 If src doesn't exist, we're using mode instead. If mode is None, we're
138 138 using umask.'''
139 139 try:
140 140 st_mode = os.lstat(src).st_mode & 0o777
141 141 except OSError as inst:
142 142 if inst.errno != errno.ENOENT:
143 143 raise
144 144 st_mode = mode
145 145 if st_mode is None:
146 146 st_mode = ~umask
147 147 st_mode &= 0o666
148 148 os.chmod(dst, st_mode)
149 149
150 150 def checkexec(path):
151 151 """
152 152 Check whether the given path is on a filesystem with UNIX-like exec flags
153 153
154 154 Requires a directory (like /foo/.hg)
155 155 """
156 156
157 157 # VFAT on some Linux versions can flip mode but it doesn't persist
158 158 # a FS remount. Frequently we can detect it if files are created
159 159 # with exec bit on.
160 160
161 161 try:
162 162 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
163 163 cachedir = os.path.join(path, '.hg', 'cache')
164 164 if os.path.isdir(cachedir):
165 165 checkisexec = os.path.join(cachedir, 'checkisexec')
166 166 checknoexec = os.path.join(cachedir, 'checknoexec')
167 167
168 168 try:
169 169 m = os.stat(checkisexec).st_mode
170 170 except OSError as e:
171 171 if e.errno != errno.ENOENT:
172 172 raise
173 173 # checkisexec does not exist - fall through ...
174 174 else:
175 175 # checkisexec exists, check if it actually is exec
176 176 if m & EXECFLAGS != 0:
177 177 # ensure checkisexec exists, check it isn't exec
178 178 try:
179 179 m = os.stat(checknoexec).st_mode
180 180 except OSError as e:
181 181 if e.errno != errno.ENOENT:
182 182 raise
183 183 file(checknoexec, 'w').close() # might fail
184 184 m = os.stat(checknoexec).st_mode
185 185 if m & EXECFLAGS == 0:
186 186 # check-exec is exec and check-no-exec is not exec
187 187 return True
188 188 # checknoexec exists but is exec - delete it
189 189 os.unlink(checknoexec)
190 190 # checkisexec exists but is not exec - delete it
191 191 os.unlink(checkisexec)
192 192
193 193 # check using one file, leave it as checkisexec
194 194 checkdir = cachedir
195 195 else:
196 196 # check directly in path and don't leave checkisexec behind
197 197 checkdir = path
198 198 checkisexec = None
199 199 fh, fn = tempfile.mkstemp(dir=checkdir, prefix='hg-checkexec-')
200 200 try:
201 201 os.close(fh)
202 202 m = os.stat(fn).st_mode
203 203 if m & EXECFLAGS == 0:
204 204 os.chmod(fn, m & 0o777 | EXECFLAGS)
205 205 if os.stat(fn).st_mode & EXECFLAGS != 0:
206 206 if checkisexec is not None:
207 207 os.rename(fn, checkisexec)
208 208 fn = None
209 209 return True
210 210 finally:
211 211 if fn is not None:
212 212 os.unlink(fn)
213 213 except (IOError, OSError):
214 214 # we don't care, the user probably won't be able to commit anyway
215 215 return False
216 216
217 217 def checklink(path):
218 218 """check whether the given path is on a symlink-capable filesystem"""
219 219 # mktemp is not racy because symlink creation will fail if the
220 220 # file already exists
221 221 while True:
222 222 cachedir = os.path.join(path, '.hg', 'cache')
223 223 checklink = os.path.join(cachedir, 'checklink')
224 224 # try fast path, read only
225 225 if os.path.islink(checklink):
226 226 return True
227 227 if os.path.isdir(cachedir):
228 228 checkdir = cachedir
229 229 else:
230 230 checkdir = path
231 231 cachedir = None
232 232 name = tempfile.mktemp(dir=checkdir, prefix='checklink-')
233 233 try:
234 fd = tempfile.NamedTemporaryFile(dir=checkdir,
235 prefix='hg-checklink-')
234 fd = None
235 if cachedir is None:
236 fd = tempfile.NamedTemporaryFile(dir=checkdir,
237 prefix='hg-checklink-')
238 target = os.path.basename(fd.name)
239 else:
240 # create a fixed file to link to; doesn't matter if it
241 # already exists.
242 target = 'checklink-target'
243 open(os.path.join(cachedir, target), 'w').close()
236 244 try:
237 os.symlink(os.path.basename(fd.name), name)
245 os.symlink(target, name)
238 246 if cachedir is None:
239 247 os.unlink(name)
240 248 else:
241 249 try:
242 250 os.rename(name, checklink)
243 251 except OSError:
244 252 os.unlink(name)
245 253 return True
246 254 except OSError as inst:
247 255 # link creation might race, try again
248 256 if inst[0] == errno.EEXIST:
249 257 continue
250 258 raise
251 259 finally:
252 fd.close()
260 if fd is not None:
261 fd.close()
253 262 except AttributeError:
254 263 return False
255 264 except OSError as inst:
256 265 # sshfs might report failure while successfully creating the link
257 266 if inst[0] == errno.EIO and os.path.exists(name):
258 267 os.unlink(name)
259 268 return False
260 269
261 270 def checkosfilename(path):
262 271 '''Check that the base-relative path is a valid filename on this platform.
263 272 Returns None if the path is ok, or a UI string describing the problem.'''
264 273 pass # on posix platforms, every path is ok
265 274
266 275 def setbinary(fd):
267 276 pass
268 277
269 278 def pconvert(path):
270 279 return path
271 280
272 281 def localpath(path):
273 282 return path
274 283
275 284 def samefile(fpath1, fpath2):
276 285 """Returns whether path1 and path2 refer to the same file. This is only
277 286 guaranteed to work for files, not directories."""
278 287 return os.path.samefile(fpath1, fpath2)
279 288
280 289 def samedevice(fpath1, fpath2):
281 290 """Returns whether fpath1 and fpath2 are on the same device. This is only
282 291 guaranteed to work for files, not directories."""
283 292 st1 = os.lstat(fpath1)
284 293 st2 = os.lstat(fpath2)
285 294 return st1.st_dev == st2.st_dev
286 295
287 296 # os.path.normcase is a no-op, which doesn't help us on non-native filesystems
288 297 def normcase(path):
289 298 return path.lower()
290 299
291 300 # what normcase does to ASCII strings
292 301 normcasespec = encoding.normcasespecs.lower
293 302 # fallback normcase function for non-ASCII strings
294 303 normcasefallback = normcase
295 304
296 305 if sys.platform == 'darwin':
297 306
298 307 def normcase(path):
299 308 '''
300 309 Normalize a filename for OS X-compatible comparison:
301 310 - escape-encode invalid characters
302 311 - decompose to NFD
303 312 - lowercase
304 313 - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
305 314
306 315 >>> normcase('UPPER')
307 316 'upper'
308 317 >>> normcase('Caf\xc3\xa9')
309 318 'cafe\\xcc\\x81'
310 319 >>> normcase('\xc3\x89')
311 320 'e\\xcc\\x81'
312 321 >>> normcase('\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
313 322 '%b8%ca%c3\\xca\\xbe%c8.jpg'
314 323 '''
315 324
316 325 try:
317 326 return encoding.asciilower(path) # exception for non-ASCII
318 327 except UnicodeDecodeError:
319 328 return normcasefallback(path)
320 329
321 330 normcasespec = encoding.normcasespecs.lower
322 331
323 332 def normcasefallback(path):
324 333 try:
325 334 u = path.decode('utf-8')
326 335 except UnicodeDecodeError:
327 336 # OS X percent-encodes any bytes that aren't valid utf-8
328 337 s = ''
329 338 pos = 0
330 339 l = len(path)
331 340 while pos < l:
332 341 try:
333 342 c = encoding.getutf8char(path, pos)
334 343 pos += len(c)
335 344 except ValueError:
336 345 c = '%%%02X' % ord(path[pos])
337 346 pos += 1
338 347 s += c
339 348
340 349 u = s.decode('utf-8')
341 350
342 351 # Decompose then lowercase (HFS+ technote specifies lower)
343 352 enc = unicodedata.normalize('NFD', u).lower().encode('utf-8')
344 353 # drop HFS+ ignored characters
345 354 return encoding.hfsignoreclean(enc)
346 355
347 356 if sys.platform == 'cygwin':
348 357 # workaround for cygwin, in which mount point part of path is
349 358 # treated as case sensitive, even though underlying NTFS is case
350 359 # insensitive.
351 360
352 361 # default mount points
353 362 cygwinmountpoints = sorted([
354 363 "/usr/bin",
355 364 "/usr/lib",
356 365 "/cygdrive",
357 366 ], reverse=True)
358 367
359 368 # use upper-ing as normcase as same as NTFS workaround
360 369 def normcase(path):
361 370 pathlen = len(path)
362 371 if (pathlen == 0) or (path[0] != os.sep):
363 372 # treat as relative
364 373 return encoding.upper(path)
365 374
366 375 # to preserve case of mountpoint part
367 376 for mp in cygwinmountpoints:
368 377 if not path.startswith(mp):
369 378 continue
370 379
371 380 mplen = len(mp)
372 381 if mplen == pathlen: # mount point itself
373 382 return mp
374 383 if path[mplen] == os.sep:
375 384 return mp + encoding.upper(path[mplen:])
376 385
377 386 return encoding.upper(path)
378 387
379 388 normcasespec = encoding.normcasespecs.other
380 389 normcasefallback = normcase
381 390
382 391 # Cygwin translates native ACLs to POSIX permissions,
383 392 # but these translations are not supported by native
384 393 # tools, so the exec bit tends to be set erroneously.
385 394 # Therefore, disable executable bit access on Cygwin.
386 395 def checkexec(path):
387 396 return False
388 397
389 398 # Similarly, Cygwin's symlink emulation is likely to create
390 399 # problems when Mercurial is used from both Cygwin and native
391 400 # Windows, with other native tools, or on shared volumes
392 401 def checklink(path):
393 402 return False
394 403
395 404 _needsshellquote = None
396 405 def shellquote(s):
397 406 if os.sys.platform == 'OpenVMS':
398 407 return '"%s"' % s
399 408 global _needsshellquote
400 409 if _needsshellquote is None:
401 410 _needsshellquote = re.compile(r'[^a-zA-Z0-9._/+-]').search
402 411 if s and not _needsshellquote(s):
403 412 # "s" shouldn't have to be quoted
404 413 return s
405 414 else:
406 415 return "'%s'" % s.replace("'", "'\\''")
407 416
408 417 def quotecommand(cmd):
409 418 return cmd
410 419
411 420 def popen(command, mode='r'):
412 421 return os.popen(command, mode)
413 422
414 423 def testpid(pid):
415 424 '''return False if pid dead, True if running or not sure'''
416 425 if os.sys.platform == 'OpenVMS':
417 426 return True
418 427 try:
419 428 os.kill(pid, 0)
420 429 return True
421 430 except OSError as inst:
422 431 return inst.errno != errno.ESRCH
423 432
424 433 def explainexit(code):
425 434 """return a 2-tuple (desc, code) describing a subprocess status
426 435 (codes from kill are negative - not os.system/wait encoding)"""
427 436 if code >= 0:
428 437 return _("exited with status %d") % code, code
429 438 return _("killed by signal %d") % -code, -code
430 439
431 440 def isowner(st):
432 441 """Return True if the stat object st is from the current user."""
433 442 return st.st_uid == os.getuid()
434 443
435 444 def findexe(command):
436 445 '''Find executable for command searching like which does.
437 446 If command is a basename then PATH is searched for command.
438 447 PATH isn't searched if command is an absolute or relative path.
439 448 If command isn't found None is returned.'''
440 449 if sys.platform == 'OpenVMS':
441 450 return command
442 451
443 452 def findexisting(executable):
444 453 'Will return executable if existing file'
445 454 if os.path.isfile(executable) and os.access(executable, os.X_OK):
446 455 return executable
447 456 return None
448 457
449 458 if os.sep in command:
450 459 return findexisting(command)
451 460
452 461 if sys.platform == 'plan9':
453 462 return findexisting(os.path.join('/bin', command))
454 463
455 464 for path in os.environ.get('PATH', '').split(os.pathsep):
456 465 executable = findexisting(os.path.join(path, command))
457 466 if executable is not None:
458 467 return executable
459 468 return None
460 469
461 470 def setsignalhandler():
462 471 pass
463 472
464 473 _wantedkinds = set([stat.S_IFREG, stat.S_IFLNK])
465 474
466 475 def statfiles(files):
467 476 '''Stat each file in files. Yield each stat, or None if a file does not
468 477 exist or has a type we don't care about.'''
469 478 lstat = os.lstat
470 479 getkind = stat.S_IFMT
471 480 for nf in files:
472 481 try:
473 482 st = lstat(nf)
474 483 if getkind(st.st_mode) not in _wantedkinds:
475 484 st = None
476 485 except OSError as err:
477 486 if err.errno not in (errno.ENOENT, errno.ENOTDIR):
478 487 raise
479 488 st = None
480 489 yield st
481 490
482 491 def getuser():
483 492 '''return name of current user'''
484 493 return getpass.getuser()
485 494
486 495 def username(uid=None):
487 496 """Return the name of the user with the given uid.
488 497
489 498 If uid is None, return the name of the current user."""
490 499
491 500 if uid is None:
492 501 uid = os.getuid()
493 502 try:
494 503 return pwd.getpwuid(uid)[0]
495 504 except KeyError:
496 505 return str(uid)
497 506
498 507 def groupname(gid=None):
499 508 """Return the name of the group with the given gid.
500 509
501 510 If gid is None, return the name of the current group."""
502 511
503 512 if gid is None:
504 513 gid = os.getgid()
505 514 try:
506 515 return grp.getgrgid(gid)[0]
507 516 except KeyError:
508 517 return str(gid)
509 518
510 519 def groupmembers(name):
511 520 """Return the list of members of the group with the given
512 521 name, KeyError if the group does not exist.
513 522 """
514 523 return list(grp.getgrnam(name).gr_mem)
515 524
516 525 def spawndetached(args):
517 526 return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
518 527 args[0], args)
519 528
520 529 def gethgcmd():
521 530 return sys.argv[:1]
522 531
523 532 def makedir(path, notindexed):
524 533 os.mkdir(path)
525 534
526 535 def unlinkpath(f, ignoremissing=False):
527 536 """unlink and remove the directory if it is empty"""
528 537 try:
529 538 os.unlink(f)
530 539 except OSError as e:
531 540 if not (ignoremissing and e.errno == errno.ENOENT):
532 541 raise
533 542 # try removing directories that might now be empty
534 543 try:
535 544 os.removedirs(os.path.dirname(f))
536 545 except OSError:
537 546 pass
538 547
539 548 def lookupreg(key, name=None, scope=None):
540 549 return None
541 550
542 551 def hidewindow():
543 552 """Hide current shell window.
544 553
545 554 Used to hide the window opened when starting asynchronous
546 555 child process under Windows, unneeded on other systems.
547 556 """
548 557 pass
549 558
550 559 class cachestat(object):
551 560 def __init__(self, path):
552 561 self.stat = os.stat(path)
553 562
554 563 def cacheable(self):
555 564 return bool(self.stat.st_ino)
556 565
557 566 __hash__ = object.__hash__
558 567
559 568 def __eq__(self, other):
560 569 try:
561 570 # Only dev, ino, size, mtime and atime are likely to change. Out
562 571 # of these, we shouldn't compare atime but should compare the
563 572 # rest. However, one of the other fields changing indicates
564 573 # something fishy going on, so return False if anything but atime
565 574 # changes.
566 575 return (self.stat.st_mode == other.stat.st_mode and
567 576 self.stat.st_ino == other.stat.st_ino and
568 577 self.stat.st_dev == other.stat.st_dev and
569 578 self.stat.st_nlink == other.stat.st_nlink and
570 579 self.stat.st_uid == other.stat.st_uid and
571 580 self.stat.st_gid == other.stat.st_gid and
572 581 self.stat.st_size == other.stat.st_size and
573 582 self.stat.st_mtime == other.stat.st_mtime and
574 583 self.stat.st_ctime == other.stat.st_ctime)
575 584 except AttributeError:
576 585 return False
577 586
578 587 def __ne__(self, other):
579 588 return not self == other
580 589
581 590 def executablepath():
582 591 return None # available on Windows only
583 592
584 593 def statislink(st):
585 594 '''check whether a stat result is a symlink'''
586 595 return st and stat.S_ISLNK(st.st_mode)
587 596
588 597 def statisexec(st):
589 598 '''check whether a stat result is an executable file'''
590 599 return st and (st.st_mode & 0o100 != 0)
591 600
592 601 def poll(fds):
593 602 """block until something happens on any file descriptor
594 603
595 604 This is a generic helper that will check for any activity
596 605 (read, write. exception) and return the list of touched files.
597 606
598 607 In unsupported cases, it will raise a NotImplementedError"""
599 608 try:
600 609 res = select.select(fds, fds, fds)
601 610 except ValueError: # out of range file descriptor
602 611 raise NotImplementedError()
603 612 return sorted(list(set(sum(res, []))))
604 613
605 614 def readpipe(pipe):
606 615 """Read all available data from a pipe."""
607 616 # We can't fstat() a pipe because Linux will always report 0.
608 617 # So, we set the pipe to non-blocking mode and read everything
609 618 # that's available.
610 619 flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
611 620 flags |= os.O_NONBLOCK
612 621 oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
613 622
614 623 try:
615 624 chunks = []
616 625 while True:
617 626 try:
618 627 s = pipe.read()
619 628 if not s:
620 629 break
621 630 chunks.append(s)
622 631 except IOError:
623 632 break
624 633
625 634 return ''.join(chunks)
626 635 finally:
627 636 fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
628 637
629 638 def bindunixsocket(sock, path):
630 639 """Bind the UNIX domain socket to the specified path"""
631 640 # use relative path instead of full path at bind() if possible, since
632 641 # AF_UNIX path has very small length limit (107 chars) on common
633 642 # platforms (see sys/un.h)
634 643 dirname, basename = os.path.split(path)
635 644 bakwdfd = None
636 645 if dirname:
637 646 bakwdfd = os.open('.', os.O_DIRECTORY)
638 647 os.chdir(dirname)
639 648 sock.bind(basename)
640 649 if bakwdfd:
641 650 os.fchdir(bakwdfd)
642 651 os.close(bakwdfd)
@@ -1,1092 +1,1094
1 1 Prepare repo a:
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ echo a > a
6 6 $ hg add a
7 7 $ hg commit -m test
8 8 $ echo first line > b
9 9 $ hg add b
10 10
11 11 Create a non-inlined filelog:
12 12
13 13 $ $PYTHON -c 'file("data1", "wb").write("".join("%s\n" % x for x in range(10000)))'
14 14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 15 > cat data1 >> b
16 16 > hg commit -m test
17 17 > done
18 18
19 19 List files in store/data (should show a 'b.d'):
20 20
21 21 $ for i in .hg/store/data/*; do
22 22 > echo $i
23 23 > done
24 24 .hg/store/data/a.i
25 25 .hg/store/data/b.d
26 26 .hg/store/data/b.i
27 27
28 28 Trigger branchcache creation:
29 29
30 30 $ hg branches
31 31 default 10:a7949464abda
32 32 $ ls .hg/cache
33 33 branch2-served
34 34 checkisexec
35 35 checklink
36 checklink-target
36 37 checknoexec
37 38 rbc-names-v1
38 39 rbc-revs-v1
39 40
40 41 Default operation:
41 42
42 43 $ hg clone . ../b
43 44 updating to branch default
44 45 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 46 $ cd ../b
46 47
47 48 Ensure branchcache got copied over:
48 49
49 50 $ ls .hg/cache
50 51 branch2-served
51 52 checkisexec
52 53 checklink
54 checklink-target
53 55
54 56 $ cat a
55 57 a
56 58 $ hg verify
57 59 checking changesets
58 60 checking manifests
59 61 crosschecking files in changesets and manifests
60 62 checking files
61 63 2 files, 11 changesets, 11 total revisions
62 64
63 65 Invalid dest '' must abort:
64 66
65 67 $ hg clone . ''
66 68 abort: empty destination path is not valid
67 69 [255]
68 70
69 71 No update, with debug option:
70 72
71 73 #if hardlink
72 74 $ hg --debug clone -U . ../c --config progress.debug=true
73 75 linking: 1
74 76 linking: 2
75 77 linking: 3
76 78 linking: 4
77 79 linking: 5
78 80 linking: 6
79 81 linking: 7
80 82 linking: 8
81 83 linked 8 files
82 84 #else
83 85 $ hg --debug clone -U . ../c --config progress.debug=true
84 86 linking: 1
85 87 copying: 2
86 88 copying: 3
87 89 copying: 4
88 90 copying: 5
89 91 copying: 6
90 92 copying: 7
91 93 copying: 8
92 94 copied 8 files
93 95 #endif
94 96 $ cd ../c
95 97
96 98 Ensure branchcache got copied over:
97 99
98 100 $ ls .hg/cache
99 101 branch2-served
100 102
101 103 $ cat a 2>/dev/null || echo "a not present"
102 104 a not present
103 105 $ hg verify
104 106 checking changesets
105 107 checking manifests
106 108 crosschecking files in changesets and manifests
107 109 checking files
108 110 2 files, 11 changesets, 11 total revisions
109 111
110 112 Default destination:
111 113
112 114 $ mkdir ../d
113 115 $ cd ../d
114 116 $ hg clone ../a
115 117 destination directory: a
116 118 updating to branch default
117 119 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 120 $ cd a
119 121 $ hg cat a
120 122 a
121 123 $ cd ../..
122 124
123 125 Check that we drop the 'file:' from the path before writing the .hgrc:
124 126
125 127 $ hg clone file:a e
126 128 updating to branch default
127 129 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 130 $ grep 'file:' e/.hg/hgrc
129 131 [1]
130 132
131 133 Check that path aliases are expanded:
132 134
133 135 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
134 136 $ hg -R f showconfig paths.default
135 137 $TESTTMP/a#0 (glob)
136 138
137 139 Use --pull:
138 140
139 141 $ hg clone --pull a g
140 142 requesting all changes
141 143 adding changesets
142 144 adding manifests
143 145 adding file changes
144 146 added 11 changesets with 11 changes to 2 files
145 147 updating to branch default
146 148 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 149 $ hg -R g verify
148 150 checking changesets
149 151 checking manifests
150 152 crosschecking files in changesets and manifests
151 153 checking files
152 154 2 files, 11 changesets, 11 total revisions
153 155
154 156 Invalid dest '' with --pull must abort (issue2528):
155 157
156 158 $ hg clone --pull a ''
157 159 abort: empty destination path is not valid
158 160 [255]
159 161
160 162 Clone to '.':
161 163
162 164 $ mkdir h
163 165 $ cd h
164 166 $ hg clone ../a .
165 167 updating to branch default
166 168 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 169 $ cd ..
168 170
169 171
170 172 *** Tests for option -u ***
171 173
172 174 Adding some more history to repo a:
173 175
174 176 $ cd a
175 177 $ hg tag ref1
176 178 $ echo the quick brown fox >a
177 179 $ hg ci -m "hacked default"
178 180 $ hg up ref1
179 181 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
180 182 $ hg branch stable
181 183 marked working directory as branch stable
182 184 (branches are permanent and global, did you want a bookmark?)
183 185 $ echo some text >a
184 186 $ hg ci -m "starting branch stable"
185 187 $ hg tag ref2
186 188 $ echo some more text >a
187 189 $ hg ci -m "another change for branch stable"
188 190 $ hg up ref2
189 191 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
190 192 $ hg parents
191 193 changeset: 13:e8ece76546a6
192 194 branch: stable
193 195 tag: ref2
194 196 parent: 10:a7949464abda
195 197 user: test
196 198 date: Thu Jan 01 00:00:00 1970 +0000
197 199 summary: starting branch stable
198 200
199 201
200 202 Repo a has two heads:
201 203
202 204 $ hg heads
203 205 changeset: 15:0aae7cf88f0d
204 206 branch: stable
205 207 tag: tip
206 208 user: test
207 209 date: Thu Jan 01 00:00:00 1970 +0000
208 210 summary: another change for branch stable
209 211
210 212 changeset: 12:f21241060d6a
211 213 user: test
212 214 date: Thu Jan 01 00:00:00 1970 +0000
213 215 summary: hacked default
214 216
215 217
216 218 $ cd ..
217 219
218 220
219 221 Testing --noupdate with --updaterev (must abort):
220 222
221 223 $ hg clone --noupdate --updaterev 1 a ua
222 224 abort: cannot specify both --noupdate and --updaterev
223 225 [255]
224 226
225 227
226 228 Testing clone -u:
227 229
228 230 $ hg clone -u . a ua
229 231 updating to branch stable
230 232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 233
232 234 Repo ua has both heads:
233 235
234 236 $ hg -R ua heads
235 237 changeset: 15:0aae7cf88f0d
236 238 branch: stable
237 239 tag: tip
238 240 user: test
239 241 date: Thu Jan 01 00:00:00 1970 +0000
240 242 summary: another change for branch stable
241 243
242 244 changeset: 12:f21241060d6a
243 245 user: test
244 246 date: Thu Jan 01 00:00:00 1970 +0000
245 247 summary: hacked default
246 248
247 249
248 250 Same revision checked out in repo a and ua:
249 251
250 252 $ hg -R a parents --template "{node|short}\n"
251 253 e8ece76546a6
252 254 $ hg -R ua parents --template "{node|short}\n"
253 255 e8ece76546a6
254 256
255 257 $ rm -r ua
256 258
257 259
258 260 Testing clone --pull -u:
259 261
260 262 $ hg clone --pull -u . a ua
261 263 requesting all changes
262 264 adding changesets
263 265 adding manifests
264 266 adding file changes
265 267 added 16 changesets with 16 changes to 3 files (+1 heads)
266 268 updating to branch stable
267 269 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 270
269 271 Repo ua has both heads:
270 272
271 273 $ hg -R ua heads
272 274 changeset: 15:0aae7cf88f0d
273 275 branch: stable
274 276 tag: tip
275 277 user: test
276 278 date: Thu Jan 01 00:00:00 1970 +0000
277 279 summary: another change for branch stable
278 280
279 281 changeset: 12:f21241060d6a
280 282 user: test
281 283 date: Thu Jan 01 00:00:00 1970 +0000
282 284 summary: hacked default
283 285
284 286
285 287 Same revision checked out in repo a and ua:
286 288
287 289 $ hg -R a parents --template "{node|short}\n"
288 290 e8ece76546a6
289 291 $ hg -R ua parents --template "{node|short}\n"
290 292 e8ece76546a6
291 293
292 294 $ rm -r ua
293 295
294 296
295 297 Testing clone -u <branch>:
296 298
297 299 $ hg clone -u stable a ua
298 300 updating to branch stable
299 301 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
300 302
301 303 Repo ua has both heads:
302 304
303 305 $ hg -R ua heads
304 306 changeset: 15:0aae7cf88f0d
305 307 branch: stable
306 308 tag: tip
307 309 user: test
308 310 date: Thu Jan 01 00:00:00 1970 +0000
309 311 summary: another change for branch stable
310 312
311 313 changeset: 12:f21241060d6a
312 314 user: test
313 315 date: Thu Jan 01 00:00:00 1970 +0000
314 316 summary: hacked default
315 317
316 318
317 319 Branch 'stable' is checked out:
318 320
319 321 $ hg -R ua parents
320 322 changeset: 15:0aae7cf88f0d
321 323 branch: stable
322 324 tag: tip
323 325 user: test
324 326 date: Thu Jan 01 00:00:00 1970 +0000
325 327 summary: another change for branch stable
326 328
327 329
328 330 $ rm -r ua
329 331
330 332
331 333 Testing default checkout:
332 334
333 335 $ hg clone a ua
334 336 updating to branch default
335 337 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
336 338
337 339 Repo ua has both heads:
338 340
339 341 $ hg -R ua heads
340 342 changeset: 15:0aae7cf88f0d
341 343 branch: stable
342 344 tag: tip
343 345 user: test
344 346 date: Thu Jan 01 00:00:00 1970 +0000
345 347 summary: another change for branch stable
346 348
347 349 changeset: 12:f21241060d6a
348 350 user: test
349 351 date: Thu Jan 01 00:00:00 1970 +0000
350 352 summary: hacked default
351 353
352 354
353 355 Branch 'default' is checked out:
354 356
355 357 $ hg -R ua parents
356 358 changeset: 12:f21241060d6a
357 359 user: test
358 360 date: Thu Jan 01 00:00:00 1970 +0000
359 361 summary: hacked default
360 362
361 363 Test clone with a branch named "@" (issue3677)
362 364
363 365 $ hg -R ua branch @
364 366 marked working directory as branch @
365 367 $ hg -R ua commit -m 'created branch @'
366 368 $ hg clone ua atbranch
367 369 updating to branch default
368 370 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
369 371 $ hg -R atbranch heads
370 372 changeset: 16:798b6d97153e
371 373 branch: @
372 374 tag: tip
373 375 parent: 12:f21241060d6a
374 376 user: test
375 377 date: Thu Jan 01 00:00:00 1970 +0000
376 378 summary: created branch @
377 379
378 380 changeset: 15:0aae7cf88f0d
379 381 branch: stable
380 382 user: test
381 383 date: Thu Jan 01 00:00:00 1970 +0000
382 384 summary: another change for branch stable
383 385
384 386 changeset: 12:f21241060d6a
385 387 user: test
386 388 date: Thu Jan 01 00:00:00 1970 +0000
387 389 summary: hacked default
388 390
389 391 $ hg -R atbranch parents
390 392 changeset: 12:f21241060d6a
391 393 user: test
392 394 date: Thu Jan 01 00:00:00 1970 +0000
393 395 summary: hacked default
394 396
395 397
396 398 $ rm -r ua atbranch
397 399
398 400
399 401 Testing #<branch>:
400 402
401 403 $ hg clone -u . a#stable ua
402 404 adding changesets
403 405 adding manifests
404 406 adding file changes
405 407 added 14 changesets with 14 changes to 3 files
406 408 updating to branch stable
407 409 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 410
409 411 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
410 412
411 413 $ hg -R ua heads
412 414 changeset: 13:0aae7cf88f0d
413 415 branch: stable
414 416 tag: tip
415 417 user: test
416 418 date: Thu Jan 01 00:00:00 1970 +0000
417 419 summary: another change for branch stable
418 420
419 421 changeset: 10:a7949464abda
420 422 user: test
421 423 date: Thu Jan 01 00:00:00 1970 +0000
422 424 summary: test
423 425
424 426
425 427 Same revision checked out in repo a and ua:
426 428
427 429 $ hg -R a parents --template "{node|short}\n"
428 430 e8ece76546a6
429 431 $ hg -R ua parents --template "{node|short}\n"
430 432 e8ece76546a6
431 433
432 434 $ rm -r ua
433 435
434 436
435 437 Testing -u -r <branch>:
436 438
437 439 $ hg clone -u . -r stable a ua
438 440 adding changesets
439 441 adding manifests
440 442 adding file changes
441 443 added 14 changesets with 14 changes to 3 files
442 444 updating to branch stable
443 445 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 446
445 447 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
446 448
447 449 $ hg -R ua heads
448 450 changeset: 13:0aae7cf88f0d
449 451 branch: stable
450 452 tag: tip
451 453 user: test
452 454 date: Thu Jan 01 00:00:00 1970 +0000
453 455 summary: another change for branch stable
454 456
455 457 changeset: 10:a7949464abda
456 458 user: test
457 459 date: Thu Jan 01 00:00:00 1970 +0000
458 460 summary: test
459 461
460 462
461 463 Same revision checked out in repo a and ua:
462 464
463 465 $ hg -R a parents --template "{node|short}\n"
464 466 e8ece76546a6
465 467 $ hg -R ua parents --template "{node|short}\n"
466 468 e8ece76546a6
467 469
468 470 $ rm -r ua
469 471
470 472
471 473 Testing -r <branch>:
472 474
473 475 $ hg clone -r stable a ua
474 476 adding changesets
475 477 adding manifests
476 478 adding file changes
477 479 added 14 changesets with 14 changes to 3 files
478 480 updating to branch stable
479 481 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 482
481 483 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
482 484
483 485 $ hg -R ua heads
484 486 changeset: 13:0aae7cf88f0d
485 487 branch: stable
486 488 tag: tip
487 489 user: test
488 490 date: Thu Jan 01 00:00:00 1970 +0000
489 491 summary: another change for branch stable
490 492
491 493 changeset: 10:a7949464abda
492 494 user: test
493 495 date: Thu Jan 01 00:00:00 1970 +0000
494 496 summary: test
495 497
496 498
497 499 Branch 'stable' is checked out:
498 500
499 501 $ hg -R ua parents
500 502 changeset: 13:0aae7cf88f0d
501 503 branch: stable
502 504 tag: tip
503 505 user: test
504 506 date: Thu Jan 01 00:00:00 1970 +0000
505 507 summary: another change for branch stable
506 508
507 509
508 510 $ rm -r ua
509 511
510 512
511 513 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
512 514 iterable in addbranchrevs()
513 515
514 516 $ cat <<EOF > simpleclone.py
515 517 > from mercurial import ui, hg
516 518 > myui = ui.ui()
517 519 > repo = hg.repository(myui, 'a')
518 520 > hg.clone(myui, {}, repo, dest="ua")
519 521 > EOF
520 522
521 523 $ python simpleclone.py
522 524 updating to branch default
523 525 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
524 526
525 527 $ rm -r ua
526 528
527 529 $ cat <<EOF > branchclone.py
528 530 > from mercurial import ui, hg, extensions
529 531 > myui = ui.ui()
530 532 > extensions.loadall(myui)
531 533 > repo = hg.repository(myui, 'a')
532 534 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
533 535 > EOF
534 536
535 537 $ python branchclone.py
536 538 adding changesets
537 539 adding manifests
538 540 adding file changes
539 541 added 14 changesets with 14 changes to 3 files
540 542 updating to branch stable
541 543 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
542 544 $ rm -r ua
543 545
544 546
545 547 Test clone with special '@' bookmark:
546 548 $ cd a
547 549 $ hg bookmark -r a7949464abda @ # branch point of stable from default
548 550 $ hg clone . ../i
549 551 updating to bookmark @
550 552 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
551 553 $ hg id -i ../i
552 554 a7949464abda
553 555 $ rm -r ../i
554 556
555 557 $ hg bookmark -f -r stable @
556 558 $ hg bookmarks
557 559 @ 15:0aae7cf88f0d
558 560 $ hg clone . ../i
559 561 updating to bookmark @ on branch stable
560 562 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 563 $ hg id -i ../i
562 564 0aae7cf88f0d
563 565 $ cd "$TESTTMP"
564 566
565 567
566 568 Testing failures:
567 569
568 570 $ mkdir fail
569 571 $ cd fail
570 572
571 573 No local source
572 574
573 575 $ hg clone a b
574 576 abort: repository a not found!
575 577 [255]
576 578
577 579 No remote source
578 580
579 581 #if windows
580 582 $ hg clone http://127.0.0.1:3121/a b
581 583 abort: error: * (glob)
582 584 [255]
583 585 #else
584 586 $ hg clone http://127.0.0.1:3121/a b
585 587 abort: error: *refused* (glob)
586 588 [255]
587 589 #endif
588 590 $ rm -rf b # work around bug with http clone
589 591
590 592
591 593 #if unix-permissions no-root
592 594
593 595 Inaccessible source
594 596
595 597 $ mkdir a
596 598 $ chmod 000 a
597 599 $ hg clone a b
598 600 abort: repository a not found!
599 601 [255]
600 602
601 603 Inaccessible destination
602 604
603 605 $ hg init b
604 606 $ cd b
605 607 $ hg clone . ../a
606 608 abort: Permission denied: '../a'
607 609 [255]
608 610 $ cd ..
609 611 $ chmod 700 a
610 612 $ rm -r a b
611 613
612 614 #endif
613 615
614 616
615 617 #if fifo
616 618
617 619 Source of wrong type
618 620
619 621 $ mkfifo a
620 622 $ hg clone a b
621 623 abort: repository a not found!
622 624 [255]
623 625 $ rm a
624 626
625 627 #endif
626 628
627 629 Default destination, same directory
628 630
629 631 $ hg init q
630 632 $ hg clone q
631 633 destination directory: q
632 634 abort: destination 'q' is not empty
633 635 [255]
634 636
635 637 destination directory not empty
636 638
637 639 $ mkdir a
638 640 $ echo stuff > a/a
639 641 $ hg clone q a
640 642 abort: destination 'a' is not empty
641 643 [255]
642 644
643 645
644 646 #if unix-permissions no-root
645 647
646 648 leave existing directory in place after clone failure
647 649
648 650 $ hg init c
649 651 $ cd c
650 652 $ echo c > c
651 653 $ hg commit -A -m test
652 654 adding c
653 655 $ chmod -rx .hg/store/data
654 656 $ cd ..
655 657 $ mkdir d
656 658 $ hg clone c d 2> err
657 659 [255]
658 660 $ test -d d
659 661 $ test -d d/.hg
660 662 [1]
661 663
662 664 re-enable perm to allow deletion
663 665
664 666 $ chmod +rx c/.hg/store/data
665 667
666 668 #endif
667 669
668 670 $ cd ..
669 671
670 672 Test clone from the repository in (emulated) revlog format 0 (issue4203):
671 673
672 674 $ mkdir issue4203
673 675 $ mkdir -p src/.hg
674 676 $ echo foo > src/foo
675 677 $ hg -R src add src/foo
676 678 $ hg -R src commit -m '#0'
677 679 $ hg -R src log -q
678 680 0:e1bab28bca43
679 681 $ hg clone -U -q src dst
680 682 $ hg -R dst log -q
681 683 0:e1bab28bca43
682 684
683 685 Create repositories to test auto sharing functionality
684 686
685 687 $ cat >> $HGRCPATH << EOF
686 688 > [extensions]
687 689 > share=
688 690 > EOF
689 691
690 692 $ hg init empty
691 693 $ hg init source1a
692 694 $ cd source1a
693 695 $ echo initial1 > foo
694 696 $ hg -q commit -A -m initial
695 697 $ echo second > foo
696 698 $ hg commit -m second
697 699 $ cd ..
698 700
699 701 $ hg init filteredrev0
700 702 $ cd filteredrev0
701 703 $ cat >> .hg/hgrc << EOF
702 704 > [experimental]
703 705 > evolution=createmarkers
704 706 > EOF
705 707 $ echo initial1 > foo
706 708 $ hg -q commit -A -m initial0
707 709 $ hg -q up -r null
708 710 $ echo initial2 > foo
709 711 $ hg -q commit -A -m initial1
710 712 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
711 713 $ cd ..
712 714
713 715 $ hg -q clone --pull source1a source1b
714 716 $ cd source1a
715 717 $ hg bookmark bookA
716 718 $ echo 1a > foo
717 719 $ hg commit -m 1a
718 720 $ cd ../source1b
719 721 $ hg -q up -r 0
720 722 $ echo head1 > foo
721 723 $ hg commit -m head1
722 724 created new head
723 725 $ hg bookmark head1
724 726 $ hg -q up -r 0
725 727 $ echo head2 > foo
726 728 $ hg commit -m head2
727 729 created new head
728 730 $ hg bookmark head2
729 731 $ hg -q up -r 0
730 732 $ hg branch branch1
731 733 marked working directory as branch branch1
732 734 (branches are permanent and global, did you want a bookmark?)
733 735 $ echo branch1 > foo
734 736 $ hg commit -m branch1
735 737 $ hg -q up -r 0
736 738 $ hg branch branch2
737 739 marked working directory as branch branch2
738 740 $ echo branch2 > foo
739 741 $ hg commit -m branch2
740 742 $ cd ..
741 743 $ hg init source2
742 744 $ cd source2
743 745 $ echo initial2 > foo
744 746 $ hg -q commit -A -m initial2
745 747 $ echo second > foo
746 748 $ hg commit -m second
747 749 $ cd ..
748 750
749 751 Clone with auto share from an empty repo should not result in share
750 752
751 753 $ mkdir share
752 754 $ hg --config share.pool=share clone empty share-empty
753 755 (not using pooled storage: remote appears to be empty)
754 756 updating to branch default
755 757 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
756 758 $ ls share
757 759 $ test -d share-empty/.hg/store
758 760 $ test -f share-empty/.hg/sharedpath
759 761 [1]
760 762
761 763 Clone with auto share from a repo with filtered revision 0 should not result in share
762 764
763 765 $ hg --config share.pool=share clone filteredrev0 share-filtered
764 766 (not using pooled storage: unable to resolve identity of remote)
765 767 requesting all changes
766 768 adding changesets
767 769 adding manifests
768 770 adding file changes
769 771 added 1 changesets with 1 changes to 1 files
770 772 updating to branch default
771 773 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
772 774
773 775 Clone from repo with content should result in shared store being created
774 776
775 777 $ hg --config share.pool=share clone source1a share-dest1a
776 778 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
777 779 requesting all changes
778 780 adding changesets
779 781 adding manifests
780 782 adding file changes
781 783 added 3 changesets with 3 changes to 1 files
782 784 searching for changes
783 785 no changes found
784 786 adding remote bookmark bookA
785 787 updating working directory
786 788 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 789
788 790 The shared repo should have been created
789 791
790 792 $ ls share
791 793 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
792 794
793 795 The destination should point to it
794 796
795 797 $ cat share-dest1a/.hg/sharedpath; echo
796 798 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
797 799
798 800 The destination should have bookmarks
799 801
800 802 $ hg -R share-dest1a bookmarks
801 803 bookA 2:e5bfe23c0b47
802 804
803 805 The default path should be the remote, not the share
804 806
805 807 $ hg -R share-dest1a config paths.default
806 808 $TESTTMP/source1a (glob)
807 809
808 810 Clone with existing share dir should result in pull + share
809 811
810 812 $ hg --config share.pool=share clone source1b share-dest1b
811 813 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
812 814 searching for changes
813 815 adding changesets
814 816 adding manifests
815 817 adding file changes
816 818 added 4 changesets with 4 changes to 1 files (+4 heads)
817 819 adding remote bookmark head1
818 820 adding remote bookmark head2
819 821 updating working directory
820 822 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 823
822 824 $ ls share
823 825 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
824 826
825 827 $ cat share-dest1b/.hg/sharedpath; echo
826 828 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg (glob)
827 829
828 830 We only get bookmarks from the remote, not everything in the share
829 831
830 832 $ hg -R share-dest1b bookmarks
831 833 head1 3:4a8dc1ab4c13
832 834 head2 4:99f71071f117
833 835
834 836 Default path should be source, not share.
835 837
836 838 $ hg -R share-dest1b config paths.default
837 839 $TESTTMP/source1b (glob)
838 840
839 841 Checked out revision should be head of default branch
840 842
841 843 $ hg -R share-dest1b log -r .
842 844 changeset: 4:99f71071f117
843 845 bookmark: head2
844 846 parent: 0:b5f04eac9d8f
845 847 user: test
846 848 date: Thu Jan 01 00:00:00 1970 +0000
847 849 summary: head2
848 850
849 851
850 852 Clone from unrelated repo should result in new share
851 853
852 854 $ hg --config share.pool=share clone source2 share-dest2
853 855 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
854 856 requesting all changes
855 857 adding changesets
856 858 adding manifests
857 859 adding file changes
858 860 added 2 changesets with 2 changes to 1 files
859 861 searching for changes
860 862 no changes found
861 863 updating working directory
862 864 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 865
864 866 $ ls share
865 867 22aeff664783fd44c6d9b435618173c118c3448e
866 868 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
867 869
868 870 remote naming mode works as advertised
869 871
870 872 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
871 873 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
872 874 requesting all changes
873 875 adding changesets
874 876 adding manifests
875 877 adding file changes
876 878 added 3 changesets with 3 changes to 1 files
877 879 searching for changes
878 880 no changes found
879 881 adding remote bookmark bookA
880 882 updating working directory
881 883 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 884
883 885 $ ls shareremote
884 886 195bb1fcdb595c14a6c13e0269129ed78f6debde
885 887
886 888 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
887 889 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
888 890 requesting all changes
889 891 adding changesets
890 892 adding manifests
891 893 adding file changes
892 894 added 6 changesets with 6 changes to 1 files (+4 heads)
893 895 searching for changes
894 896 no changes found
895 897 adding remote bookmark head1
896 898 adding remote bookmark head2
897 899 updating working directory
898 900 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
899 901
900 902 $ ls shareremote
901 903 195bb1fcdb595c14a6c13e0269129ed78f6debde
902 904 c0d4f83847ca2a873741feb7048a45085fd47c46
903 905
904 906 request to clone a single revision is respected in sharing mode
905 907
906 908 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
907 909 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
908 910 adding changesets
909 911 adding manifests
910 912 adding file changes
911 913 added 2 changesets with 2 changes to 1 files
912 914 no changes found
913 915 adding remote bookmark head1
914 916 updating working directory
915 917 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
916 918
917 919 $ hg -R share-1arev log -G
918 920 @ changeset: 1:4a8dc1ab4c13
919 921 | bookmark: head1
920 922 | tag: tip
921 923 | user: test
922 924 | date: Thu Jan 01 00:00:00 1970 +0000
923 925 | summary: head1
924 926 |
925 927 o changeset: 0:b5f04eac9d8f
926 928 user: test
927 929 date: Thu Jan 01 00:00:00 1970 +0000
928 930 summary: initial
929 931
930 932
931 933 making another clone should only pull down requested rev
932 934
933 935 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
934 936 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
935 937 searching for changes
936 938 adding changesets
937 939 adding manifests
938 940 adding file changes
939 941 added 1 changesets with 1 changes to 1 files (+1 heads)
940 942 adding remote bookmark head1
941 943 adding remote bookmark head2
942 944 updating working directory
943 945 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
944 946
945 947 $ hg -R share-1brev log -G
946 948 @ changeset: 2:99f71071f117
947 949 | bookmark: head2
948 950 | tag: tip
949 951 | parent: 0:b5f04eac9d8f
950 952 | user: test
951 953 | date: Thu Jan 01 00:00:00 1970 +0000
952 954 | summary: head2
953 955 |
954 956 | o changeset: 1:4a8dc1ab4c13
955 957 |/ bookmark: head1
956 958 | user: test
957 959 | date: Thu Jan 01 00:00:00 1970 +0000
958 960 | summary: head1
959 961 |
960 962 o changeset: 0:b5f04eac9d8f
961 963 user: test
962 964 date: Thu Jan 01 00:00:00 1970 +0000
963 965 summary: initial
964 966
965 967
966 968 Request to clone a single branch is respected in sharing mode
967 969
968 970 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
969 971 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
970 972 adding changesets
971 973 adding manifests
972 974 adding file changes
973 975 added 2 changesets with 2 changes to 1 files
974 976 no changes found
975 977 updating working directory
976 978 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
977 979
978 980 $ hg -R share-1bbranch1 log -G
979 981 o changeset: 1:5f92a6c1a1b1
980 982 | branch: branch1
981 983 | tag: tip
982 984 | user: test
983 985 | date: Thu Jan 01 00:00:00 1970 +0000
984 986 | summary: branch1
985 987 |
986 988 @ changeset: 0:b5f04eac9d8f
987 989 user: test
988 990 date: Thu Jan 01 00:00:00 1970 +0000
989 991 summary: initial
990 992
991 993
992 994 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
993 995 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
994 996 searching for changes
995 997 adding changesets
996 998 adding manifests
997 999 adding file changes
998 1000 added 1 changesets with 1 changes to 1 files (+1 heads)
999 1001 updating working directory
1000 1002 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1001 1003
1002 1004 $ hg -R share-1bbranch2 log -G
1003 1005 o changeset: 2:6bacf4683960
1004 1006 | branch: branch2
1005 1007 | tag: tip
1006 1008 | parent: 0:b5f04eac9d8f
1007 1009 | user: test
1008 1010 | date: Thu Jan 01 00:00:00 1970 +0000
1009 1011 | summary: branch2
1010 1012 |
1011 1013 | o changeset: 1:5f92a6c1a1b1
1012 1014 |/ branch: branch1
1013 1015 | user: test
1014 1016 | date: Thu Jan 01 00:00:00 1970 +0000
1015 1017 | summary: branch1
1016 1018 |
1017 1019 @ changeset: 0:b5f04eac9d8f
1018 1020 user: test
1019 1021 date: Thu Jan 01 00:00:00 1970 +0000
1020 1022 summary: initial
1021 1023
1022 1024
1023 1025 -U is respected in share clone mode
1024 1026
1025 1027 $ hg --config share.pool=share clone -U source1a share-1anowc
1026 1028 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1027 1029 searching for changes
1028 1030 no changes found
1029 1031 adding remote bookmark bookA
1030 1032
1031 1033 $ ls share-1anowc
1032 1034
1033 1035 Test that auto sharing doesn't cause failure of "hg clone local remote"
1034 1036
1035 1037 $ cd $TESTTMP
1036 1038 $ hg -R a id -r 0
1037 1039 acb14030fe0a
1038 1040 $ hg id -R remote -r 0
1039 1041 abort: repository remote not found!
1040 1042 [255]
1041 1043 $ hg --config share.pool=share -q clone -e "python \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1042 1044 $ hg -R remote id -r 0
1043 1045 acb14030fe0a
1044 1046
1045 1047 Cloning into pooled storage doesn't race (issue5104)
1046 1048
1047 1049 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1048 1050 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1049 1051 $ wait
1050 1052
1051 1053 $ hg -R share-destrace1 log -r tip
1052 1054 changeset: 2:e5bfe23c0b47
1053 1055 bookmark: bookA
1054 1056 tag: tip
1055 1057 user: test
1056 1058 date: Thu Jan 01 00:00:00 1970 +0000
1057 1059 summary: 1a
1058 1060
1059 1061
1060 1062 $ hg -R share-destrace2 log -r tip
1061 1063 changeset: 2:e5bfe23c0b47
1062 1064 bookmark: bookA
1063 1065 tag: tip
1064 1066 user: test
1065 1067 date: Thu Jan 01 00:00:00 1970 +0000
1066 1068 summary: 1a
1067 1069
1068 1070 One repo should be new, the other should be shared from the pool. We
1069 1071 don't care which is which, so we just make sure we always print the
1070 1072 one containing "new pooled" first, then one one containing "existing
1071 1073 pooled".
1072 1074
1073 1075 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1074 1076 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1075 1077 requesting all changes
1076 1078 adding changesets
1077 1079 adding manifests
1078 1080 adding file changes
1079 1081 added 3 changesets with 3 changes to 1 files
1080 1082 searching for changes
1081 1083 no changes found
1082 1084 adding remote bookmark bookA
1083 1085 updating working directory
1084 1086 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1085 1087
1086 1088 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1087 1089 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1088 1090 searching for changes
1089 1091 no changes found
1090 1092 adding remote bookmark bookA
1091 1093 updating working directory
1092 1094 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,380 +1,383
1 1 #require hardlink
2 2
3 3 $ cat > nlinks.py <<EOF
4 4 > import sys
5 5 > from mercurial import util
6 6 > for f in sorted(sys.stdin.readlines()):
7 7 > f = f[:-1]
8 8 > print util.nlinks(f), f
9 9 > EOF
10 10
11 11 $ nlinksdir()
12 12 > {
13 13 > find $1 -type f | python $TESTTMP/nlinks.py
14 14 > }
15 15
16 16 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
17 17
18 18 $ cat > linkcp.py <<EOF
19 19 > from mercurial import util
20 20 > import sys
21 21 > util.copyfiles(sys.argv[1], sys.argv[2], hardlink=True)
22 22 > EOF
23 23
24 24 $ linkcp()
25 25 > {
26 26 > python $TESTTMP/linkcp.py $1 $2
27 27 > }
28 28
29 29 Prepare repo r1:
30 30
31 31 $ hg init r1
32 32 $ cd r1
33 33
34 34 $ echo c1 > f1
35 35 $ hg add f1
36 36 $ hg ci -m0
37 37
38 38 $ mkdir d1
39 39 $ cd d1
40 40 $ echo c2 > f2
41 41 $ hg add f2
42 42 $ hg ci -m1
43 43 $ cd ../..
44 44
45 45 $ nlinksdir r1/.hg/store
46 46 1 r1/.hg/store/00changelog.i
47 47 1 r1/.hg/store/00manifest.i
48 48 1 r1/.hg/store/data/d1/f2.i
49 49 1 r1/.hg/store/data/f1.i
50 50 1 r1/.hg/store/fncache
51 51 1 r1/.hg/store/phaseroots
52 52 1 r1/.hg/store/undo
53 53 1 r1/.hg/store/undo.backup.fncache
54 54 1 r1/.hg/store/undo.backupfiles
55 55 1 r1/.hg/store/undo.phaseroots
56 56
57 57
58 58 Create hardlinked clone r2:
59 59
60 60 $ hg clone -U --debug r1 r2 --config progress.debug=true
61 61 linking: 1
62 62 linking: 2
63 63 linking: 3
64 64 linking: 4
65 65 linking: 5
66 66 linking: 6
67 67 linking: 7
68 68 linked 7 files
69 69
70 70 Create non-hardlinked clone r3:
71 71
72 72 $ hg clone --pull r1 r3
73 73 requesting all changes
74 74 adding changesets
75 75 adding manifests
76 76 adding file changes
77 77 added 2 changesets with 2 changes to 2 files
78 78 updating to branch default
79 79 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 80
81 81
82 82 Repos r1 and r2 should now contain hardlinked files:
83 83
84 84 $ nlinksdir r1/.hg/store
85 85 2 r1/.hg/store/00changelog.i
86 86 2 r1/.hg/store/00manifest.i
87 87 2 r1/.hg/store/data/d1/f2.i
88 88 2 r1/.hg/store/data/f1.i
89 89 2 r1/.hg/store/fncache
90 90 1 r1/.hg/store/phaseroots
91 91 1 r1/.hg/store/undo
92 92 1 r1/.hg/store/undo.backup.fncache
93 93 1 r1/.hg/store/undo.backupfiles
94 94 1 r1/.hg/store/undo.phaseroots
95 95
96 96 $ nlinksdir r2/.hg/store
97 97 2 r2/.hg/store/00changelog.i
98 98 2 r2/.hg/store/00manifest.i
99 99 2 r2/.hg/store/data/d1/f2.i
100 100 2 r2/.hg/store/data/f1.i
101 101 2 r2/.hg/store/fncache
102 102
103 103 Repo r3 should not be hardlinked:
104 104
105 105 $ nlinksdir r3/.hg/store
106 106 1 r3/.hg/store/00changelog.i
107 107 1 r3/.hg/store/00manifest.i
108 108 1 r3/.hg/store/data/d1/f2.i
109 109 1 r3/.hg/store/data/f1.i
110 110 1 r3/.hg/store/fncache
111 111 1 r3/.hg/store/phaseroots
112 112 1 r3/.hg/store/undo
113 113 1 r3/.hg/store/undo.backupfiles
114 114 1 r3/.hg/store/undo.phaseroots
115 115
116 116
117 117 Create a non-inlined filelog in r3:
118 118
119 119 $ cd r3/d1
120 120 >>> f = open('data1', 'wb')
121 121 >>> for x in range(10000):
122 122 ... f.write("%s\n" % str(x))
123 123 >>> f.close()
124 124 $ for j in 0 1 2 3 4 5 6 7 8 9; do
125 125 > cat data1 >> f2
126 126 > hg commit -m$j
127 127 > done
128 128 $ cd ../..
129 129
130 130 $ nlinksdir r3/.hg/store
131 131 1 r3/.hg/store/00changelog.i
132 132 1 r3/.hg/store/00manifest.i
133 133 1 r3/.hg/store/data/d1/f2.d
134 134 1 r3/.hg/store/data/d1/f2.i
135 135 1 r3/.hg/store/data/f1.i
136 136 1 r3/.hg/store/fncache
137 137 1 r3/.hg/store/phaseroots
138 138 1 r3/.hg/store/undo
139 139 1 r3/.hg/store/undo.backup.fncache
140 140 1 r3/.hg/store/undo.backup.phaseroots
141 141 1 r3/.hg/store/undo.backupfiles
142 142 1 r3/.hg/store/undo.phaseroots
143 143
144 144 Push to repo r1 should break up most hardlinks in r2:
145 145
146 146 $ hg -R r2 verify
147 147 checking changesets
148 148 checking manifests
149 149 crosschecking files in changesets and manifests
150 150 checking files
151 151 2 files, 2 changesets, 2 total revisions
152 152
153 153 $ cd r3
154 154 $ hg push
155 155 pushing to $TESTTMP/r1 (glob)
156 156 searching for changes
157 157 adding changesets
158 158 adding manifests
159 159 adding file changes
160 160 added 10 changesets with 10 changes to 1 files
161 161
162 162 $ cd ..
163 163
164 164 $ nlinksdir r2/.hg/store
165 165 1 r2/.hg/store/00changelog.i
166 166 1 r2/.hg/store/00manifest.i
167 167 1 r2/.hg/store/data/d1/f2.i
168 168 2 r2/.hg/store/data/f1.i
169 169 1 r2/.hg/store/fncache
170 170
171 171 $ hg -R r2 verify
172 172 checking changesets
173 173 checking manifests
174 174 crosschecking files in changesets and manifests
175 175 checking files
176 176 2 files, 2 changesets, 2 total revisions
177 177
178 178
179 179 $ cd r1
180 180 $ hg up
181 181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 182
183 183 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
184 184
185 185 $ echo c1c1 >> f1
186 186 $ hg ci -m00
187 187 $ cd ..
188 188
189 189 $ nlinksdir r2/.hg/store
190 190 1 r2/.hg/store/00changelog.i
191 191 1 r2/.hg/store/00manifest.i
192 192 1 r2/.hg/store/data/d1/f2.i
193 193 1 r2/.hg/store/data/f1.i
194 194 1 r2/.hg/store/fncache
195 195
196 196
197 197 $ cd r3
198 198 $ hg tip --template '{rev}:{node|short}\n'
199 199 11:a6451b6bc41f
200 200 $ echo bla > f1
201 201 $ hg ci -m1
202 202 $ cd ..
203 203
204 204 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
205 205
206 206 $ linkcp r3 r4
207 207
208 208 r4 has hardlinks in the working dir (not just inside .hg):
209 209
210 210 $ nlinksdir r4
211 211 2 r4/.hg/00changelog.i
212 212 2 r4/.hg/branch
213 213 2 r4/.hg/cache/branch2-served
214 214 2 r4/.hg/cache/checkisexec
215 3 r4/.hg/cache/checklink (?)
216 ? r4/.hg/cache/checklink-target (glob)
215 217 2 r4/.hg/cache/checknoexec
216 218 2 r4/.hg/cache/rbc-names-v1
217 219 2 r4/.hg/cache/rbc-revs-v1
218 220 2 r4/.hg/dirstate
219 221 2 r4/.hg/hgrc
220 222 2 r4/.hg/last-message.txt
221 223 2 r4/.hg/requires
222 224 2 r4/.hg/store/00changelog.i
223 225 2 r4/.hg/store/00manifest.i
224 226 2 r4/.hg/store/data/d1/f2.d
225 227 2 r4/.hg/store/data/d1/f2.i
226 228 2 r4/.hg/store/data/f1.i
227 229 2 r4/.hg/store/fncache
228 230 2 r4/.hg/store/phaseroots
229 231 2 r4/.hg/store/undo
230 232 2 r4/.hg/store/undo.backup.fncache
231 233 2 r4/.hg/store/undo.backup.phaseroots
232 234 2 r4/.hg/store/undo.backupfiles
233 235 2 r4/.hg/store/undo.phaseroots
234 236 2 r4/.hg/undo.backup.dirstate
235 237 2 r4/.hg/undo.bookmarks
236 238 2 r4/.hg/undo.branch
237 239 2 r4/.hg/undo.desc
238 240 2 r4/.hg/undo.dirstate
239 241 2 r4/d1/data1
240 242 2 r4/d1/f2
241 243 2 r4/f1
242 244
243 245 Update back to revision 11 in r4 should break hardlink of file f1:
244 246
245 247 $ hg -R r4 up 11
246 248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 249
248 250 $ nlinksdir r4
249 251 2 r4/.hg/00changelog.i
250 252 1 r4/.hg/branch
251 253 2 r4/.hg/cache/branch2-served
252 254 2 r4/.hg/cache/checkisexec
255 2 r4/.hg/cache/checklink-target
253 256 2 r4/.hg/cache/checknoexec
254 257 2 r4/.hg/cache/rbc-names-v1
255 258 2 r4/.hg/cache/rbc-revs-v1
256 259 1 r4/.hg/dirstate
257 260 2 r4/.hg/hgrc
258 261 2 r4/.hg/last-message.txt
259 262 2 r4/.hg/requires
260 263 2 r4/.hg/store/00changelog.i
261 264 2 r4/.hg/store/00manifest.i
262 265 2 r4/.hg/store/data/d1/f2.d
263 266 2 r4/.hg/store/data/d1/f2.i
264 267 2 r4/.hg/store/data/f1.i
265 268 2 r4/.hg/store/fncache
266 269 2 r4/.hg/store/phaseroots
267 270 2 r4/.hg/store/undo
268 271 2 r4/.hg/store/undo.backup.fncache
269 272 2 r4/.hg/store/undo.backup.phaseroots
270 273 2 r4/.hg/store/undo.backupfiles
271 274 2 r4/.hg/store/undo.phaseroots
272 275 2 r4/.hg/undo.backup.dirstate
273 276 2 r4/.hg/undo.bookmarks
274 277 2 r4/.hg/undo.branch
275 278 2 r4/.hg/undo.desc
276 279 2 r4/.hg/undo.dirstate
277 280 2 r4/d1/data1
278 281 2 r4/d1/f2
279 282 1 r4/f1
280 283
281 284
282 285 Test hardlinking outside hg:
283 286
284 287 $ mkdir x
285 288 $ echo foo > x/a
286 289
287 290 $ linkcp x y
288 291 $ echo bar >> y/a
289 292
290 293 No diff if hardlink:
291 294
292 295 $ diff x/a y/a
293 296
294 297 Test mq hardlinking:
295 298
296 299 $ echo "[extensions]" >> $HGRCPATH
297 300 $ echo "mq=" >> $HGRCPATH
298 301
299 302 $ hg init a
300 303 $ cd a
301 304
302 305 $ hg qimport -n foo - << EOF
303 306 > # HG changeset patch
304 307 > # Date 1 0
305 308 > diff -r 2588a8b53d66 a
306 309 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
307 310 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
308 311 > @@ -0,0 +1,1 @@
309 312 > +a
310 313 > EOF
311 314 adding foo to series file
312 315
313 316 $ hg qpush
314 317 applying foo
315 318 now at: foo
316 319
317 320 $ cd ..
318 321 $ linkcp a b
319 322 $ cd b
320 323
321 324 $ hg qimport -n bar - << EOF
322 325 > # HG changeset patch
323 326 > # Date 2 0
324 327 > diff -r 2588a8b53d66 a
325 328 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
326 329 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
327 330 > @@ -0,0 +1,1 @@
328 331 > +b
329 332 > EOF
330 333 adding bar to series file
331 334
332 335 $ hg qpush
333 336 applying bar
334 337 now at: bar
335 338
336 339 $ cat .hg/patches/status
337 340 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
338 341 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
339 342
340 343 $ cat .hg/patches/series
341 344 foo
342 345 bar
343 346
344 347 $ cat ../a/.hg/patches/status
345 348 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
346 349
347 350 $ cat ../a/.hg/patches/series
348 351 foo
349 352
350 353 Test tags hardlinking:
351 354
352 355 $ hg qdel -r qbase:qtip
353 356 patch foo finalized without changeset message
354 357 patch bar finalized without changeset message
355 358
356 359 $ hg tag -l lfoo
357 360 $ hg tag foo
358 361
359 362 $ cd ..
360 363 $ linkcp b c
361 364 $ cd c
362 365
363 366 $ hg tag -l -r 0 lbar
364 367 $ hg tag -r 0 bar
365 368
366 369 $ cat .hgtags
367 370 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
368 371 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
369 372
370 373 $ cat .hg/localtags
371 374 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
372 375 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
373 376
374 377 $ cat ../b/.hgtags
375 378 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
376 379
377 380 $ cat ../b/.hg/localtags
378 381 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
379 382
380 383 $ cd ..
@@ -1,716 +1,718
1 1 setup
2 2
3 3 $ cat >> $HGRCPATH << EOF
4 4 > [extensions]
5 5 > blackbox=
6 6 > mock=$TESTDIR/mockblackbox.py
7 7 > EOF
8 8
9 9 Helper functions:
10 10
11 11 $ cacheexists() {
12 12 > [ -f .hg/cache/tags2-visible ] && echo "tag cache exists" || echo "no tag cache"
13 13 > }
14 14
15 15 $ fnodescacheexists() {
16 16 > [ -f .hg/cache/hgtagsfnodes1 ] && echo "fnodes cache exists" || echo "no fnodes cache"
17 17 > }
18 18
19 19 $ dumptags() {
20 20 > rev=$1
21 21 > echo "rev $rev: .hgtags:"
22 22 > hg cat -r$rev .hgtags
23 23 > }
24 24
25 25 # XXX need to test that the tag cache works when we strip an old head
26 26 # and add a new one rooted off non-tip: i.e. node and rev of tip are the
27 27 # same, but stuff has changed behind tip.
28 28
29 29 Setup:
30 30
31 31 $ hg init t
32 32 $ cd t
33 33 $ cacheexists
34 34 no tag cache
35 35 $ fnodescacheexists
36 36 no fnodes cache
37 37 $ hg id
38 38 000000000000 tip
39 39 $ cacheexists
40 40 no tag cache
41 41 $ fnodescacheexists
42 42 no fnodes cache
43 43 $ echo a > a
44 44 $ hg add a
45 45 $ hg commit -m "test"
46 46 $ hg co
47 47 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 48 $ hg identify
49 49 acb14030fe0a tip
50 50 $ hg identify -r 'wdir()'
51 51 acb14030fe0a tip
52 52 $ cacheexists
53 53 tag cache exists
54 54 No fnodes cache because .hgtags file doesn't exist
55 55 (this is an implementation detail)
56 56 $ fnodescacheexists
57 57 no fnodes cache
58 58
59 59 Try corrupting the cache
60 60
61 61 $ printf 'a b' > .hg/cache/tags2-visible
62 62 $ hg identify
63 63 acb14030fe0a tip
64 64 $ cacheexists
65 65 tag cache exists
66 66 $ fnodescacheexists
67 67 no fnodes cache
68 68 $ hg identify
69 69 acb14030fe0a tip
70 70
71 71 Create local tag with long name:
72 72
73 73 $ T=`hg identify --debug --id`
74 74 $ hg tag -l "This is a local tag with a really long name!"
75 75 $ hg tags
76 76 tip 0:acb14030fe0a
77 77 This is a local tag with a really long name! 0:acb14030fe0a
78 78 $ rm .hg/localtags
79 79
80 80 Create a tag behind hg's back:
81 81
82 82 $ echo "$T first" > .hgtags
83 83 $ cat .hgtags
84 84 acb14030fe0a21b60322c440ad2d20cf7685a376 first
85 85 $ hg add .hgtags
86 86 $ hg commit -m "add tags"
87 87 $ hg tags
88 88 tip 1:b9154636be93
89 89 first 0:acb14030fe0a
90 90 $ hg identify
91 91 b9154636be93 tip
92 92
93 93 We should have a fnodes cache now that we have a real tag
94 94 The cache should have an empty entry for rev 0 and a valid entry for rev 1.
95 95
96 96
97 97 $ fnodescacheexists
98 98 fnodes cache exists
99 99 $ f --size --hexdump .hg/cache/hgtagsfnodes1
100 100 .hg/cache/hgtagsfnodes1: size=48
101 101 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
102 102 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
103 103 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
104 104
105 105 Repeat with cold tag cache:
106 106
107 107 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
108 108 $ hg identify
109 109 b9154636be93 tip
110 110
111 111 $ fnodescacheexists
112 112 fnodes cache exists
113 113 $ f --size --hexdump .hg/cache/hgtagsfnodes1
114 114 .hg/cache/hgtagsfnodes1: size=48
115 115 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
116 116 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
117 117 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
118 118
119 119 And again, but now unable to write tag cache or lock file:
120 120
121 121 #if unix-permissions
122 122 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
123 123 $ chmod 555 .hg/cache
124 124 $ hg identify
125 125 b9154636be93 tip
126 126 $ chmod 755 .hg/cache
127 127
128 128 $ chmod 555 .hg
129 129 $ hg identify
130 130 b9154636be93 tip
131 131 $ chmod 755 .hg
132 132 #endif
133 133
134 134 Tag cache debug info written to blackbox log
135 135
136 136 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
137 137 $ hg identify
138 138 b9154636be93 tip
139 139 $ hg blackbox -l 6
140 140 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
141 141 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing 48 bytes to cache/hgtagsfnodes1
142 142 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/1 cache hits/lookups in * seconds (glob)
143 143 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
144 144 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
145 145 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
146 146
147 147 Failure to acquire lock results in no write
148 148
149 149 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
150 150 $ echo 'foo:1' > .hg/wlock
151 151 $ hg identify
152 152 b9154636be93 tip
153 153 $ hg blackbox -l 6
154 154 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
155 155 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> not writing .hg/cache/hgtagsfnodes1 because lock cannot be acquired
156 156 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/1 cache hits/lookups in * seconds (glob)
157 157 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
158 158 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
159 159 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
160 160
161 161 $ fnodescacheexists
162 162 no fnodes cache
163 163
164 164 $ rm .hg/wlock
165 165
166 166 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
167 167 $ hg identify
168 168 b9154636be93 tip
169 169
170 170 Create a branch:
171 171
172 172 $ echo bb > a
173 173 $ hg status
174 174 M a
175 175 $ hg identify
176 176 b9154636be93+ tip
177 177 $ hg co first
178 178 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
179 179 $ hg id
180 180 acb14030fe0a+ first
181 181 $ hg id -r 'wdir()'
182 182 acb14030fe0a+ first
183 183 $ hg -v id
184 184 acb14030fe0a+ first
185 185 $ hg status
186 186 M a
187 187 $ echo 1 > b
188 188 $ hg add b
189 189 $ hg commit -m "branch"
190 190 created new head
191 191
192 192 Creating a new commit shouldn't append the .hgtags fnodes cache until
193 193 tags info is accessed
194 194
195 195 $ f --size --hexdump .hg/cache/hgtagsfnodes1
196 196 .hg/cache/hgtagsfnodes1: size=48
197 197 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
198 198 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
199 199 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
200 200
201 201 $ hg id
202 202 c8edf04160c7 tip
203 203
204 204 First 4 bytes of record 3 are changeset fragment
205 205
206 206 $ f --size --hexdump .hg/cache/hgtagsfnodes1
207 207 .hg/cache/hgtagsfnodes1: size=72
208 208 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
209 209 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
210 210 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
211 211 0030: c8 ed f0 41 00 00 00 00 00 00 00 00 00 00 00 00 |...A............|
212 212 0040: 00 00 00 00 00 00 00 00 |........|
213 213
214 214 Merge the two heads:
215 215
216 216 $ hg merge 1
217 217 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 218 (branch merge, don't forget to commit)
219 219 $ hg blackbox -l3
220 220 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28 (5000)> merge 1
221 221 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> merge 1 exited 0 after * seconds (glob)
222 222 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l3
223 223 $ hg id
224 224 c8edf04160c7+b9154636be93+ tip
225 225 $ hg status
226 226 M .hgtags
227 227 $ hg commit -m "merge"
228 228
229 229 Create a fake head, make sure tag not visible afterwards:
230 230
231 231 $ cp .hgtags tags
232 232 $ hg tag last
233 233 $ hg rm .hgtags
234 234 $ hg commit -m "remove"
235 235
236 236 $ mv tags .hgtags
237 237 $ hg add .hgtags
238 238 $ hg commit -m "readd"
239 239 $
240 240 $ hg tags
241 241 tip 6:35ff301afafe
242 242 first 0:acb14030fe0a
243 243
244 244 Add invalid tags:
245 245
246 246 $ echo "spam" >> .hgtags
247 247 $ echo >> .hgtags
248 248 $ echo "foo bar" >> .hgtags
249 249 $ echo "a5a5 invalid" >> .hg/localtags
250 250 $ cat .hgtags
251 251 acb14030fe0a21b60322c440ad2d20cf7685a376 first
252 252 spam
253 253
254 254 foo bar
255 255 $ hg commit -m "tags"
256 256
257 257 Report tag parse error on other head:
258 258
259 259 $ hg up 3
260 260 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
261 261 $ echo 'x y' >> .hgtags
262 262 $ hg commit -m "head"
263 263 created new head
264 264
265 265 $ hg tags --debug
266 266 .hgtags@75d9f02dfe28, line 2: cannot parse entry
267 267 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
268 268 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
269 269 tip 8:c4be69a18c11e8bc3a5fdbb576017c25f7d84663
270 270 first 0:acb14030fe0a21b60322c440ad2d20cf7685a376
271 271 $ hg tip
272 272 changeset: 8:c4be69a18c11
273 273 tag: tip
274 274 parent: 3:ac5e980c4dc0
275 275 user: test
276 276 date: Thu Jan 01 00:00:00 1970 +0000
277 277 summary: head
278 278
279 279
280 280 Test tag precedence rules:
281 281
282 282 $ cd ..
283 283 $ hg init t2
284 284 $ cd t2
285 285 $ echo foo > foo
286 286 $ hg add foo
287 287 $ hg ci -m 'add foo' # rev 0
288 288 $ hg tag bar # rev 1
289 289 $ echo >> foo
290 290 $ hg ci -m 'change foo 1' # rev 2
291 291 $ hg up -C 1
292 292 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 293 $ hg tag -r 1 -f bar # rev 3
294 294 $ hg up -C 1
295 295 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 296 $ echo >> foo
297 297 $ hg ci -m 'change foo 2' # rev 4
298 298 created new head
299 299 $ hg tags
300 300 tip 4:0c192d7d5e6b
301 301 bar 1:78391a272241
302 302
303 303 Repeat in case of cache effects:
304 304
305 305 $ hg tags
306 306 tip 4:0c192d7d5e6b
307 307 bar 1:78391a272241
308 308
309 309 Detailed dump of tag info:
310 310
311 311 $ hg heads -q # expect 4, 3, 2
312 312 4:0c192d7d5e6b
313 313 3:6fa450212aeb
314 314 2:7a94127795a3
315 315 $ dumptags 2
316 316 rev 2: .hgtags:
317 317 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
318 318 $ dumptags 3
319 319 rev 3: .hgtags:
320 320 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
321 321 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
322 322 78391a272241d70354aa14c874552cad6b51bb42 bar
323 323 $ dumptags 4
324 324 rev 4: .hgtags:
325 325 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
326 326
327 327 Dump cache:
328 328
329 329 $ cat .hg/cache/tags2-visible
330 330 4 0c192d7d5e6b78a714de54a2e9627952a877e25a
331 331 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
332 332 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
333 333 78391a272241d70354aa14c874552cad6b51bb42 bar
334 334
335 335 $ f --size --hexdump .hg/cache/hgtagsfnodes1
336 336 .hg/cache/hgtagsfnodes1: size=120
337 337 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
338 338 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
339 339 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
340 340 0030: 7a 94 12 77 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |z..w.....1....B(|
341 341 0040: 78 ee 5a 2d ad bc 94 3d 6f a4 50 21 7d 3b 71 8c |x.Z-...=o.P!};q.|
342 342 0050: 96 4e f3 7b 89 e5 50 eb da fd 57 89 e7 6c e1 b0 |.N.{..P...W..l..|
343 343 0060: 0c 19 2d 7d 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |..-}.....1....B(|
344 344 0070: 78 ee 5a 2d ad bc 94 3d |x.Z-...=|
345 345
346 346 Corrupt the .hgtags fnodes cache
347 347 Extra junk data at the end should get overwritten on next cache update
348 348
349 349 $ echo extra >> .hg/cache/hgtagsfnodes1
350 350 $ echo dummy1 > foo
351 351 $ hg commit -m throwaway1
352 352
353 353 $ hg tags
354 354 tip 5:8dbfe60eff30
355 355 bar 1:78391a272241
356 356
357 357 $ hg blackbox -l 6
358 358 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags
359 359 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing 24 bytes to cache/hgtagsfnodes1
360 360 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> 2/3 cache hits/lookups in * seconds (glob)
361 361 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing .hg/cache/tags2-visible with 1 tags
362 362 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags exited 0 after * seconds (glob)
363 363 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> blackbox -l 6
364 364
365 365 #if unix-permissions no-root
366 366 Errors writing to .hgtags fnodes cache are silently ignored
367 367
368 368 $ echo dummy2 > foo
369 369 $ hg commit -m throwaway2
370 370
371 371 $ chmod a-w .hg/cache/hgtagsfnodes1
372 372 $ rm -f .hg/cache/tags2-visible
373 373
374 374 $ hg tags
375 375 tip 6:b968051b5cf3
376 376 bar 1:78391a272241
377 377
378 378 $ hg blackbox -l 6
379 379 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
380 380 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno 13] Permission denied: '$TESTTMP/t2/.hg/cache/hgtagsfnodes1'
381 381 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 2/3 cache hits/lookups in * seconds (glob)
382 382 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
383 383 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
384 384 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
385 385
386 386 $ chmod a+w .hg/cache/hgtagsfnodes1
387 387
388 388 $ rm -f .hg/cache/tags2-visible
389 389 $ hg tags
390 390 tip 6:b968051b5cf3
391 391 bar 1:78391a272241
392 392
393 393 $ hg blackbox -l 6
394 394 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
395 395 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing 24 bytes to cache/hgtagsfnodes1
396 396 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 2/3 cache hits/lookups in * seconds (glob)
397 397 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
398 398 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
399 399 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
400 400
401 401 $ f --size .hg/cache/hgtagsfnodes1
402 402 .hg/cache/hgtagsfnodes1: size=168
403 403
404 404 $ hg -q --config extensions.strip= strip -r 6 --no-backup
405 405 #endif
406 406
407 407 Stripping doesn't truncate the tags cache until new data is available
408 408
409 409 $ rm -f .hg/cache/hgtagsfnodes1 .hg/cache/tags2-visible
410 410 $ hg tags
411 411 tip 5:8dbfe60eff30
412 412 bar 1:78391a272241
413 413
414 414 $ f --size .hg/cache/hgtagsfnodes1
415 415 .hg/cache/hgtagsfnodes1: size=144
416 416
417 417 $ hg -q --config extensions.strip= strip -r 5 --no-backup
418 418 $ hg tags
419 419 tip 4:0c192d7d5e6b
420 420 bar 1:78391a272241
421 421
422 422 $ hg blackbox -l 5
423 423 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing 24 bytes to cache/hgtagsfnodes1
424 424 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> 2/3 cache hits/lookups in * seconds (glob)
425 425 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing .hg/cache/tags2-visible with 1 tags
426 426 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> tags exited 0 after * seconds (glob)
427 427 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> blackbox -l 5
428 428
429 429 $ f --size .hg/cache/hgtagsfnodes1
430 430 .hg/cache/hgtagsfnodes1: size=120
431 431
432 432 $ echo dummy > foo
433 433 $ hg commit -m throwaway3
434 434
435 435 $ hg tags
436 436 tip 5:035f65efb448
437 437 bar 1:78391a272241
438 438
439 439 $ hg blackbox -l 6
440 440 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags
441 441 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing 24 bytes to cache/hgtagsfnodes1
442 442 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> 2/3 cache hits/lookups in * seconds (glob)
443 443 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing .hg/cache/tags2-visible with 1 tags
444 444 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags exited 0 after * seconds (glob)
445 445 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> blackbox -l 6
446 446 $ f --size .hg/cache/hgtagsfnodes1
447 447 .hg/cache/hgtagsfnodes1: size=144
448 448
449 449 $ hg -q --config extensions.strip= strip -r 5 --no-backup
450 450
451 451 Test tag removal:
452 452
453 453 $ hg tag --remove bar # rev 5
454 454 $ hg tip -vp
455 455 changeset: 5:5f6e8655b1c7
456 456 tag: tip
457 457 user: test
458 458 date: Thu Jan 01 00:00:00 1970 +0000
459 459 files: .hgtags
460 460 description:
461 461 Removed tag bar
462 462
463 463
464 464 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
465 465 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
466 466 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
467 467 @@ -1,1 +1,3 @@
468 468 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
469 469 +78391a272241d70354aa14c874552cad6b51bb42 bar
470 470 +0000000000000000000000000000000000000000 bar
471 471
472 472 $ hg tags
473 473 tip 5:5f6e8655b1c7
474 474 $ hg tags # again, try to expose cache bugs
475 475 tip 5:5f6e8655b1c7
476 476
477 477 Remove nonexistent tag:
478 478
479 479 $ hg tag --remove foobar
480 480 abort: tag 'foobar' does not exist
481 481 [255]
482 482 $ hg tip
483 483 changeset: 5:5f6e8655b1c7
484 484 tag: tip
485 485 user: test
486 486 date: Thu Jan 01 00:00:00 1970 +0000
487 487 summary: Removed tag bar
488 488
489 489
490 490 Undo a tag with rollback:
491 491
492 492 $ hg rollback # destroy rev 5 (restore bar)
493 493 repository tip rolled back to revision 4 (undo commit)
494 494 working directory now based on revision 4
495 495 $ hg tags
496 496 tip 4:0c192d7d5e6b
497 497 bar 1:78391a272241
498 498 $ hg tags
499 499 tip 4:0c192d7d5e6b
500 500 bar 1:78391a272241
501 501
502 502 Test tag rank:
503 503
504 504 $ cd ..
505 505 $ hg init t3
506 506 $ cd t3
507 507 $ echo foo > foo
508 508 $ hg add foo
509 509 $ hg ci -m 'add foo' # rev 0
510 510 $ hg tag -f bar # rev 1 bar -> 0
511 511 $ hg tag -f bar # rev 2 bar -> 1
512 512 $ hg tag -fr 0 bar # rev 3 bar -> 0
513 513 $ hg tag -fr 1 bar # rev 4 bar -> 1
514 514 $ hg tag -fr 0 bar # rev 5 bar -> 0
515 515 $ hg tags
516 516 tip 5:85f05169d91d
517 517 bar 0:bbd179dfa0a7
518 518 $ hg co 3
519 519 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
520 520 $ echo barbar > foo
521 521 $ hg ci -m 'change foo' # rev 6
522 522 created new head
523 523 $ hg tags
524 524 tip 6:735c3ca72986
525 525 bar 0:bbd179dfa0a7
526 526
527 527 Don't allow moving tag without -f:
528 528
529 529 $ hg tag -r 3 bar
530 530 abort: tag 'bar' already exists (use -f to force)
531 531 [255]
532 532 $ hg tags
533 533 tip 6:735c3ca72986
534 534 bar 0:bbd179dfa0a7
535 535
536 536 Strip 1: expose an old head:
537 537
538 538 $ hg --config extensions.mq= strip 5
539 539 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
540 540 $ hg tags # partly stale cache
541 541 tip 5:735c3ca72986
542 542 bar 1:78391a272241
543 543 $ hg tags # up-to-date cache
544 544 tip 5:735c3ca72986
545 545 bar 1:78391a272241
546 546
547 547 Strip 2: destroy whole branch, no old head exposed
548 548
549 549 $ hg --config extensions.mq= strip 4
550 550 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
551 551 $ hg tags # partly stale
552 552 tip 4:735c3ca72986
553 553 bar 0:bbd179dfa0a7
554 554 $ rm -f .hg/cache/tags2-visible
555 555 $ hg tags # cold cache
556 556 tip 4:735c3ca72986
557 557 bar 0:bbd179dfa0a7
558 558
559 559 Test tag rank with 3 heads:
560 560
561 561 $ cd ..
562 562 $ hg init t4
563 563 $ cd t4
564 564 $ echo foo > foo
565 565 $ hg add
566 566 adding foo
567 567 $ hg ci -m 'add foo' # rev 0
568 568 $ hg tag bar # rev 1 bar -> 0
569 569 $ hg tag -f bar # rev 2 bar -> 1
570 570 $ hg up -qC 0
571 571 $ hg tag -fr 2 bar # rev 3 bar -> 2
572 572 $ hg tags
573 573 tip 3:197c21bbbf2c
574 574 bar 2:6fa450212aeb
575 575 $ hg up -qC 0
576 576 $ hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2
577 577
578 578 Bar should still point to rev 2:
579 579
580 580 $ hg tags
581 581 tip 4:3b4b14ed0202
582 582 bar 2:6fa450212aeb
583 583
584 584 Test that removing global/local tags does not get confused when trying
585 585 to remove a tag of type X which actually only exists as a type Y:
586 586
587 587 $ cd ..
588 588 $ hg init t5
589 589 $ cd t5
590 590 $ echo foo > foo
591 591 $ hg add
592 592 adding foo
593 593 $ hg ci -m 'add foo' # rev 0
594 594
595 595 $ hg tag -r 0 -l localtag
596 596 $ hg tag --remove localtag
597 597 abort: tag 'localtag' is not a global tag
598 598 [255]
599 599 $
600 600 $ hg tag -r 0 globaltag
601 601 $ hg tag --remove -l globaltag
602 602 abort: tag 'globaltag' is not a local tag
603 603 [255]
604 604 $ hg tags -v
605 605 tip 1:a0b6fe111088
606 606 localtag 0:bbd179dfa0a7 local
607 607 globaltag 0:bbd179dfa0a7
608 608
609 609 Test for issue3911
610 610
611 611 $ hg tag -r 0 -l localtag2
612 612 $ hg tag -l --remove localtag2
613 613 $ hg tags -v
614 614 tip 1:a0b6fe111088
615 615 localtag 0:bbd179dfa0a7 local
616 616 globaltag 0:bbd179dfa0a7
617 617
618 618 $ hg tag -r 1 -f localtag
619 619 $ hg tags -v
620 620 tip 2:5c70a037bb37
621 621 localtag 1:a0b6fe111088
622 622 globaltag 0:bbd179dfa0a7
623 623
624 624 $ hg tags -v
625 625 tip 2:5c70a037bb37
626 626 localtag 1:a0b6fe111088
627 627 globaltag 0:bbd179dfa0a7
628 628
629 629 $ hg tag -r 1 localtag2
630 630 $ hg tags -v
631 631 tip 3:bbfb8cd42be2
632 632 localtag2 1:a0b6fe111088
633 633 localtag 1:a0b6fe111088
634 634 globaltag 0:bbd179dfa0a7
635 635
636 636 $ hg tags -v
637 637 tip 3:bbfb8cd42be2
638 638 localtag2 1:a0b6fe111088
639 639 localtag 1:a0b6fe111088
640 640 globaltag 0:bbd179dfa0a7
641 641
642 642 $ cd ..
643 643
644 644 Create a repository with tags data to test .hgtags fnodes transfer
645 645
646 646 $ hg init tagsserver
647 647 $ cd tagsserver
648 648 $ touch foo
649 649 $ hg -q commit -A -m initial
650 650 $ hg tag -m 'tag 0.1' 0.1
651 651 $ echo second > foo
652 652 $ hg commit -m second
653 653 $ hg tag -m 'tag 0.2' 0.2
654 654 $ hg tags
655 655 tip 3:40f0358cb314
656 656 0.2 2:f63cc8fe54e4
657 657 0.1 0:96ee1d7354c4
658 658 $ cd ..
659 659
660 660 Cloning should pull down hgtags fnodes mappings and write the cache file
661 661
662 662 $ hg clone --pull tagsserver tagsclient
663 663 requesting all changes
664 664 adding changesets
665 665 adding manifests
666 666 adding file changes
667 667 added 4 changesets with 4 changes to 2 files
668 668 updating to branch default
669 669 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
670 670
671 671 Missing tags2* files means the cache wasn't written through the normal mechanism.
672 672
673 673 $ ls tagsclient/.hg/cache
674 674 branch2-served
675 675 checkisexec
676 676 checklink
677 checklink-target
677 678 hgtagsfnodes1
678 679 rbc-names-v1
679 680 rbc-revs-v1
680 681
681 682 Cache should contain the head only, even though other nodes have tags data
682 683
683 684 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
684 685 tagsclient/.hg/cache/hgtagsfnodes1: size=96
685 686 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
686 687 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
687 688 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
688 689 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
689 690 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
690 691 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
691 692
692 693 Running hg tags should produce tags2* file and not change cache
693 694
694 695 $ hg -R tagsclient tags
695 696 tip 3:40f0358cb314
696 697 0.2 2:f63cc8fe54e4
697 698 0.1 0:96ee1d7354c4
698 699
699 700 $ ls tagsclient/.hg/cache
700 701 branch2-served
701 702 checkisexec
702 703 checklink
704 checklink-target
703 705 hgtagsfnodes1
704 706 rbc-names-v1
705 707 rbc-revs-v1
706 708 tags2-visible
707 709
708 710 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
709 711 tagsclient/.hg/cache/hgtagsfnodes1: size=96
710 712 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
711 713 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
712 714 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
713 715 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
714 716 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
715 717 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
716 718
General Comments 0
You need to be logged in to leave comments. Login now