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