##// END OF EJS Templates
localrepo: reuse parent manifest in commitctx if no files have changed...
Peter Arrenbrecht -
r14162:301725c3 default
parent child Browse files
Show More
@@ -1,1953 +1,1959
1 # localrepo.py - read/write repository class for mercurial
1 # localrepo.py - read/write repository class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
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 node import bin, hex, nullid, nullrev, short
8 from node import bin, hex, nullid, nullrev, short
9 from i18n import _
9 from i18n import _
10 import repo, changegroup, subrepo, discovery, pushkey
10 import repo, changegroup, subrepo, discovery, pushkey
11 import changelog, dirstate, filelog, manifest, context, bookmarks
11 import changelog, dirstate, filelog, manifest, context, bookmarks
12 import lock, transaction, store, encoding
12 import lock, transaction, store, encoding
13 import scmutil, util, extensions, hook, error
13 import scmutil, util, extensions, hook, error
14 import match as matchmod
14 import match as matchmod
15 import merge as mergemod
15 import merge as mergemod
16 import tags as tagsmod
16 import tags as tagsmod
17 from lock import release
17 from lock import release
18 import weakref, errno, os, time, inspect
18 import weakref, errno, os, time, inspect
19 propertycache = util.propertycache
19 propertycache = util.propertycache
20
20
21 class localrepository(repo.repository):
21 class localrepository(repo.repository):
22 capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
22 capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
23 'known', 'getbundle'))
23 'known', 'getbundle'))
24 supportedformats = set(('revlogv1', 'parentdelta'))
24 supportedformats = set(('revlogv1', 'parentdelta'))
25 supported = supportedformats | set(('store', 'fncache', 'shared',
25 supported = supportedformats | set(('store', 'fncache', 'shared',
26 'dotencode'))
26 'dotencode'))
27
27
28 def __init__(self, baseui, path=None, create=0):
28 def __init__(self, baseui, path=None, create=0):
29 repo.repository.__init__(self)
29 repo.repository.__init__(self)
30 self.root = os.path.realpath(util.expandpath(path))
30 self.root = os.path.realpath(util.expandpath(path))
31 self.path = os.path.join(self.root, ".hg")
31 self.path = os.path.join(self.root, ".hg")
32 self.origroot = path
32 self.origroot = path
33 self.auditor = scmutil.path_auditor(self.root, self._checknested)
33 self.auditor = scmutil.path_auditor(self.root, self._checknested)
34 self.opener = scmutil.opener(self.path)
34 self.opener = scmutil.opener(self.path)
35 self.wopener = scmutil.opener(self.root)
35 self.wopener = scmutil.opener(self.root)
36 self.baseui = baseui
36 self.baseui = baseui
37 self.ui = baseui.copy()
37 self.ui = baseui.copy()
38
38
39 try:
39 try:
40 self.ui.readconfig(self.join("hgrc"), self.root)
40 self.ui.readconfig(self.join("hgrc"), self.root)
41 extensions.loadall(self.ui)
41 extensions.loadall(self.ui)
42 except IOError:
42 except IOError:
43 pass
43 pass
44
44
45 if not os.path.isdir(self.path):
45 if not os.path.isdir(self.path):
46 if create:
46 if create:
47 if not os.path.exists(path):
47 if not os.path.exists(path):
48 util.makedirs(path)
48 util.makedirs(path)
49 util.makedir(self.path, notindexed=True)
49 util.makedir(self.path, notindexed=True)
50 requirements = ["revlogv1"]
50 requirements = ["revlogv1"]
51 if self.ui.configbool('format', 'usestore', True):
51 if self.ui.configbool('format', 'usestore', True):
52 os.mkdir(os.path.join(self.path, "store"))
52 os.mkdir(os.path.join(self.path, "store"))
53 requirements.append("store")
53 requirements.append("store")
54 if self.ui.configbool('format', 'usefncache', True):
54 if self.ui.configbool('format', 'usefncache', True):
55 requirements.append("fncache")
55 requirements.append("fncache")
56 if self.ui.configbool('format', 'dotencode', True):
56 if self.ui.configbool('format', 'dotencode', True):
57 requirements.append('dotencode')
57 requirements.append('dotencode')
58 # create an invalid changelog
58 # create an invalid changelog
59 self.opener("00changelog.i", "a").write(
59 self.opener("00changelog.i", "a").write(
60 '\0\0\0\2' # represents revlogv2
60 '\0\0\0\2' # represents revlogv2
61 ' dummy changelog to prevent using the old repo layout'
61 ' dummy changelog to prevent using the old repo layout'
62 )
62 )
63 if self.ui.configbool('format', 'parentdelta', False):
63 if self.ui.configbool('format', 'parentdelta', False):
64 requirements.append("parentdelta")
64 requirements.append("parentdelta")
65 else:
65 else:
66 raise error.RepoError(_("repository %s not found") % path)
66 raise error.RepoError(_("repository %s not found") % path)
67 elif create:
67 elif create:
68 raise error.RepoError(_("repository %s already exists") % path)
68 raise error.RepoError(_("repository %s already exists") % path)
69 else:
69 else:
70 # find requirements
70 # find requirements
71 requirements = set()
71 requirements = set()
72 try:
72 try:
73 requirements = set(self.opener("requires").read().splitlines())
73 requirements = set(self.opener("requires").read().splitlines())
74 except IOError, inst:
74 except IOError, inst:
75 if inst.errno != errno.ENOENT:
75 if inst.errno != errno.ENOENT:
76 raise
76 raise
77 for r in requirements - self.supported:
77 for r in requirements - self.supported:
78 raise error.RequirementError(
78 raise error.RequirementError(
79 _("requirement '%s' not supported") % r)
79 _("requirement '%s' not supported") % r)
80
80
81 self.sharedpath = self.path
81 self.sharedpath = self.path
82 try:
82 try:
83 s = os.path.realpath(self.opener("sharedpath").read())
83 s = os.path.realpath(self.opener("sharedpath").read())
84 if not os.path.exists(s):
84 if not os.path.exists(s):
85 raise error.RepoError(
85 raise error.RepoError(
86 _('.hg/sharedpath points to nonexistent directory %s') % s)
86 _('.hg/sharedpath points to nonexistent directory %s') % s)
87 self.sharedpath = s
87 self.sharedpath = s
88 except IOError, inst:
88 except IOError, inst:
89 if inst.errno != errno.ENOENT:
89 if inst.errno != errno.ENOENT:
90 raise
90 raise
91
91
92 self.store = store.store(requirements, self.sharedpath, scmutil.opener)
92 self.store = store.store(requirements, self.sharedpath, scmutil.opener)
93 self.spath = self.store.path
93 self.spath = self.store.path
94 self.sopener = self.store.opener
94 self.sopener = self.store.opener
95 self.sjoin = self.store.join
95 self.sjoin = self.store.join
96 self.opener.createmode = self.store.createmode
96 self.opener.createmode = self.store.createmode
97 self._applyrequirements(requirements)
97 self._applyrequirements(requirements)
98 if create:
98 if create:
99 self._writerequirements()
99 self._writerequirements()
100
100
101 # These two define the set of tags for this repository. _tags
101 # These two define the set of tags for this repository. _tags
102 # maps tag name to node; _tagtypes maps tag name to 'global' or
102 # maps tag name to node; _tagtypes maps tag name to 'global' or
103 # 'local'. (Global tags are defined by .hgtags across all
103 # 'local'. (Global tags are defined by .hgtags across all
104 # heads, and local tags are defined in .hg/localtags.) They
104 # heads, and local tags are defined in .hg/localtags.) They
105 # constitute the in-memory cache of tags.
105 # constitute the in-memory cache of tags.
106 self._tags = None
106 self._tags = None
107 self._tagtypes = None
107 self._tagtypes = None
108
108
109 self._branchcache = None
109 self._branchcache = None
110 self._branchcachetip = None
110 self._branchcachetip = None
111 self.nodetagscache = None
111 self.nodetagscache = None
112 self.filterpats = {}
112 self.filterpats = {}
113 self._datafilters = {}
113 self._datafilters = {}
114 self._transref = self._lockref = self._wlockref = None
114 self._transref = self._lockref = self._wlockref = None
115
115
116 def _applyrequirements(self, requirements):
116 def _applyrequirements(self, requirements):
117 self.requirements = requirements
117 self.requirements = requirements
118 self.sopener.options = {}
118 self.sopener.options = {}
119 if 'parentdelta' in requirements:
119 if 'parentdelta' in requirements:
120 self.sopener.options['parentdelta'] = 1
120 self.sopener.options['parentdelta'] = 1
121
121
122 def _writerequirements(self):
122 def _writerequirements(self):
123 reqfile = self.opener("requires", "w")
123 reqfile = self.opener("requires", "w")
124 for r in self.requirements:
124 for r in self.requirements:
125 reqfile.write("%s\n" % r)
125 reqfile.write("%s\n" % r)
126 reqfile.close()
126 reqfile.close()
127
127
128 def _checknested(self, path):
128 def _checknested(self, path):
129 """Determine if path is a legal nested repository."""
129 """Determine if path is a legal nested repository."""
130 if not path.startswith(self.root):
130 if not path.startswith(self.root):
131 return False
131 return False
132 subpath = path[len(self.root) + 1:]
132 subpath = path[len(self.root) + 1:]
133
133
134 # XXX: Checking against the current working copy is wrong in
134 # XXX: Checking against the current working copy is wrong in
135 # the sense that it can reject things like
135 # the sense that it can reject things like
136 #
136 #
137 # $ hg cat -r 10 sub/x.txt
137 # $ hg cat -r 10 sub/x.txt
138 #
138 #
139 # if sub/ is no longer a subrepository in the working copy
139 # if sub/ is no longer a subrepository in the working copy
140 # parent revision.
140 # parent revision.
141 #
141 #
142 # However, it can of course also allow things that would have
142 # However, it can of course also allow things that would have
143 # been rejected before, such as the above cat command if sub/
143 # been rejected before, such as the above cat command if sub/
144 # is a subrepository now, but was a normal directory before.
144 # is a subrepository now, but was a normal directory before.
145 # The old path auditor would have rejected by mistake since it
145 # The old path auditor would have rejected by mistake since it
146 # panics when it sees sub/.hg/.
146 # panics when it sees sub/.hg/.
147 #
147 #
148 # All in all, checking against the working copy seems sensible
148 # All in all, checking against the working copy seems sensible
149 # since we want to prevent access to nested repositories on
149 # since we want to prevent access to nested repositories on
150 # the filesystem *now*.
150 # the filesystem *now*.
151 ctx = self[None]
151 ctx = self[None]
152 parts = util.splitpath(subpath)
152 parts = util.splitpath(subpath)
153 while parts:
153 while parts:
154 prefix = os.sep.join(parts)
154 prefix = os.sep.join(parts)
155 if prefix in ctx.substate:
155 if prefix in ctx.substate:
156 if prefix == subpath:
156 if prefix == subpath:
157 return True
157 return True
158 else:
158 else:
159 sub = ctx.sub(prefix)
159 sub = ctx.sub(prefix)
160 return sub.checknested(subpath[len(prefix) + 1:])
160 return sub.checknested(subpath[len(prefix) + 1:])
161 else:
161 else:
162 parts.pop()
162 parts.pop()
163 return False
163 return False
164
164
165 @util.propertycache
165 @util.propertycache
166 def _bookmarks(self):
166 def _bookmarks(self):
167 return bookmarks.read(self)
167 return bookmarks.read(self)
168
168
169 @util.propertycache
169 @util.propertycache
170 def _bookmarkcurrent(self):
170 def _bookmarkcurrent(self):
171 return bookmarks.readcurrent(self)
171 return bookmarks.readcurrent(self)
172
172
173 @propertycache
173 @propertycache
174 def changelog(self):
174 def changelog(self):
175 c = changelog.changelog(self.sopener)
175 c = changelog.changelog(self.sopener)
176 if 'HG_PENDING' in os.environ:
176 if 'HG_PENDING' in os.environ:
177 p = os.environ['HG_PENDING']
177 p = os.environ['HG_PENDING']
178 if p.startswith(self.root):
178 if p.startswith(self.root):
179 c.readpending('00changelog.i.a')
179 c.readpending('00changelog.i.a')
180 self.sopener.options['defversion'] = c.version
180 self.sopener.options['defversion'] = c.version
181 return c
181 return c
182
182
183 @propertycache
183 @propertycache
184 def manifest(self):
184 def manifest(self):
185 return manifest.manifest(self.sopener)
185 return manifest.manifest(self.sopener)
186
186
187 @propertycache
187 @propertycache
188 def dirstate(self):
188 def dirstate(self):
189 warned = [0]
189 warned = [0]
190 def validate(node):
190 def validate(node):
191 try:
191 try:
192 self.changelog.rev(node)
192 self.changelog.rev(node)
193 return node
193 return node
194 except error.LookupError:
194 except error.LookupError:
195 if not warned[0]:
195 if not warned[0]:
196 warned[0] = True
196 warned[0] = True
197 self.ui.warn(_("warning: ignoring unknown"
197 self.ui.warn(_("warning: ignoring unknown"
198 " working parent %s!\n") % short(node))
198 " working parent %s!\n") % short(node))
199 return nullid
199 return nullid
200
200
201 return dirstate.dirstate(self.opener, self.ui, self.root, validate)
201 return dirstate.dirstate(self.opener, self.ui, self.root, validate)
202
202
203 def __getitem__(self, changeid):
203 def __getitem__(self, changeid):
204 if changeid is None:
204 if changeid is None:
205 return context.workingctx(self)
205 return context.workingctx(self)
206 return context.changectx(self, changeid)
206 return context.changectx(self, changeid)
207
207
208 def __contains__(self, changeid):
208 def __contains__(self, changeid):
209 try:
209 try:
210 return bool(self.lookup(changeid))
210 return bool(self.lookup(changeid))
211 except error.RepoLookupError:
211 except error.RepoLookupError:
212 return False
212 return False
213
213
214 def __nonzero__(self):
214 def __nonzero__(self):
215 return True
215 return True
216
216
217 def __len__(self):
217 def __len__(self):
218 return len(self.changelog)
218 return len(self.changelog)
219
219
220 def __iter__(self):
220 def __iter__(self):
221 for i in xrange(len(self)):
221 for i in xrange(len(self)):
222 yield i
222 yield i
223
223
224 def url(self):
224 def url(self):
225 return 'file:' + self.root
225 return 'file:' + self.root
226
226
227 def hook(self, name, throw=False, **args):
227 def hook(self, name, throw=False, **args):
228 return hook.hook(self.ui, self, name, throw, **args)
228 return hook.hook(self.ui, self, name, throw, **args)
229
229
230 tag_disallowed = ':\r\n'
230 tag_disallowed = ':\r\n'
231
231
232 def _tag(self, names, node, message, local, user, date, extra={}):
232 def _tag(self, names, node, message, local, user, date, extra={}):
233 if isinstance(names, str):
233 if isinstance(names, str):
234 allchars = names
234 allchars = names
235 names = (names,)
235 names = (names,)
236 else:
236 else:
237 allchars = ''.join(names)
237 allchars = ''.join(names)
238 for c in self.tag_disallowed:
238 for c in self.tag_disallowed:
239 if c in allchars:
239 if c in allchars:
240 raise util.Abort(_('%r cannot be used in a tag name') % c)
240 raise util.Abort(_('%r cannot be used in a tag name') % c)
241
241
242 branches = self.branchmap()
242 branches = self.branchmap()
243 for name in names:
243 for name in names:
244 self.hook('pretag', throw=True, node=hex(node), tag=name,
244 self.hook('pretag', throw=True, node=hex(node), tag=name,
245 local=local)
245 local=local)
246 if name in branches:
246 if name in branches:
247 self.ui.warn(_("warning: tag %s conflicts with existing"
247 self.ui.warn(_("warning: tag %s conflicts with existing"
248 " branch name\n") % name)
248 " branch name\n") % name)
249
249
250 def writetags(fp, names, munge, prevtags):
250 def writetags(fp, names, munge, prevtags):
251 fp.seek(0, 2)
251 fp.seek(0, 2)
252 if prevtags and prevtags[-1] != '\n':
252 if prevtags and prevtags[-1] != '\n':
253 fp.write('\n')
253 fp.write('\n')
254 for name in names:
254 for name in names:
255 m = munge and munge(name) or name
255 m = munge and munge(name) or name
256 if self._tagtypes and name in self._tagtypes:
256 if self._tagtypes and name in self._tagtypes:
257 old = self._tags.get(name, nullid)
257 old = self._tags.get(name, nullid)
258 fp.write('%s %s\n' % (hex(old), m))
258 fp.write('%s %s\n' % (hex(old), m))
259 fp.write('%s %s\n' % (hex(node), m))
259 fp.write('%s %s\n' % (hex(node), m))
260 fp.close()
260 fp.close()
261
261
262 prevtags = ''
262 prevtags = ''
263 if local:
263 if local:
264 try:
264 try:
265 fp = self.opener('localtags', 'r+')
265 fp = self.opener('localtags', 'r+')
266 except IOError:
266 except IOError:
267 fp = self.opener('localtags', 'a')
267 fp = self.opener('localtags', 'a')
268 else:
268 else:
269 prevtags = fp.read()
269 prevtags = fp.read()
270
270
271 # local tags are stored in the current charset
271 # local tags are stored in the current charset
272 writetags(fp, names, None, prevtags)
272 writetags(fp, names, None, prevtags)
273 for name in names:
273 for name in names:
274 self.hook('tag', node=hex(node), tag=name, local=local)
274 self.hook('tag', node=hex(node), tag=name, local=local)
275 return
275 return
276
276
277 try:
277 try:
278 fp = self.wfile('.hgtags', 'rb+')
278 fp = self.wfile('.hgtags', 'rb+')
279 except IOError:
279 except IOError:
280 fp = self.wfile('.hgtags', 'ab')
280 fp = self.wfile('.hgtags', 'ab')
281 else:
281 else:
282 prevtags = fp.read()
282 prevtags = fp.read()
283
283
284 # committed tags are stored in UTF-8
284 # committed tags are stored in UTF-8
285 writetags(fp, names, encoding.fromlocal, prevtags)
285 writetags(fp, names, encoding.fromlocal, prevtags)
286
286
287 fp.close()
287 fp.close()
288
288
289 if '.hgtags' not in self.dirstate:
289 if '.hgtags' not in self.dirstate:
290 self[None].add(['.hgtags'])
290 self[None].add(['.hgtags'])
291
291
292 m = matchmod.exact(self.root, '', ['.hgtags'])
292 m = matchmod.exact(self.root, '', ['.hgtags'])
293 tagnode = self.commit(message, user, date, extra=extra, match=m)
293 tagnode = self.commit(message, user, date, extra=extra, match=m)
294
294
295 for name in names:
295 for name in names:
296 self.hook('tag', node=hex(node), tag=name, local=local)
296 self.hook('tag', node=hex(node), tag=name, local=local)
297
297
298 return tagnode
298 return tagnode
299
299
300 def tag(self, names, node, message, local, user, date):
300 def tag(self, names, node, message, local, user, date):
301 '''tag a revision with one or more symbolic names.
301 '''tag a revision with one or more symbolic names.
302
302
303 names is a list of strings or, when adding a single tag, names may be a
303 names is a list of strings or, when adding a single tag, names may be a
304 string.
304 string.
305
305
306 if local is True, the tags are stored in a per-repository file.
306 if local is True, the tags are stored in a per-repository file.
307 otherwise, they are stored in the .hgtags file, and a new
307 otherwise, they are stored in the .hgtags file, and a new
308 changeset is committed with the change.
308 changeset is committed with the change.
309
309
310 keyword arguments:
310 keyword arguments:
311
311
312 local: whether to store tags in non-version-controlled file
312 local: whether to store tags in non-version-controlled file
313 (default False)
313 (default False)
314
314
315 message: commit message to use if committing
315 message: commit message to use if committing
316
316
317 user: name of user to use if committing
317 user: name of user to use if committing
318
318
319 date: date tuple to use if committing'''
319 date: date tuple to use if committing'''
320
320
321 if not local:
321 if not local:
322 for x in self.status()[:5]:
322 for x in self.status()[:5]:
323 if '.hgtags' in x:
323 if '.hgtags' in x:
324 raise util.Abort(_('working copy of .hgtags is changed '
324 raise util.Abort(_('working copy of .hgtags is changed '
325 '(please commit .hgtags manually)'))
325 '(please commit .hgtags manually)'))
326
326
327 self.tags() # instantiate the cache
327 self.tags() # instantiate the cache
328 self._tag(names, node, message, local, user, date)
328 self._tag(names, node, message, local, user, date)
329
329
330 def tags(self):
330 def tags(self):
331 '''return a mapping of tag to node'''
331 '''return a mapping of tag to node'''
332 if self._tags is None:
332 if self._tags is None:
333 (self._tags, self._tagtypes) = self._findtags()
333 (self._tags, self._tagtypes) = self._findtags()
334
334
335 return self._tags
335 return self._tags
336
336
337 def _findtags(self):
337 def _findtags(self):
338 '''Do the hard work of finding tags. Return a pair of dicts
338 '''Do the hard work of finding tags. Return a pair of dicts
339 (tags, tagtypes) where tags maps tag name to node, and tagtypes
339 (tags, tagtypes) where tags maps tag name to node, and tagtypes
340 maps tag name to a string like \'global\' or \'local\'.
340 maps tag name to a string like \'global\' or \'local\'.
341 Subclasses or extensions are free to add their own tags, but
341 Subclasses or extensions are free to add their own tags, but
342 should be aware that the returned dicts will be retained for the
342 should be aware that the returned dicts will be retained for the
343 duration of the localrepo object.'''
343 duration of the localrepo object.'''
344
344
345 # XXX what tagtype should subclasses/extensions use? Currently
345 # XXX what tagtype should subclasses/extensions use? Currently
346 # mq and bookmarks add tags, but do not set the tagtype at all.
346 # mq and bookmarks add tags, but do not set the tagtype at all.
347 # Should each extension invent its own tag type? Should there
347 # Should each extension invent its own tag type? Should there
348 # be one tagtype for all such "virtual" tags? Or is the status
348 # be one tagtype for all such "virtual" tags? Or is the status
349 # quo fine?
349 # quo fine?
350
350
351 alltags = {} # map tag name to (node, hist)
351 alltags = {} # map tag name to (node, hist)
352 tagtypes = {}
352 tagtypes = {}
353
353
354 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
354 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
355 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
355 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
356
356
357 # Build the return dicts. Have to re-encode tag names because
357 # Build the return dicts. Have to re-encode tag names because
358 # the tags module always uses UTF-8 (in order not to lose info
358 # the tags module always uses UTF-8 (in order not to lose info
359 # writing to the cache), but the rest of Mercurial wants them in
359 # writing to the cache), but the rest of Mercurial wants them in
360 # local encoding.
360 # local encoding.
361 tags = {}
361 tags = {}
362 for (name, (node, hist)) in alltags.iteritems():
362 for (name, (node, hist)) in alltags.iteritems():
363 if node != nullid:
363 if node != nullid:
364 try:
364 try:
365 # ignore tags to unknown nodes
365 # ignore tags to unknown nodes
366 self.changelog.lookup(node)
366 self.changelog.lookup(node)
367 tags[encoding.tolocal(name)] = node
367 tags[encoding.tolocal(name)] = node
368 except error.LookupError:
368 except error.LookupError:
369 pass
369 pass
370 tags['tip'] = self.changelog.tip()
370 tags['tip'] = self.changelog.tip()
371 tagtypes = dict([(encoding.tolocal(name), value)
371 tagtypes = dict([(encoding.tolocal(name), value)
372 for (name, value) in tagtypes.iteritems()])
372 for (name, value) in tagtypes.iteritems()])
373 return (tags, tagtypes)
373 return (tags, tagtypes)
374
374
375 def tagtype(self, tagname):
375 def tagtype(self, tagname):
376 '''
376 '''
377 return the type of the given tag. result can be:
377 return the type of the given tag. result can be:
378
378
379 'local' : a local tag
379 'local' : a local tag
380 'global' : a global tag
380 'global' : a global tag
381 None : tag does not exist
381 None : tag does not exist
382 '''
382 '''
383
383
384 self.tags()
384 self.tags()
385
385
386 return self._tagtypes.get(tagname)
386 return self._tagtypes.get(tagname)
387
387
388 def tagslist(self):
388 def tagslist(self):
389 '''return a list of tags ordered by revision'''
389 '''return a list of tags ordered by revision'''
390 l = []
390 l = []
391 for t, n in self.tags().iteritems():
391 for t, n in self.tags().iteritems():
392 r = self.changelog.rev(n)
392 r = self.changelog.rev(n)
393 l.append((r, t, n))
393 l.append((r, t, n))
394 return [(t, n) for r, t, n in sorted(l)]
394 return [(t, n) for r, t, n in sorted(l)]
395
395
396 def nodetags(self, node):
396 def nodetags(self, node):
397 '''return the tags associated with a node'''
397 '''return the tags associated with a node'''
398 if not self.nodetagscache:
398 if not self.nodetagscache:
399 self.nodetagscache = {}
399 self.nodetagscache = {}
400 for t, n in self.tags().iteritems():
400 for t, n in self.tags().iteritems():
401 self.nodetagscache.setdefault(n, []).append(t)
401 self.nodetagscache.setdefault(n, []).append(t)
402 for tags in self.nodetagscache.itervalues():
402 for tags in self.nodetagscache.itervalues():
403 tags.sort()
403 tags.sort()
404 return self.nodetagscache.get(node, [])
404 return self.nodetagscache.get(node, [])
405
405
406 def nodebookmarks(self, node):
406 def nodebookmarks(self, node):
407 marks = []
407 marks = []
408 for bookmark, n in self._bookmarks.iteritems():
408 for bookmark, n in self._bookmarks.iteritems():
409 if n == node:
409 if n == node:
410 marks.append(bookmark)
410 marks.append(bookmark)
411 return sorted(marks)
411 return sorted(marks)
412
412
413 def _branchtags(self, partial, lrev):
413 def _branchtags(self, partial, lrev):
414 # TODO: rename this function?
414 # TODO: rename this function?
415 tiprev = len(self) - 1
415 tiprev = len(self) - 1
416 if lrev != tiprev:
416 if lrev != tiprev:
417 ctxgen = (self[r] for r in xrange(lrev + 1, tiprev + 1))
417 ctxgen = (self[r] for r in xrange(lrev + 1, tiprev + 1))
418 self._updatebranchcache(partial, ctxgen)
418 self._updatebranchcache(partial, ctxgen)
419 self._writebranchcache(partial, self.changelog.tip(), tiprev)
419 self._writebranchcache(partial, self.changelog.tip(), tiprev)
420
420
421 return partial
421 return partial
422
422
423 def updatebranchcache(self):
423 def updatebranchcache(self):
424 tip = self.changelog.tip()
424 tip = self.changelog.tip()
425 if self._branchcache is not None and self._branchcachetip == tip:
425 if self._branchcache is not None and self._branchcachetip == tip:
426 return self._branchcache
426 return self._branchcache
427
427
428 oldtip = self._branchcachetip
428 oldtip = self._branchcachetip
429 self._branchcachetip = tip
429 self._branchcachetip = tip
430 if oldtip is None or oldtip not in self.changelog.nodemap:
430 if oldtip is None or oldtip not in self.changelog.nodemap:
431 partial, last, lrev = self._readbranchcache()
431 partial, last, lrev = self._readbranchcache()
432 else:
432 else:
433 lrev = self.changelog.rev(oldtip)
433 lrev = self.changelog.rev(oldtip)
434 partial = self._branchcache
434 partial = self._branchcache
435
435
436 self._branchtags(partial, lrev)
436 self._branchtags(partial, lrev)
437 # this private cache holds all heads (not just tips)
437 # this private cache holds all heads (not just tips)
438 self._branchcache = partial
438 self._branchcache = partial
439
439
440 def branchmap(self):
440 def branchmap(self):
441 '''returns a dictionary {branch: [branchheads]}'''
441 '''returns a dictionary {branch: [branchheads]}'''
442 self.updatebranchcache()
442 self.updatebranchcache()
443 return self._branchcache
443 return self._branchcache
444
444
445 def branchtags(self):
445 def branchtags(self):
446 '''return a dict where branch names map to the tipmost head of
446 '''return a dict where branch names map to the tipmost head of
447 the branch, open heads come before closed'''
447 the branch, open heads come before closed'''
448 bt = {}
448 bt = {}
449 for bn, heads in self.branchmap().iteritems():
449 for bn, heads in self.branchmap().iteritems():
450 tip = heads[-1]
450 tip = heads[-1]
451 for h in reversed(heads):
451 for h in reversed(heads):
452 if 'close' not in self.changelog.read(h)[5]:
452 if 'close' not in self.changelog.read(h)[5]:
453 tip = h
453 tip = h
454 break
454 break
455 bt[bn] = tip
455 bt[bn] = tip
456 return bt
456 return bt
457
457
458 def _readbranchcache(self):
458 def _readbranchcache(self):
459 partial = {}
459 partial = {}
460 try:
460 try:
461 f = self.opener("cache/branchheads")
461 f = self.opener("cache/branchheads")
462 lines = f.read().split('\n')
462 lines = f.read().split('\n')
463 f.close()
463 f.close()
464 except (IOError, OSError):
464 except (IOError, OSError):
465 return {}, nullid, nullrev
465 return {}, nullid, nullrev
466
466
467 try:
467 try:
468 last, lrev = lines.pop(0).split(" ", 1)
468 last, lrev = lines.pop(0).split(" ", 1)
469 last, lrev = bin(last), int(lrev)
469 last, lrev = bin(last), int(lrev)
470 if lrev >= len(self) or self[lrev].node() != last:
470 if lrev >= len(self) or self[lrev].node() != last:
471 # invalidate the cache
471 # invalidate the cache
472 raise ValueError('invalidating branch cache (tip differs)')
472 raise ValueError('invalidating branch cache (tip differs)')
473 for l in lines:
473 for l in lines:
474 if not l:
474 if not l:
475 continue
475 continue
476 node, label = l.split(" ", 1)
476 node, label = l.split(" ", 1)
477 label = encoding.tolocal(label.strip())
477 label = encoding.tolocal(label.strip())
478 partial.setdefault(label, []).append(bin(node))
478 partial.setdefault(label, []).append(bin(node))
479 except KeyboardInterrupt:
479 except KeyboardInterrupt:
480 raise
480 raise
481 except Exception, inst:
481 except Exception, inst:
482 if self.ui.debugflag:
482 if self.ui.debugflag:
483 self.ui.warn(str(inst), '\n')
483 self.ui.warn(str(inst), '\n')
484 partial, last, lrev = {}, nullid, nullrev
484 partial, last, lrev = {}, nullid, nullrev
485 return partial, last, lrev
485 return partial, last, lrev
486
486
487 def _writebranchcache(self, branches, tip, tiprev):
487 def _writebranchcache(self, branches, tip, tiprev):
488 try:
488 try:
489 f = self.opener("cache/branchheads", "w", atomictemp=True)
489 f = self.opener("cache/branchheads", "w", atomictemp=True)
490 f.write("%s %s\n" % (hex(tip), tiprev))
490 f.write("%s %s\n" % (hex(tip), tiprev))
491 for label, nodes in branches.iteritems():
491 for label, nodes in branches.iteritems():
492 for node in nodes:
492 for node in nodes:
493 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
493 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
494 f.rename()
494 f.rename()
495 except (IOError, OSError):
495 except (IOError, OSError):
496 pass
496 pass
497
497
498 def _updatebranchcache(self, partial, ctxgen):
498 def _updatebranchcache(self, partial, ctxgen):
499 # collect new branch entries
499 # collect new branch entries
500 newbranches = {}
500 newbranches = {}
501 for c in ctxgen:
501 for c in ctxgen:
502 newbranches.setdefault(c.branch(), []).append(c.node())
502 newbranches.setdefault(c.branch(), []).append(c.node())
503 # if older branchheads are reachable from new ones, they aren't
503 # if older branchheads are reachable from new ones, they aren't
504 # really branchheads. Note checking parents is insufficient:
504 # really branchheads. Note checking parents is insufficient:
505 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
505 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
506 for branch, newnodes in newbranches.iteritems():
506 for branch, newnodes in newbranches.iteritems():
507 bheads = partial.setdefault(branch, [])
507 bheads = partial.setdefault(branch, [])
508 bheads.extend(newnodes)
508 bheads.extend(newnodes)
509 if len(bheads) <= 1:
509 if len(bheads) <= 1:
510 continue
510 continue
511 bheads = sorted(bheads, key=lambda x: self[x].rev())
511 bheads = sorted(bheads, key=lambda x: self[x].rev())
512 # starting from tip means fewer passes over reachable
512 # starting from tip means fewer passes over reachable
513 while newnodes:
513 while newnodes:
514 latest = newnodes.pop()
514 latest = newnodes.pop()
515 if latest not in bheads:
515 if latest not in bheads:
516 continue
516 continue
517 minbhrev = self[bheads[0]].node()
517 minbhrev = self[bheads[0]].node()
518 reachable = self.changelog.reachable(latest, minbhrev)
518 reachable = self.changelog.reachable(latest, minbhrev)
519 reachable.remove(latest)
519 reachable.remove(latest)
520 if reachable:
520 if reachable:
521 bheads = [b for b in bheads if b not in reachable]
521 bheads = [b for b in bheads if b not in reachable]
522 partial[branch] = bheads
522 partial[branch] = bheads
523
523
524 def lookup(self, key):
524 def lookup(self, key):
525 if isinstance(key, int):
525 if isinstance(key, int):
526 return self.changelog.node(key)
526 return self.changelog.node(key)
527 elif key == '.':
527 elif key == '.':
528 return self.dirstate.p1()
528 return self.dirstate.p1()
529 elif key == 'null':
529 elif key == 'null':
530 return nullid
530 return nullid
531 elif key == 'tip':
531 elif key == 'tip':
532 return self.changelog.tip()
532 return self.changelog.tip()
533 n = self.changelog._match(key)
533 n = self.changelog._match(key)
534 if n:
534 if n:
535 return n
535 return n
536 if key in self._bookmarks:
536 if key in self._bookmarks:
537 return self._bookmarks[key]
537 return self._bookmarks[key]
538 if key in self.tags():
538 if key in self.tags():
539 return self.tags()[key]
539 return self.tags()[key]
540 if key in self.branchtags():
540 if key in self.branchtags():
541 return self.branchtags()[key]
541 return self.branchtags()[key]
542 n = self.changelog._partialmatch(key)
542 n = self.changelog._partialmatch(key)
543 if n:
543 if n:
544 return n
544 return n
545
545
546 # can't find key, check if it might have come from damaged dirstate
546 # can't find key, check if it might have come from damaged dirstate
547 if key in self.dirstate.parents():
547 if key in self.dirstate.parents():
548 raise error.Abort(_("working directory has unknown parent '%s'!")
548 raise error.Abort(_("working directory has unknown parent '%s'!")
549 % short(key))
549 % short(key))
550 try:
550 try:
551 if len(key) == 20:
551 if len(key) == 20:
552 key = hex(key)
552 key = hex(key)
553 except TypeError:
553 except TypeError:
554 pass
554 pass
555 raise error.RepoLookupError(_("unknown revision '%s'") % key)
555 raise error.RepoLookupError(_("unknown revision '%s'") % key)
556
556
557 def lookupbranch(self, key, remote=None):
557 def lookupbranch(self, key, remote=None):
558 repo = remote or self
558 repo = remote or self
559 if key in repo.branchmap():
559 if key in repo.branchmap():
560 return key
560 return key
561
561
562 repo = (remote and remote.local()) and remote or self
562 repo = (remote and remote.local()) and remote or self
563 return repo[key].branch()
563 return repo[key].branch()
564
564
565 def known(self, nodes):
565 def known(self, nodes):
566 nm = self.changelog.nodemap
566 nm = self.changelog.nodemap
567 return [(n in nm) for n in nodes]
567 return [(n in nm) for n in nodes]
568
568
569 def local(self):
569 def local(self):
570 return True
570 return True
571
571
572 def join(self, f):
572 def join(self, f):
573 return os.path.join(self.path, f)
573 return os.path.join(self.path, f)
574
574
575 def wjoin(self, f):
575 def wjoin(self, f):
576 return os.path.join(self.root, f)
576 return os.path.join(self.root, f)
577
577
578 def file(self, f):
578 def file(self, f):
579 if f[0] == '/':
579 if f[0] == '/':
580 f = f[1:]
580 f = f[1:]
581 return filelog.filelog(self.sopener, f)
581 return filelog.filelog(self.sopener, f)
582
582
583 def changectx(self, changeid):
583 def changectx(self, changeid):
584 return self[changeid]
584 return self[changeid]
585
585
586 def parents(self, changeid=None):
586 def parents(self, changeid=None):
587 '''get list of changectxs for parents of changeid'''
587 '''get list of changectxs for parents of changeid'''
588 return self[changeid].parents()
588 return self[changeid].parents()
589
589
590 def filectx(self, path, changeid=None, fileid=None):
590 def filectx(self, path, changeid=None, fileid=None):
591 """changeid can be a changeset revision, node, or tag.
591 """changeid can be a changeset revision, node, or tag.
592 fileid can be a file revision or node."""
592 fileid can be a file revision or node."""
593 return context.filectx(self, path, changeid, fileid)
593 return context.filectx(self, path, changeid, fileid)
594
594
595 def getcwd(self):
595 def getcwd(self):
596 return self.dirstate.getcwd()
596 return self.dirstate.getcwd()
597
597
598 def pathto(self, f, cwd=None):
598 def pathto(self, f, cwd=None):
599 return self.dirstate.pathto(f, cwd)
599 return self.dirstate.pathto(f, cwd)
600
600
601 def wfile(self, f, mode='r'):
601 def wfile(self, f, mode='r'):
602 return self.wopener(f, mode)
602 return self.wopener(f, mode)
603
603
604 def _link(self, f):
604 def _link(self, f):
605 return os.path.islink(self.wjoin(f))
605 return os.path.islink(self.wjoin(f))
606
606
607 def _loadfilter(self, filter):
607 def _loadfilter(self, filter):
608 if filter not in self.filterpats:
608 if filter not in self.filterpats:
609 l = []
609 l = []
610 for pat, cmd in self.ui.configitems(filter):
610 for pat, cmd in self.ui.configitems(filter):
611 if cmd == '!':
611 if cmd == '!':
612 continue
612 continue
613 mf = matchmod.match(self.root, '', [pat])
613 mf = matchmod.match(self.root, '', [pat])
614 fn = None
614 fn = None
615 params = cmd
615 params = cmd
616 for name, filterfn in self._datafilters.iteritems():
616 for name, filterfn in self._datafilters.iteritems():
617 if cmd.startswith(name):
617 if cmd.startswith(name):
618 fn = filterfn
618 fn = filterfn
619 params = cmd[len(name):].lstrip()
619 params = cmd[len(name):].lstrip()
620 break
620 break
621 if not fn:
621 if not fn:
622 fn = lambda s, c, **kwargs: util.filter(s, c)
622 fn = lambda s, c, **kwargs: util.filter(s, c)
623 # Wrap old filters not supporting keyword arguments
623 # Wrap old filters not supporting keyword arguments
624 if not inspect.getargspec(fn)[2]:
624 if not inspect.getargspec(fn)[2]:
625 oldfn = fn
625 oldfn = fn
626 fn = lambda s, c, **kwargs: oldfn(s, c)
626 fn = lambda s, c, **kwargs: oldfn(s, c)
627 l.append((mf, fn, params))
627 l.append((mf, fn, params))
628 self.filterpats[filter] = l
628 self.filterpats[filter] = l
629 return self.filterpats[filter]
629 return self.filterpats[filter]
630
630
631 def _filter(self, filterpats, filename, data):
631 def _filter(self, filterpats, filename, data):
632 for mf, fn, cmd in filterpats:
632 for mf, fn, cmd in filterpats:
633 if mf(filename):
633 if mf(filename):
634 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
634 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
635 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
635 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
636 break
636 break
637
637
638 return data
638 return data
639
639
640 @propertycache
640 @propertycache
641 def _encodefilterpats(self):
641 def _encodefilterpats(self):
642 return self._loadfilter('encode')
642 return self._loadfilter('encode')
643
643
644 @propertycache
644 @propertycache
645 def _decodefilterpats(self):
645 def _decodefilterpats(self):
646 return self._loadfilter('decode')
646 return self._loadfilter('decode')
647
647
648 def adddatafilter(self, name, filter):
648 def adddatafilter(self, name, filter):
649 self._datafilters[name] = filter
649 self._datafilters[name] = filter
650
650
651 def wread(self, filename):
651 def wread(self, filename):
652 if self._link(filename):
652 if self._link(filename):
653 data = os.readlink(self.wjoin(filename))
653 data = os.readlink(self.wjoin(filename))
654 else:
654 else:
655 data = self.wopener(filename, 'r').read()
655 data = self.wopener(filename, 'r').read()
656 return self._filter(self._encodefilterpats, filename, data)
656 return self._filter(self._encodefilterpats, filename, data)
657
657
658 def wwrite(self, filename, data, flags):
658 def wwrite(self, filename, data, flags):
659 data = self._filter(self._decodefilterpats, filename, data)
659 data = self._filter(self._decodefilterpats, filename, data)
660 if 'l' in flags:
660 if 'l' in flags:
661 self.wopener.symlink(data, filename)
661 self.wopener.symlink(data, filename)
662 else:
662 else:
663 self.wopener(filename, 'w').write(data)
663 self.wopener(filename, 'w').write(data)
664 if 'x' in flags:
664 if 'x' in flags:
665 util.set_flags(self.wjoin(filename), False, True)
665 util.set_flags(self.wjoin(filename), False, True)
666
666
667 def wwritedata(self, filename, data):
667 def wwritedata(self, filename, data):
668 return self._filter(self._decodefilterpats, filename, data)
668 return self._filter(self._decodefilterpats, filename, data)
669
669
670 def transaction(self, desc):
670 def transaction(self, desc):
671 tr = self._transref and self._transref() or None
671 tr = self._transref and self._transref() or None
672 if tr and tr.running():
672 if tr and tr.running():
673 return tr.nest()
673 return tr.nest()
674
674
675 # abort here if the journal already exists
675 # abort here if the journal already exists
676 if os.path.exists(self.sjoin("journal")):
676 if os.path.exists(self.sjoin("journal")):
677 raise error.RepoError(
677 raise error.RepoError(
678 _("abandoned transaction found - run hg recover"))
678 _("abandoned transaction found - run hg recover"))
679
679
680 # save dirstate for rollback
680 # save dirstate for rollback
681 try:
681 try:
682 ds = self.opener("dirstate").read()
682 ds = self.opener("dirstate").read()
683 except IOError:
683 except IOError:
684 ds = ""
684 ds = ""
685 self.opener("journal.dirstate", "w").write(ds)
685 self.opener("journal.dirstate", "w").write(ds)
686 self.opener("journal.branch", "w").write(
686 self.opener("journal.branch", "w").write(
687 encoding.fromlocal(self.dirstate.branch()))
687 encoding.fromlocal(self.dirstate.branch()))
688 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
688 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
689
689
690 renames = [(self.sjoin("journal"), self.sjoin("undo")),
690 renames = [(self.sjoin("journal"), self.sjoin("undo")),
691 (self.join("journal.dirstate"), self.join("undo.dirstate")),
691 (self.join("journal.dirstate"), self.join("undo.dirstate")),
692 (self.join("journal.branch"), self.join("undo.branch")),
692 (self.join("journal.branch"), self.join("undo.branch")),
693 (self.join("journal.desc"), self.join("undo.desc"))]
693 (self.join("journal.desc"), self.join("undo.desc"))]
694 tr = transaction.transaction(self.ui.warn, self.sopener,
694 tr = transaction.transaction(self.ui.warn, self.sopener,
695 self.sjoin("journal"),
695 self.sjoin("journal"),
696 aftertrans(renames),
696 aftertrans(renames),
697 self.store.createmode)
697 self.store.createmode)
698 self._transref = weakref.ref(tr)
698 self._transref = weakref.ref(tr)
699 return tr
699 return tr
700
700
701 def recover(self):
701 def recover(self):
702 lock = self.lock()
702 lock = self.lock()
703 try:
703 try:
704 if os.path.exists(self.sjoin("journal")):
704 if os.path.exists(self.sjoin("journal")):
705 self.ui.status(_("rolling back interrupted transaction\n"))
705 self.ui.status(_("rolling back interrupted transaction\n"))
706 transaction.rollback(self.sopener, self.sjoin("journal"),
706 transaction.rollback(self.sopener, self.sjoin("journal"),
707 self.ui.warn)
707 self.ui.warn)
708 self.invalidate()
708 self.invalidate()
709 return True
709 return True
710 else:
710 else:
711 self.ui.warn(_("no interrupted transaction available\n"))
711 self.ui.warn(_("no interrupted transaction available\n"))
712 return False
712 return False
713 finally:
713 finally:
714 lock.release()
714 lock.release()
715
715
716 def rollback(self, dryrun=False):
716 def rollback(self, dryrun=False):
717 wlock = lock = None
717 wlock = lock = None
718 try:
718 try:
719 wlock = self.wlock()
719 wlock = self.wlock()
720 lock = self.lock()
720 lock = self.lock()
721 if os.path.exists(self.sjoin("undo")):
721 if os.path.exists(self.sjoin("undo")):
722 try:
722 try:
723 args = self.opener("undo.desc", "r").read().splitlines()
723 args = self.opener("undo.desc", "r").read().splitlines()
724 if len(args) >= 3 and self.ui.verbose:
724 if len(args) >= 3 and self.ui.verbose:
725 desc = _("repository tip rolled back to revision %s"
725 desc = _("repository tip rolled back to revision %s"
726 " (undo %s: %s)\n") % (
726 " (undo %s: %s)\n") % (
727 int(args[0]) - 1, args[1], args[2])
727 int(args[0]) - 1, args[1], args[2])
728 elif len(args) >= 2:
728 elif len(args) >= 2:
729 desc = _("repository tip rolled back to revision %s"
729 desc = _("repository tip rolled back to revision %s"
730 " (undo %s)\n") % (
730 " (undo %s)\n") % (
731 int(args[0]) - 1, args[1])
731 int(args[0]) - 1, args[1])
732 except IOError:
732 except IOError:
733 desc = _("rolling back unknown transaction\n")
733 desc = _("rolling back unknown transaction\n")
734 self.ui.status(desc)
734 self.ui.status(desc)
735 if dryrun:
735 if dryrun:
736 return
736 return
737 transaction.rollback(self.sopener, self.sjoin("undo"),
737 transaction.rollback(self.sopener, self.sjoin("undo"),
738 self.ui.warn)
738 self.ui.warn)
739 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
739 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
740 if os.path.exists(self.join('undo.bookmarks')):
740 if os.path.exists(self.join('undo.bookmarks')):
741 util.rename(self.join('undo.bookmarks'),
741 util.rename(self.join('undo.bookmarks'),
742 self.join('bookmarks'))
742 self.join('bookmarks'))
743 try:
743 try:
744 branch = self.opener("undo.branch").read()
744 branch = self.opener("undo.branch").read()
745 self.dirstate.setbranch(branch)
745 self.dirstate.setbranch(branch)
746 except IOError:
746 except IOError:
747 self.ui.warn(_("named branch could not be reset, "
747 self.ui.warn(_("named branch could not be reset, "
748 "current branch is still: %s\n")
748 "current branch is still: %s\n")
749 % self.dirstate.branch())
749 % self.dirstate.branch())
750 self.invalidate()
750 self.invalidate()
751 self.dirstate.invalidate()
751 self.dirstate.invalidate()
752 self.destroyed()
752 self.destroyed()
753 parents = tuple([p.rev() for p in self.parents()])
753 parents = tuple([p.rev() for p in self.parents()])
754 if len(parents) > 1:
754 if len(parents) > 1:
755 self.ui.status(_("working directory now based on "
755 self.ui.status(_("working directory now based on "
756 "revisions %d and %d\n") % parents)
756 "revisions %d and %d\n") % parents)
757 else:
757 else:
758 self.ui.status(_("working directory now based on "
758 self.ui.status(_("working directory now based on "
759 "revision %d\n") % parents)
759 "revision %d\n") % parents)
760 else:
760 else:
761 self.ui.warn(_("no rollback information available\n"))
761 self.ui.warn(_("no rollback information available\n"))
762 return 1
762 return 1
763 finally:
763 finally:
764 release(lock, wlock)
764 release(lock, wlock)
765
765
766 def invalidatecaches(self):
766 def invalidatecaches(self):
767 self._tags = None
767 self._tags = None
768 self._tagtypes = None
768 self._tagtypes = None
769 self.nodetagscache = None
769 self.nodetagscache = None
770 self._branchcache = None # in UTF-8
770 self._branchcache = None # in UTF-8
771 self._branchcachetip = None
771 self._branchcachetip = None
772
772
773 def invalidate(self):
773 def invalidate(self):
774 for a in ("changelog", "manifest", "_bookmarks", "_bookmarkcurrent"):
774 for a in ("changelog", "manifest", "_bookmarks", "_bookmarkcurrent"):
775 if a in self.__dict__:
775 if a in self.__dict__:
776 delattr(self, a)
776 delattr(self, a)
777 self.invalidatecaches()
777 self.invalidatecaches()
778
778
779 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
779 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
780 try:
780 try:
781 l = lock.lock(lockname, 0, releasefn, desc=desc)
781 l = lock.lock(lockname, 0, releasefn, desc=desc)
782 except error.LockHeld, inst:
782 except error.LockHeld, inst:
783 if not wait:
783 if not wait:
784 raise
784 raise
785 self.ui.warn(_("waiting for lock on %s held by %r\n") %
785 self.ui.warn(_("waiting for lock on %s held by %r\n") %
786 (desc, inst.locker))
786 (desc, inst.locker))
787 # default to 600 seconds timeout
787 # default to 600 seconds timeout
788 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
788 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
789 releasefn, desc=desc)
789 releasefn, desc=desc)
790 if acquirefn:
790 if acquirefn:
791 acquirefn()
791 acquirefn()
792 return l
792 return l
793
793
794 def lock(self, wait=True):
794 def lock(self, wait=True):
795 '''Lock the repository store (.hg/store) and return a weak reference
795 '''Lock the repository store (.hg/store) and return a weak reference
796 to the lock. Use this before modifying the store (e.g. committing or
796 to the lock. Use this before modifying the store (e.g. committing or
797 stripping). If you are opening a transaction, get a lock as well.)'''
797 stripping). If you are opening a transaction, get a lock as well.)'''
798 l = self._lockref and self._lockref()
798 l = self._lockref and self._lockref()
799 if l is not None and l.held:
799 if l is not None and l.held:
800 l.lock()
800 l.lock()
801 return l
801 return l
802
802
803 l = self._lock(self.sjoin("lock"), wait, self.store.write,
803 l = self._lock(self.sjoin("lock"), wait, self.store.write,
804 self.invalidate, _('repository %s') % self.origroot)
804 self.invalidate, _('repository %s') % self.origroot)
805 self._lockref = weakref.ref(l)
805 self._lockref = weakref.ref(l)
806 return l
806 return l
807
807
808 def wlock(self, wait=True):
808 def wlock(self, wait=True):
809 '''Lock the non-store parts of the repository (everything under
809 '''Lock the non-store parts of the repository (everything under
810 .hg except .hg/store) and return a weak reference to the lock.
810 .hg except .hg/store) and return a weak reference to the lock.
811 Use this before modifying files in .hg.'''
811 Use this before modifying files in .hg.'''
812 l = self._wlockref and self._wlockref()
812 l = self._wlockref and self._wlockref()
813 if l is not None and l.held:
813 if l is not None and l.held:
814 l.lock()
814 l.lock()
815 return l
815 return l
816
816
817 l = self._lock(self.join("wlock"), wait, self.dirstate.write,
817 l = self._lock(self.join("wlock"), wait, self.dirstate.write,
818 self.dirstate.invalidate, _('working directory of %s') %
818 self.dirstate.invalidate, _('working directory of %s') %
819 self.origroot)
819 self.origroot)
820 self._wlockref = weakref.ref(l)
820 self._wlockref = weakref.ref(l)
821 return l
821 return l
822
822
823 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
823 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
824 """
824 """
825 commit an individual file as part of a larger transaction
825 commit an individual file as part of a larger transaction
826 """
826 """
827
827
828 fname = fctx.path()
828 fname = fctx.path()
829 text = fctx.data()
829 text = fctx.data()
830 flog = self.file(fname)
830 flog = self.file(fname)
831 fparent1 = manifest1.get(fname, nullid)
831 fparent1 = manifest1.get(fname, nullid)
832 fparent2 = fparent2o = manifest2.get(fname, nullid)
832 fparent2 = fparent2o = manifest2.get(fname, nullid)
833
833
834 meta = {}
834 meta = {}
835 copy = fctx.renamed()
835 copy = fctx.renamed()
836 if copy and copy[0] != fname:
836 if copy and copy[0] != fname:
837 # Mark the new revision of this file as a copy of another
837 # Mark the new revision of this file as a copy of another
838 # file. This copy data will effectively act as a parent
838 # file. This copy data will effectively act as a parent
839 # of this new revision. If this is a merge, the first
839 # of this new revision. If this is a merge, the first
840 # parent will be the nullid (meaning "look up the copy data")
840 # parent will be the nullid (meaning "look up the copy data")
841 # and the second one will be the other parent. For example:
841 # and the second one will be the other parent. For example:
842 #
842 #
843 # 0 --- 1 --- 3 rev1 changes file foo
843 # 0 --- 1 --- 3 rev1 changes file foo
844 # \ / rev2 renames foo to bar and changes it
844 # \ / rev2 renames foo to bar and changes it
845 # \- 2 -/ rev3 should have bar with all changes and
845 # \- 2 -/ rev3 should have bar with all changes and
846 # should record that bar descends from
846 # should record that bar descends from
847 # bar in rev2 and foo in rev1
847 # bar in rev2 and foo in rev1
848 #
848 #
849 # this allows this merge to succeed:
849 # this allows this merge to succeed:
850 #
850 #
851 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
851 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
852 # \ / merging rev3 and rev4 should use bar@rev2
852 # \ / merging rev3 and rev4 should use bar@rev2
853 # \- 2 --- 4 as the merge base
853 # \- 2 --- 4 as the merge base
854 #
854 #
855
855
856 cfname = copy[0]
856 cfname = copy[0]
857 crev = manifest1.get(cfname)
857 crev = manifest1.get(cfname)
858 newfparent = fparent2
858 newfparent = fparent2
859
859
860 if manifest2: # branch merge
860 if manifest2: # branch merge
861 if fparent2 == nullid or crev is None: # copied on remote side
861 if fparent2 == nullid or crev is None: # copied on remote side
862 if cfname in manifest2:
862 if cfname in manifest2:
863 crev = manifest2[cfname]
863 crev = manifest2[cfname]
864 newfparent = fparent1
864 newfparent = fparent1
865
865
866 # find source in nearest ancestor if we've lost track
866 # find source in nearest ancestor if we've lost track
867 if not crev:
867 if not crev:
868 self.ui.debug(" %s: searching for copy revision for %s\n" %
868 self.ui.debug(" %s: searching for copy revision for %s\n" %
869 (fname, cfname))
869 (fname, cfname))
870 for ancestor in self[None].ancestors():
870 for ancestor in self[None].ancestors():
871 if cfname in ancestor:
871 if cfname in ancestor:
872 crev = ancestor[cfname].filenode()
872 crev = ancestor[cfname].filenode()
873 break
873 break
874
874
875 if crev:
875 if crev:
876 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
876 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
877 meta["copy"] = cfname
877 meta["copy"] = cfname
878 meta["copyrev"] = hex(crev)
878 meta["copyrev"] = hex(crev)
879 fparent1, fparent2 = nullid, newfparent
879 fparent1, fparent2 = nullid, newfparent
880 else:
880 else:
881 self.ui.warn(_("warning: can't find ancestor for '%s' "
881 self.ui.warn(_("warning: can't find ancestor for '%s' "
882 "copied from '%s'!\n") % (fname, cfname))
882 "copied from '%s'!\n") % (fname, cfname))
883
883
884 elif fparent2 != nullid:
884 elif fparent2 != nullid:
885 # is one parent an ancestor of the other?
885 # is one parent an ancestor of the other?
886 fparentancestor = flog.ancestor(fparent1, fparent2)
886 fparentancestor = flog.ancestor(fparent1, fparent2)
887 if fparentancestor == fparent1:
887 if fparentancestor == fparent1:
888 fparent1, fparent2 = fparent2, nullid
888 fparent1, fparent2 = fparent2, nullid
889 elif fparentancestor == fparent2:
889 elif fparentancestor == fparent2:
890 fparent2 = nullid
890 fparent2 = nullid
891
891
892 # is the file changed?
892 # is the file changed?
893 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
893 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
894 changelist.append(fname)
894 changelist.append(fname)
895 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
895 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
896
896
897 # are just the flags changed during merge?
897 # are just the flags changed during merge?
898 if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
898 if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
899 changelist.append(fname)
899 changelist.append(fname)
900
900
901 return fparent1
901 return fparent1
902
902
903 def commit(self, text="", user=None, date=None, match=None, force=False,
903 def commit(self, text="", user=None, date=None, match=None, force=False,
904 editor=False, extra={}):
904 editor=False, extra={}):
905 """Add a new revision to current repository.
905 """Add a new revision to current repository.
906
906
907 Revision information is gathered from the working directory,
907 Revision information is gathered from the working directory,
908 match can be used to filter the committed files. If editor is
908 match can be used to filter the committed files. If editor is
909 supplied, it is called to get a commit message.
909 supplied, it is called to get a commit message.
910 """
910 """
911
911
912 def fail(f, msg):
912 def fail(f, msg):
913 raise util.Abort('%s: %s' % (f, msg))
913 raise util.Abort('%s: %s' % (f, msg))
914
914
915 if not match:
915 if not match:
916 match = matchmod.always(self.root, '')
916 match = matchmod.always(self.root, '')
917
917
918 if not force:
918 if not force:
919 vdirs = []
919 vdirs = []
920 match.dir = vdirs.append
920 match.dir = vdirs.append
921 match.bad = fail
921 match.bad = fail
922
922
923 wlock = self.wlock()
923 wlock = self.wlock()
924 try:
924 try:
925 wctx = self[None]
925 wctx = self[None]
926 merge = len(wctx.parents()) > 1
926 merge = len(wctx.parents()) > 1
927
927
928 if (not force and merge and match and
928 if (not force and merge and match and
929 (match.files() or match.anypats())):
929 (match.files() or match.anypats())):
930 raise util.Abort(_('cannot partially commit a merge '
930 raise util.Abort(_('cannot partially commit a merge '
931 '(do not specify files or patterns)'))
931 '(do not specify files or patterns)'))
932
932
933 changes = self.status(match=match, clean=force)
933 changes = self.status(match=match, clean=force)
934 if force:
934 if force:
935 changes[0].extend(changes[6]) # mq may commit unchanged files
935 changes[0].extend(changes[6]) # mq may commit unchanged files
936
936
937 # check subrepos
937 # check subrepos
938 subs = []
938 subs = []
939 removedsubs = set()
939 removedsubs = set()
940 for p in wctx.parents():
940 for p in wctx.parents():
941 removedsubs.update(s for s in p.substate if match(s))
941 removedsubs.update(s for s in p.substate if match(s))
942 for s in wctx.substate:
942 for s in wctx.substate:
943 removedsubs.discard(s)
943 removedsubs.discard(s)
944 if match(s) and wctx.sub(s).dirty():
944 if match(s) and wctx.sub(s).dirty():
945 subs.append(s)
945 subs.append(s)
946 if (subs or removedsubs):
946 if (subs or removedsubs):
947 if (not match('.hgsub') and
947 if (not match('.hgsub') and
948 '.hgsub' in (wctx.modified() + wctx.added())):
948 '.hgsub' in (wctx.modified() + wctx.added())):
949 raise util.Abort(_("can't commit subrepos without .hgsub"))
949 raise util.Abort(_("can't commit subrepos without .hgsub"))
950 if '.hgsubstate' not in changes[0]:
950 if '.hgsubstate' not in changes[0]:
951 changes[0].insert(0, '.hgsubstate')
951 changes[0].insert(0, '.hgsubstate')
952
952
953 if subs and not self.ui.configbool('ui', 'commitsubrepos', True):
953 if subs and not self.ui.configbool('ui', 'commitsubrepos', True):
954 changedsubs = [s for s in subs if wctx.sub(s).dirty(True)]
954 changedsubs = [s for s in subs if wctx.sub(s).dirty(True)]
955 if changedsubs:
955 if changedsubs:
956 raise util.Abort(_("uncommitted changes in subrepo %s")
956 raise util.Abort(_("uncommitted changes in subrepo %s")
957 % changedsubs[0])
957 % changedsubs[0])
958
958
959 # make sure all explicit patterns are matched
959 # make sure all explicit patterns are matched
960 if not force and match.files():
960 if not force and match.files():
961 matched = set(changes[0] + changes[1] + changes[2])
961 matched = set(changes[0] + changes[1] + changes[2])
962
962
963 for f in match.files():
963 for f in match.files():
964 if f == '.' or f in matched or f in wctx.substate:
964 if f == '.' or f in matched or f in wctx.substate:
965 continue
965 continue
966 if f in changes[3]: # missing
966 if f in changes[3]: # missing
967 fail(f, _('file not found!'))
967 fail(f, _('file not found!'))
968 if f in vdirs: # visited directory
968 if f in vdirs: # visited directory
969 d = f + '/'
969 d = f + '/'
970 for mf in matched:
970 for mf in matched:
971 if mf.startswith(d):
971 if mf.startswith(d):
972 break
972 break
973 else:
973 else:
974 fail(f, _("no match under directory!"))
974 fail(f, _("no match under directory!"))
975 elif f not in self.dirstate:
975 elif f not in self.dirstate:
976 fail(f, _("file not tracked!"))
976 fail(f, _("file not tracked!"))
977
977
978 if (not force and not extra.get("close") and not merge
978 if (not force and not extra.get("close") and not merge
979 and not (changes[0] or changes[1] or changes[2])
979 and not (changes[0] or changes[1] or changes[2])
980 and wctx.branch() == wctx.p1().branch()):
980 and wctx.branch() == wctx.p1().branch()):
981 return None
981 return None
982
982
983 ms = mergemod.mergestate(self)
983 ms = mergemod.mergestate(self)
984 for f in changes[0]:
984 for f in changes[0]:
985 if f in ms and ms[f] == 'u':
985 if f in ms and ms[f] == 'u':
986 raise util.Abort(_("unresolved merge conflicts "
986 raise util.Abort(_("unresolved merge conflicts "
987 "(see hg help resolve)"))
987 "(see hg help resolve)"))
988
988
989 cctx = context.workingctx(self, text, user, date, extra, changes)
989 cctx = context.workingctx(self, text, user, date, extra, changes)
990 if editor:
990 if editor:
991 cctx._text = editor(self, cctx, subs)
991 cctx._text = editor(self, cctx, subs)
992 edited = (text != cctx._text)
992 edited = (text != cctx._text)
993
993
994 # commit subs
994 # commit subs
995 if subs or removedsubs:
995 if subs or removedsubs:
996 state = wctx.substate.copy()
996 state = wctx.substate.copy()
997 for s in sorted(subs):
997 for s in sorted(subs):
998 sub = wctx.sub(s)
998 sub = wctx.sub(s)
999 self.ui.status(_('committing subrepository %s\n') %
999 self.ui.status(_('committing subrepository %s\n') %
1000 subrepo.subrelpath(sub))
1000 subrepo.subrelpath(sub))
1001 sr = sub.commit(cctx._text, user, date)
1001 sr = sub.commit(cctx._text, user, date)
1002 state[s] = (state[s][0], sr)
1002 state[s] = (state[s][0], sr)
1003 subrepo.writestate(self, state)
1003 subrepo.writestate(self, state)
1004
1004
1005 # Save commit message in case this transaction gets rolled back
1005 # Save commit message in case this transaction gets rolled back
1006 # (e.g. by a pretxncommit hook). Leave the content alone on
1006 # (e.g. by a pretxncommit hook). Leave the content alone on
1007 # the assumption that the user will use the same editor again.
1007 # the assumption that the user will use the same editor again.
1008 msgfile = self.opener('last-message.txt', 'wb')
1008 msgfile = self.opener('last-message.txt', 'wb')
1009 msgfile.write(cctx._text)
1009 msgfile.write(cctx._text)
1010 msgfile.close()
1010 msgfile.close()
1011
1011
1012 p1, p2 = self.dirstate.parents()
1012 p1, p2 = self.dirstate.parents()
1013 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
1013 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
1014 try:
1014 try:
1015 self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2)
1015 self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2)
1016 ret = self.commitctx(cctx, True)
1016 ret = self.commitctx(cctx, True)
1017 except:
1017 except:
1018 if edited:
1018 if edited:
1019 msgfn = self.pathto(msgfile.name[len(self.root)+1:])
1019 msgfn = self.pathto(msgfile.name[len(self.root)+1:])
1020 self.ui.write(
1020 self.ui.write(
1021 _('note: commit message saved in %s\n') % msgfn)
1021 _('note: commit message saved in %s\n') % msgfn)
1022 raise
1022 raise
1023
1023
1024 # update bookmarks, dirstate and mergestate
1024 # update bookmarks, dirstate and mergestate
1025 bookmarks.update(self, p1, ret)
1025 bookmarks.update(self, p1, ret)
1026 for f in changes[0] + changes[1]:
1026 for f in changes[0] + changes[1]:
1027 self.dirstate.normal(f)
1027 self.dirstate.normal(f)
1028 for f in changes[2]:
1028 for f in changes[2]:
1029 self.dirstate.forget(f)
1029 self.dirstate.forget(f)
1030 self.dirstate.setparents(ret)
1030 self.dirstate.setparents(ret)
1031 ms.reset()
1031 ms.reset()
1032 finally:
1032 finally:
1033 wlock.release()
1033 wlock.release()
1034
1034
1035 self.hook("commit", node=hex(ret), parent1=hookp1, parent2=hookp2)
1035 self.hook("commit", node=hex(ret), parent1=hookp1, parent2=hookp2)
1036 return ret
1036 return ret
1037
1037
1038 def commitctx(self, ctx, error=False):
1038 def commitctx(self, ctx, error=False):
1039 """Add a new revision to current repository.
1039 """Add a new revision to current repository.
1040 Revision information is passed via the context argument.
1040 Revision information is passed via the context argument.
1041 """
1041 """
1042
1042
1043 tr = lock = None
1043 tr = lock = None
1044 removed = list(ctx.removed())
1044 removed = list(ctx.removed())
1045 p1, p2 = ctx.p1(), ctx.p2()
1045 p1, p2 = ctx.p1(), ctx.p2()
1046 m1 = p1.manifest().copy()
1047 m2 = p2.manifest()
1048 user = ctx.user()
1046 user = ctx.user()
1049
1047
1050 lock = self.lock()
1048 lock = self.lock()
1051 try:
1049 try:
1052 tr = self.transaction("commit")
1050 tr = self.transaction("commit")
1053 trp = weakref.proxy(tr)
1051 trp = weakref.proxy(tr)
1054
1052
1055 # check in files
1053 if ctx.files():
1056 new = {}
1054 m1 = p1.manifest().copy()
1057 changed = []
1055 m2 = p2.manifest()
1058 linkrev = len(self)
1056
1059 for f in sorted(ctx.modified() + ctx.added()):
1057 # check in files
1060 self.ui.note(f + "\n")
1058 new = {}
1061 try:
1059 changed = []
1062 fctx = ctx[f]
1060 linkrev = len(self)
1063 new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
1061 for f in sorted(ctx.modified() + ctx.added()):
1064 changed)
1062 self.ui.note(f + "\n")
1065 m1.set(f, fctx.flags())
1063 try:
1066 except OSError, inst:
1064 fctx = ctx[f]
1067 self.ui.warn(_("trouble committing %s!\n") % f)
1065 new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
1068 raise
1066 changed)
1069 except IOError, inst:
1067 m1.set(f, fctx.flags())
1070 errcode = getattr(inst, 'errno', errno.ENOENT)
1068 except OSError, inst:
1071 if error or errcode and errcode != errno.ENOENT:
1072 self.ui.warn(_("trouble committing %s!\n") % f)
1069 self.ui.warn(_("trouble committing %s!\n") % f)
1073 raise
1070 raise
1074 else:
1071 except IOError, inst:
1075 removed.append(f)
1072 errcode = getattr(inst, 'errno', errno.ENOENT)
1073 if error or errcode and errcode != errno.ENOENT:
1074 self.ui.warn(_("trouble committing %s!\n") % f)
1075 raise
1076 else:
1077 removed.append(f)
1076
1078
1077 # update manifest
1079 # update manifest
1078 m1.update(new)
1080 m1.update(new)
1079 removed = [f for f in sorted(removed) if f in m1 or f in m2]
1081 removed = [f for f in sorted(removed) if f in m1 or f in m2]
1080 drop = [f for f in removed if f in m1]
1082 drop = [f for f in removed if f in m1]
1081 for f in drop:
1083 for f in drop:
1082 del m1[f]
1084 del m1[f]
1083 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
1085 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
1084 p2.manifestnode(), (new, drop))
1086 p2.manifestnode(), (new, drop))
1087 files = changed + removed
1088 else:
1089 mn = p1.manifestnode()
1090 files = []
1085
1091
1086 # update changelog
1092 # update changelog
1087 self.changelog.delayupdate()
1093 self.changelog.delayupdate()
1088 n = self.changelog.add(mn, changed + removed, ctx.description(),
1094 n = self.changelog.add(mn, files, ctx.description(),
1089 trp, p1.node(), p2.node(),
1095 trp, p1.node(), p2.node(),
1090 user, ctx.date(), ctx.extra().copy())
1096 user, ctx.date(), ctx.extra().copy())
1091 p = lambda: self.changelog.writepending() and self.root or ""
1097 p = lambda: self.changelog.writepending() and self.root or ""
1092 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
1098 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
1093 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
1099 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
1094 parent2=xp2, pending=p)
1100 parent2=xp2, pending=p)
1095 self.changelog.finalize(trp)
1101 self.changelog.finalize(trp)
1096 tr.close()
1102 tr.close()
1097
1103
1098 if self._branchcache:
1104 if self._branchcache:
1099 self.updatebranchcache()
1105 self.updatebranchcache()
1100 return n
1106 return n
1101 finally:
1107 finally:
1102 if tr:
1108 if tr:
1103 tr.release()
1109 tr.release()
1104 lock.release()
1110 lock.release()
1105
1111
1106 def destroyed(self):
1112 def destroyed(self):
1107 '''Inform the repository that nodes have been destroyed.
1113 '''Inform the repository that nodes have been destroyed.
1108 Intended for use by strip and rollback, so there's a common
1114 Intended for use by strip and rollback, so there's a common
1109 place for anything that has to be done after destroying history.'''
1115 place for anything that has to be done after destroying history.'''
1110 # XXX it might be nice if we could take the list of destroyed
1116 # XXX it might be nice if we could take the list of destroyed
1111 # nodes, but I don't see an easy way for rollback() to do that
1117 # nodes, but I don't see an easy way for rollback() to do that
1112
1118
1113 # Ensure the persistent tag cache is updated. Doing it now
1119 # Ensure the persistent tag cache is updated. Doing it now
1114 # means that the tag cache only has to worry about destroyed
1120 # means that the tag cache only has to worry about destroyed
1115 # heads immediately after a strip/rollback. That in turn
1121 # heads immediately after a strip/rollback. That in turn
1116 # guarantees that "cachetip == currenttip" (comparing both rev
1122 # guarantees that "cachetip == currenttip" (comparing both rev
1117 # and node) always means no nodes have been added or destroyed.
1123 # and node) always means no nodes have been added or destroyed.
1118
1124
1119 # XXX this is suboptimal when qrefresh'ing: we strip the current
1125 # XXX this is suboptimal when qrefresh'ing: we strip the current
1120 # head, refresh the tag cache, then immediately add a new head.
1126 # head, refresh the tag cache, then immediately add a new head.
1121 # But I think doing it this way is necessary for the "instant
1127 # But I think doing it this way is necessary for the "instant
1122 # tag cache retrieval" case to work.
1128 # tag cache retrieval" case to work.
1123 self.invalidatecaches()
1129 self.invalidatecaches()
1124
1130
1125 def walk(self, match, node=None):
1131 def walk(self, match, node=None):
1126 '''
1132 '''
1127 walk recursively through the directory tree or a given
1133 walk recursively through the directory tree or a given
1128 changeset, finding all files matched by the match
1134 changeset, finding all files matched by the match
1129 function
1135 function
1130 '''
1136 '''
1131 return self[node].walk(match)
1137 return self[node].walk(match)
1132
1138
1133 def status(self, node1='.', node2=None, match=None,
1139 def status(self, node1='.', node2=None, match=None,
1134 ignored=False, clean=False, unknown=False,
1140 ignored=False, clean=False, unknown=False,
1135 listsubrepos=False):
1141 listsubrepos=False):
1136 """return status of files between two nodes or node and working directory
1142 """return status of files between two nodes or node and working directory
1137
1143
1138 If node1 is None, use the first dirstate parent instead.
1144 If node1 is None, use the first dirstate parent instead.
1139 If node2 is None, compare node1 with working directory.
1145 If node2 is None, compare node1 with working directory.
1140 """
1146 """
1141
1147
1142 def mfmatches(ctx):
1148 def mfmatches(ctx):
1143 mf = ctx.manifest().copy()
1149 mf = ctx.manifest().copy()
1144 for fn in mf.keys():
1150 for fn in mf.keys():
1145 if not match(fn):
1151 if not match(fn):
1146 del mf[fn]
1152 del mf[fn]
1147 return mf
1153 return mf
1148
1154
1149 if isinstance(node1, context.changectx):
1155 if isinstance(node1, context.changectx):
1150 ctx1 = node1
1156 ctx1 = node1
1151 else:
1157 else:
1152 ctx1 = self[node1]
1158 ctx1 = self[node1]
1153 if isinstance(node2, context.changectx):
1159 if isinstance(node2, context.changectx):
1154 ctx2 = node2
1160 ctx2 = node2
1155 else:
1161 else:
1156 ctx2 = self[node2]
1162 ctx2 = self[node2]
1157
1163
1158 working = ctx2.rev() is None
1164 working = ctx2.rev() is None
1159 parentworking = working and ctx1 == self['.']
1165 parentworking = working and ctx1 == self['.']
1160 match = match or matchmod.always(self.root, self.getcwd())
1166 match = match or matchmod.always(self.root, self.getcwd())
1161 listignored, listclean, listunknown = ignored, clean, unknown
1167 listignored, listclean, listunknown = ignored, clean, unknown
1162
1168
1163 # load earliest manifest first for caching reasons
1169 # load earliest manifest first for caching reasons
1164 if not working and ctx2.rev() < ctx1.rev():
1170 if not working and ctx2.rev() < ctx1.rev():
1165 ctx2.manifest()
1171 ctx2.manifest()
1166
1172
1167 if not parentworking:
1173 if not parentworking:
1168 def bad(f, msg):
1174 def bad(f, msg):
1169 if f not in ctx1:
1175 if f not in ctx1:
1170 self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
1176 self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
1171 match.bad = bad
1177 match.bad = bad
1172
1178
1173 if working: # we need to scan the working dir
1179 if working: # we need to scan the working dir
1174 subrepos = []
1180 subrepos = []
1175 if '.hgsub' in self.dirstate:
1181 if '.hgsub' in self.dirstate:
1176 subrepos = ctx1.substate.keys()
1182 subrepos = ctx1.substate.keys()
1177 s = self.dirstate.status(match, subrepos, listignored,
1183 s = self.dirstate.status(match, subrepos, listignored,
1178 listclean, listunknown)
1184 listclean, listunknown)
1179 cmp, modified, added, removed, deleted, unknown, ignored, clean = s
1185 cmp, modified, added, removed, deleted, unknown, ignored, clean = s
1180
1186
1181 # check for any possibly clean files
1187 # check for any possibly clean files
1182 if parentworking and cmp:
1188 if parentworking and cmp:
1183 fixup = []
1189 fixup = []
1184 # do a full compare of any files that might have changed
1190 # do a full compare of any files that might have changed
1185 for f in sorted(cmp):
1191 for f in sorted(cmp):
1186 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
1192 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
1187 or ctx1[f].cmp(ctx2[f])):
1193 or ctx1[f].cmp(ctx2[f])):
1188 modified.append(f)
1194 modified.append(f)
1189 else:
1195 else:
1190 fixup.append(f)
1196 fixup.append(f)
1191
1197
1192 # update dirstate for files that are actually clean
1198 # update dirstate for files that are actually clean
1193 if fixup:
1199 if fixup:
1194 if listclean:
1200 if listclean:
1195 clean += fixup
1201 clean += fixup
1196
1202
1197 try:
1203 try:
1198 # updating the dirstate is optional
1204 # updating the dirstate is optional
1199 # so we don't wait on the lock
1205 # so we don't wait on the lock
1200 wlock = self.wlock(False)
1206 wlock = self.wlock(False)
1201 try:
1207 try:
1202 for f in fixup:
1208 for f in fixup:
1203 self.dirstate.normal(f)
1209 self.dirstate.normal(f)
1204 finally:
1210 finally:
1205 wlock.release()
1211 wlock.release()
1206 except error.LockError:
1212 except error.LockError:
1207 pass
1213 pass
1208
1214
1209 if not parentworking:
1215 if not parentworking:
1210 mf1 = mfmatches(ctx1)
1216 mf1 = mfmatches(ctx1)
1211 if working:
1217 if working:
1212 # we are comparing working dir against non-parent
1218 # we are comparing working dir against non-parent
1213 # generate a pseudo-manifest for the working dir
1219 # generate a pseudo-manifest for the working dir
1214 mf2 = mfmatches(self['.'])
1220 mf2 = mfmatches(self['.'])
1215 for f in cmp + modified + added:
1221 for f in cmp + modified + added:
1216 mf2[f] = None
1222 mf2[f] = None
1217 mf2.set(f, ctx2.flags(f))
1223 mf2.set(f, ctx2.flags(f))
1218 for f in removed:
1224 for f in removed:
1219 if f in mf2:
1225 if f in mf2:
1220 del mf2[f]
1226 del mf2[f]
1221 else:
1227 else:
1222 # we are comparing two revisions
1228 # we are comparing two revisions
1223 deleted, unknown, ignored = [], [], []
1229 deleted, unknown, ignored = [], [], []
1224 mf2 = mfmatches(ctx2)
1230 mf2 = mfmatches(ctx2)
1225
1231
1226 modified, added, clean = [], [], []
1232 modified, added, clean = [], [], []
1227 for fn in mf2:
1233 for fn in mf2:
1228 if fn in mf1:
1234 if fn in mf1:
1229 if (fn not in deleted and
1235 if (fn not in deleted and
1230 (mf1.flags(fn) != mf2.flags(fn) or
1236 (mf1.flags(fn) != mf2.flags(fn) or
1231 (mf1[fn] != mf2[fn] and
1237 (mf1[fn] != mf2[fn] and
1232 (mf2[fn] or ctx1[fn].cmp(ctx2[fn]))))):
1238 (mf2[fn] or ctx1[fn].cmp(ctx2[fn]))))):
1233 modified.append(fn)
1239 modified.append(fn)
1234 elif listclean:
1240 elif listclean:
1235 clean.append(fn)
1241 clean.append(fn)
1236 del mf1[fn]
1242 del mf1[fn]
1237 elif fn not in deleted:
1243 elif fn not in deleted:
1238 added.append(fn)
1244 added.append(fn)
1239 removed = mf1.keys()
1245 removed = mf1.keys()
1240
1246
1241 r = modified, added, removed, deleted, unknown, ignored, clean
1247 r = modified, added, removed, deleted, unknown, ignored, clean
1242
1248
1243 if listsubrepos:
1249 if listsubrepos:
1244 for subpath, sub in subrepo.itersubrepos(ctx1, ctx2):
1250 for subpath, sub in subrepo.itersubrepos(ctx1, ctx2):
1245 if working:
1251 if working:
1246 rev2 = None
1252 rev2 = None
1247 else:
1253 else:
1248 rev2 = ctx2.substate[subpath][1]
1254 rev2 = ctx2.substate[subpath][1]
1249 try:
1255 try:
1250 submatch = matchmod.narrowmatcher(subpath, match)
1256 submatch = matchmod.narrowmatcher(subpath, match)
1251 s = sub.status(rev2, match=submatch, ignored=listignored,
1257 s = sub.status(rev2, match=submatch, ignored=listignored,
1252 clean=listclean, unknown=listunknown,
1258 clean=listclean, unknown=listunknown,
1253 listsubrepos=True)
1259 listsubrepos=True)
1254 for rfiles, sfiles in zip(r, s):
1260 for rfiles, sfiles in zip(r, s):
1255 rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
1261 rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
1256 except error.LookupError:
1262 except error.LookupError:
1257 self.ui.status(_("skipping missing subrepository: %s\n")
1263 self.ui.status(_("skipping missing subrepository: %s\n")
1258 % subpath)
1264 % subpath)
1259
1265
1260 for l in r:
1266 for l in r:
1261 l.sort()
1267 l.sort()
1262 return r
1268 return r
1263
1269
1264 def heads(self, start=None):
1270 def heads(self, start=None):
1265 heads = self.changelog.heads(start)
1271 heads = self.changelog.heads(start)
1266 # sort the output in rev descending order
1272 # sort the output in rev descending order
1267 return sorted(heads, key=self.changelog.rev, reverse=True)
1273 return sorted(heads, key=self.changelog.rev, reverse=True)
1268
1274
1269 def branchheads(self, branch=None, start=None, closed=False):
1275 def branchheads(self, branch=None, start=None, closed=False):
1270 '''return a (possibly filtered) list of heads for the given branch
1276 '''return a (possibly filtered) list of heads for the given branch
1271
1277
1272 Heads are returned in topological order, from newest to oldest.
1278 Heads are returned in topological order, from newest to oldest.
1273 If branch is None, use the dirstate branch.
1279 If branch is None, use the dirstate branch.
1274 If start is not None, return only heads reachable from start.
1280 If start is not None, return only heads reachable from start.
1275 If closed is True, return heads that are marked as closed as well.
1281 If closed is True, return heads that are marked as closed as well.
1276 '''
1282 '''
1277 if branch is None:
1283 if branch is None:
1278 branch = self[None].branch()
1284 branch = self[None].branch()
1279 branches = self.branchmap()
1285 branches = self.branchmap()
1280 if branch not in branches:
1286 if branch not in branches:
1281 return []
1287 return []
1282 # the cache returns heads ordered lowest to highest
1288 # the cache returns heads ordered lowest to highest
1283 bheads = list(reversed(branches[branch]))
1289 bheads = list(reversed(branches[branch]))
1284 if start is not None:
1290 if start is not None:
1285 # filter out the heads that cannot be reached from startrev
1291 # filter out the heads that cannot be reached from startrev
1286 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
1292 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
1287 bheads = [h for h in bheads if h in fbheads]
1293 bheads = [h for h in bheads if h in fbheads]
1288 if not closed:
1294 if not closed:
1289 bheads = [h for h in bheads if
1295 bheads = [h for h in bheads if
1290 ('close' not in self.changelog.read(h)[5])]
1296 ('close' not in self.changelog.read(h)[5])]
1291 return bheads
1297 return bheads
1292
1298
1293 def branches(self, nodes):
1299 def branches(self, nodes):
1294 if not nodes:
1300 if not nodes:
1295 nodes = [self.changelog.tip()]
1301 nodes = [self.changelog.tip()]
1296 b = []
1302 b = []
1297 for n in nodes:
1303 for n in nodes:
1298 t = n
1304 t = n
1299 while 1:
1305 while 1:
1300 p = self.changelog.parents(n)
1306 p = self.changelog.parents(n)
1301 if p[1] != nullid or p[0] == nullid:
1307 if p[1] != nullid or p[0] == nullid:
1302 b.append((t, n, p[0], p[1]))
1308 b.append((t, n, p[0], p[1]))
1303 break
1309 break
1304 n = p[0]
1310 n = p[0]
1305 return b
1311 return b
1306
1312
1307 def between(self, pairs):
1313 def between(self, pairs):
1308 r = []
1314 r = []
1309
1315
1310 for top, bottom in pairs:
1316 for top, bottom in pairs:
1311 n, l, i = top, [], 0
1317 n, l, i = top, [], 0
1312 f = 1
1318 f = 1
1313
1319
1314 while n != bottom and n != nullid:
1320 while n != bottom and n != nullid:
1315 p = self.changelog.parents(n)[0]
1321 p = self.changelog.parents(n)[0]
1316 if i == f:
1322 if i == f:
1317 l.append(n)
1323 l.append(n)
1318 f = f * 2
1324 f = f * 2
1319 n = p
1325 n = p
1320 i += 1
1326 i += 1
1321
1327
1322 r.append(l)
1328 r.append(l)
1323
1329
1324 return r
1330 return r
1325
1331
1326 def pull(self, remote, heads=None, force=False):
1332 def pull(self, remote, heads=None, force=False):
1327 lock = self.lock()
1333 lock = self.lock()
1328 try:
1334 try:
1329 tmp = discovery.findcommonincoming(self, remote, heads=heads,
1335 tmp = discovery.findcommonincoming(self, remote, heads=heads,
1330 force=force)
1336 force=force)
1331 common, fetch, rheads = tmp
1337 common, fetch, rheads = tmp
1332 if not fetch:
1338 if not fetch:
1333 self.ui.status(_("no changes found\n"))
1339 self.ui.status(_("no changes found\n"))
1334 result = 0
1340 result = 0
1335 else:
1341 else:
1336 if heads is None and list(common) == [nullid]:
1342 if heads is None and list(common) == [nullid]:
1337 self.ui.status(_("requesting all changes\n"))
1343 self.ui.status(_("requesting all changes\n"))
1338 elif heads is None and remote.capable('changegroupsubset'):
1344 elif heads is None and remote.capable('changegroupsubset'):
1339 # issue1320, avoid a race if remote changed after discovery
1345 # issue1320, avoid a race if remote changed after discovery
1340 heads = rheads
1346 heads = rheads
1341
1347
1342 if remote.capable('getbundle'):
1348 if remote.capable('getbundle'):
1343 cg = remote.getbundle('pull', common=common,
1349 cg = remote.getbundle('pull', common=common,
1344 heads=heads or rheads)
1350 heads=heads or rheads)
1345 elif heads is None:
1351 elif heads is None:
1346 cg = remote.changegroup(fetch, 'pull')
1352 cg = remote.changegroup(fetch, 'pull')
1347 elif not remote.capable('changegroupsubset'):
1353 elif not remote.capable('changegroupsubset'):
1348 raise util.Abort(_("partial pull cannot be done because "
1354 raise util.Abort(_("partial pull cannot be done because "
1349 "other repository doesn't support "
1355 "other repository doesn't support "
1350 "changegroupsubset."))
1356 "changegroupsubset."))
1351 else:
1357 else:
1352 cg = remote.changegroupsubset(fetch, heads, 'pull')
1358 cg = remote.changegroupsubset(fetch, heads, 'pull')
1353 result = self.addchangegroup(cg, 'pull', remote.url(),
1359 result = self.addchangegroup(cg, 'pull', remote.url(),
1354 lock=lock)
1360 lock=lock)
1355 finally:
1361 finally:
1356 lock.release()
1362 lock.release()
1357
1363
1358 return result
1364 return result
1359
1365
1360 def checkpush(self, force, revs):
1366 def checkpush(self, force, revs):
1361 """Extensions can override this function if additional checks have
1367 """Extensions can override this function if additional checks have
1362 to be performed before pushing, or call it if they override push
1368 to be performed before pushing, or call it if they override push
1363 command.
1369 command.
1364 """
1370 """
1365 pass
1371 pass
1366
1372
1367 def push(self, remote, force=False, revs=None, newbranch=False):
1373 def push(self, remote, force=False, revs=None, newbranch=False):
1368 '''Push outgoing changesets (limited by revs) from the current
1374 '''Push outgoing changesets (limited by revs) from the current
1369 repository to remote. Return an integer:
1375 repository to remote. Return an integer:
1370 - 0 means HTTP error *or* nothing to push
1376 - 0 means HTTP error *or* nothing to push
1371 - 1 means we pushed and remote head count is unchanged *or*
1377 - 1 means we pushed and remote head count is unchanged *or*
1372 we have outgoing changesets but refused to push
1378 we have outgoing changesets but refused to push
1373 - other values as described by addchangegroup()
1379 - other values as described by addchangegroup()
1374 '''
1380 '''
1375 # there are two ways to push to remote repo:
1381 # there are two ways to push to remote repo:
1376 #
1382 #
1377 # addchangegroup assumes local user can lock remote
1383 # addchangegroup assumes local user can lock remote
1378 # repo (local filesystem, old ssh servers).
1384 # repo (local filesystem, old ssh servers).
1379 #
1385 #
1380 # unbundle assumes local user cannot lock remote repo (new ssh
1386 # unbundle assumes local user cannot lock remote repo (new ssh
1381 # servers, http servers).
1387 # servers, http servers).
1382
1388
1383 self.checkpush(force, revs)
1389 self.checkpush(force, revs)
1384 lock = None
1390 lock = None
1385 unbundle = remote.capable('unbundle')
1391 unbundle = remote.capable('unbundle')
1386 if not unbundle:
1392 if not unbundle:
1387 lock = remote.lock()
1393 lock = remote.lock()
1388 try:
1394 try:
1389 cg, remote_heads = discovery.prepush(self, remote, force, revs,
1395 cg, remote_heads = discovery.prepush(self, remote, force, revs,
1390 newbranch)
1396 newbranch)
1391 ret = remote_heads
1397 ret = remote_heads
1392 if cg is not None:
1398 if cg is not None:
1393 if unbundle:
1399 if unbundle:
1394 # local repo finds heads on server, finds out what
1400 # local repo finds heads on server, finds out what
1395 # revs it must push. once revs transferred, if server
1401 # revs it must push. once revs transferred, if server
1396 # finds it has different heads (someone else won
1402 # finds it has different heads (someone else won
1397 # commit/push race), server aborts.
1403 # commit/push race), server aborts.
1398 if force:
1404 if force:
1399 remote_heads = ['force']
1405 remote_heads = ['force']
1400 # ssh: return remote's addchangegroup()
1406 # ssh: return remote's addchangegroup()
1401 # http: return remote's addchangegroup() or 0 for error
1407 # http: return remote's addchangegroup() or 0 for error
1402 ret = remote.unbundle(cg, remote_heads, 'push')
1408 ret = remote.unbundle(cg, remote_heads, 'push')
1403 else:
1409 else:
1404 # we return an integer indicating remote head count change
1410 # we return an integer indicating remote head count change
1405 ret = remote.addchangegroup(cg, 'push', self.url(),
1411 ret = remote.addchangegroup(cg, 'push', self.url(),
1406 lock=lock)
1412 lock=lock)
1407 finally:
1413 finally:
1408 if lock is not None:
1414 if lock is not None:
1409 lock.release()
1415 lock.release()
1410
1416
1411 self.ui.debug("checking for updated bookmarks\n")
1417 self.ui.debug("checking for updated bookmarks\n")
1412 rb = remote.listkeys('bookmarks')
1418 rb = remote.listkeys('bookmarks')
1413 for k in rb.keys():
1419 for k in rb.keys():
1414 if k in self._bookmarks:
1420 if k in self._bookmarks:
1415 nr, nl = rb[k], hex(self._bookmarks[k])
1421 nr, nl = rb[k], hex(self._bookmarks[k])
1416 if nr in self:
1422 if nr in self:
1417 cr = self[nr]
1423 cr = self[nr]
1418 cl = self[nl]
1424 cl = self[nl]
1419 if cl in cr.descendants():
1425 if cl in cr.descendants():
1420 r = remote.pushkey('bookmarks', k, nr, nl)
1426 r = remote.pushkey('bookmarks', k, nr, nl)
1421 if r:
1427 if r:
1422 self.ui.status(_("updating bookmark %s\n") % k)
1428 self.ui.status(_("updating bookmark %s\n") % k)
1423 else:
1429 else:
1424 self.ui.warn(_('updating bookmark %s'
1430 self.ui.warn(_('updating bookmark %s'
1425 ' failed!\n') % k)
1431 ' failed!\n') % k)
1426
1432
1427 return ret
1433 return ret
1428
1434
1429 def changegroupinfo(self, nodes, source):
1435 def changegroupinfo(self, nodes, source):
1430 if self.ui.verbose or source == 'bundle':
1436 if self.ui.verbose or source == 'bundle':
1431 self.ui.status(_("%d changesets found\n") % len(nodes))
1437 self.ui.status(_("%d changesets found\n") % len(nodes))
1432 if self.ui.debugflag:
1438 if self.ui.debugflag:
1433 self.ui.debug("list of changesets:\n")
1439 self.ui.debug("list of changesets:\n")
1434 for node in nodes:
1440 for node in nodes:
1435 self.ui.debug("%s\n" % hex(node))
1441 self.ui.debug("%s\n" % hex(node))
1436
1442
1437 def changegroupsubset(self, bases, heads, source):
1443 def changegroupsubset(self, bases, heads, source):
1438 """Compute a changegroup consisting of all the nodes that are
1444 """Compute a changegroup consisting of all the nodes that are
1439 descendents of any of the bases and ancestors of any of the heads.
1445 descendents of any of the bases and ancestors of any of the heads.
1440 Return a chunkbuffer object whose read() method will return
1446 Return a chunkbuffer object whose read() method will return
1441 successive changegroup chunks.
1447 successive changegroup chunks.
1442
1448
1443 It is fairly complex as determining which filenodes and which
1449 It is fairly complex as determining which filenodes and which
1444 manifest nodes need to be included for the changeset to be complete
1450 manifest nodes need to be included for the changeset to be complete
1445 is non-trivial.
1451 is non-trivial.
1446
1452
1447 Another wrinkle is doing the reverse, figuring out which changeset in
1453 Another wrinkle is doing the reverse, figuring out which changeset in
1448 the changegroup a particular filenode or manifestnode belongs to.
1454 the changegroup a particular filenode or manifestnode belongs to.
1449 """
1455 """
1450 cl = self.changelog
1456 cl = self.changelog
1451 if not bases:
1457 if not bases:
1452 bases = [nullid]
1458 bases = [nullid]
1453 csets, bases, heads = cl.nodesbetween(bases, heads)
1459 csets, bases, heads = cl.nodesbetween(bases, heads)
1454 # We assume that all ancestors of bases are known
1460 # We assume that all ancestors of bases are known
1455 common = set(cl.ancestors(*[cl.rev(n) for n in bases]))
1461 common = set(cl.ancestors(*[cl.rev(n) for n in bases]))
1456 return self._changegroupsubset(common, csets, heads, source)
1462 return self._changegroupsubset(common, csets, heads, source)
1457
1463
1458 def getbundle(self, source, heads=None, common=None):
1464 def getbundle(self, source, heads=None, common=None):
1459 """Like changegroupsubset, but returns the set difference between the
1465 """Like changegroupsubset, but returns the set difference between the
1460 ancestors of heads and the ancestors common.
1466 ancestors of heads and the ancestors common.
1461
1467
1462 If heads is None, use the local heads. If common is None, use [nullid].
1468 If heads is None, use the local heads. If common is None, use [nullid].
1463
1469
1464 The nodes in common might not all be known locally due to the way the
1470 The nodes in common might not all be known locally due to the way the
1465 current discovery protocol works.
1471 current discovery protocol works.
1466 """
1472 """
1467 cl = self.changelog
1473 cl = self.changelog
1468 if common:
1474 if common:
1469 nm = cl.nodemap
1475 nm = cl.nodemap
1470 common = [n for n in common if n in nm]
1476 common = [n for n in common if n in nm]
1471 else:
1477 else:
1472 common = [nullid]
1478 common = [nullid]
1473 if not heads:
1479 if not heads:
1474 heads = cl.heads()
1480 heads = cl.heads()
1475 common, missing = cl.findcommonmissing(common, heads)
1481 common, missing = cl.findcommonmissing(common, heads)
1476 if not missing:
1482 if not missing:
1477 return None
1483 return None
1478 return self._changegroupsubset(common, missing, heads, source)
1484 return self._changegroupsubset(common, missing, heads, source)
1479
1485
1480 def _changegroupsubset(self, commonrevs, csets, heads, source):
1486 def _changegroupsubset(self, commonrevs, csets, heads, source):
1481
1487
1482 cl = self.changelog
1488 cl = self.changelog
1483 mf = self.manifest
1489 mf = self.manifest
1484 mfs = {} # needed manifests
1490 mfs = {} # needed manifests
1485 fnodes = {} # needed file nodes
1491 fnodes = {} # needed file nodes
1486 changedfiles = set()
1492 changedfiles = set()
1487 fstate = ['', {}]
1493 fstate = ['', {}]
1488 count = [0]
1494 count = [0]
1489
1495
1490 # can we go through the fast path ?
1496 # can we go through the fast path ?
1491 heads.sort()
1497 heads.sort()
1492 if heads == sorted(self.heads()):
1498 if heads == sorted(self.heads()):
1493 return self._changegroup(csets, source)
1499 return self._changegroup(csets, source)
1494
1500
1495 # slow path
1501 # slow path
1496 self.hook('preoutgoing', throw=True, source=source)
1502 self.hook('preoutgoing', throw=True, source=source)
1497 self.changegroupinfo(csets, source)
1503 self.changegroupinfo(csets, source)
1498
1504
1499 # filter any nodes that claim to be part of the known set
1505 # filter any nodes that claim to be part of the known set
1500 def prune(revlog, missing):
1506 def prune(revlog, missing):
1501 for n in missing:
1507 for n in missing:
1502 if revlog.linkrev(revlog.rev(n)) not in commonrevs:
1508 if revlog.linkrev(revlog.rev(n)) not in commonrevs:
1503 yield n
1509 yield n
1504
1510
1505 def lookup(revlog, x):
1511 def lookup(revlog, x):
1506 if revlog == cl:
1512 if revlog == cl:
1507 c = cl.read(x)
1513 c = cl.read(x)
1508 changedfiles.update(c[3])
1514 changedfiles.update(c[3])
1509 mfs.setdefault(c[0], x)
1515 mfs.setdefault(c[0], x)
1510 count[0] += 1
1516 count[0] += 1
1511 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1517 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1512 return x
1518 return x
1513 elif revlog == mf:
1519 elif revlog == mf:
1514 clnode = mfs[x]
1520 clnode = mfs[x]
1515 mdata = mf.readfast(x)
1521 mdata = mf.readfast(x)
1516 for f in changedfiles:
1522 for f in changedfiles:
1517 if f in mdata:
1523 if f in mdata:
1518 fnodes.setdefault(f, {}).setdefault(mdata[f], clnode)
1524 fnodes.setdefault(f, {}).setdefault(mdata[f], clnode)
1519 count[0] += 1
1525 count[0] += 1
1520 self.ui.progress(_('bundling'), count[0],
1526 self.ui.progress(_('bundling'), count[0],
1521 unit=_('manifests'), total=len(mfs))
1527 unit=_('manifests'), total=len(mfs))
1522 return mfs[x]
1528 return mfs[x]
1523 else:
1529 else:
1524 self.ui.progress(
1530 self.ui.progress(
1525 _('bundling'), count[0], item=fstate[0],
1531 _('bundling'), count[0], item=fstate[0],
1526 unit=_('files'), total=len(changedfiles))
1532 unit=_('files'), total=len(changedfiles))
1527 return fstate[1][x]
1533 return fstate[1][x]
1528
1534
1529 bundler = changegroup.bundle10(lookup)
1535 bundler = changegroup.bundle10(lookup)
1530
1536
1531 def gengroup():
1537 def gengroup():
1532 # Create a changenode group generator that will call our functions
1538 # Create a changenode group generator that will call our functions
1533 # back to lookup the owning changenode and collect information.
1539 # back to lookup the owning changenode and collect information.
1534 for chunk in cl.group(csets, bundler):
1540 for chunk in cl.group(csets, bundler):
1535 yield chunk
1541 yield chunk
1536 self.ui.progress(_('bundling'), None)
1542 self.ui.progress(_('bundling'), None)
1537
1543
1538 # Create a generator for the manifestnodes that calls our lookup
1544 # Create a generator for the manifestnodes that calls our lookup
1539 # and data collection functions back.
1545 # and data collection functions back.
1540 count[0] = 0
1546 count[0] = 0
1541 for chunk in mf.group(prune(mf, mfs), bundler):
1547 for chunk in mf.group(prune(mf, mfs), bundler):
1542 yield chunk
1548 yield chunk
1543 self.ui.progress(_('bundling'), None)
1549 self.ui.progress(_('bundling'), None)
1544
1550
1545 mfs.clear()
1551 mfs.clear()
1546
1552
1547 # Go through all our files in order sorted by name.
1553 # Go through all our files in order sorted by name.
1548 count[0] = 0
1554 count[0] = 0
1549 for fname in sorted(changedfiles):
1555 for fname in sorted(changedfiles):
1550 filerevlog = self.file(fname)
1556 filerevlog = self.file(fname)
1551 if not len(filerevlog):
1557 if not len(filerevlog):
1552 raise util.Abort(_("empty or missing revlog for %s") % fname)
1558 raise util.Abort(_("empty or missing revlog for %s") % fname)
1553 fstate[0] = fname
1559 fstate[0] = fname
1554 fstate[1] = fnodes.pop(fname, {})
1560 fstate[1] = fnodes.pop(fname, {})
1555 first = True
1561 first = True
1556
1562
1557 for chunk in filerevlog.group(prune(filerevlog, fstate[1]),
1563 for chunk in filerevlog.group(prune(filerevlog, fstate[1]),
1558 bundler):
1564 bundler):
1559 if first:
1565 if first:
1560 if chunk == bundler.close():
1566 if chunk == bundler.close():
1561 break
1567 break
1562 count[0] += 1
1568 count[0] += 1
1563 yield bundler.fileheader(fname)
1569 yield bundler.fileheader(fname)
1564 first = False
1570 first = False
1565 yield chunk
1571 yield chunk
1566 # Signal that no more groups are left.
1572 # Signal that no more groups are left.
1567 yield bundler.close()
1573 yield bundler.close()
1568 self.ui.progress(_('bundling'), None)
1574 self.ui.progress(_('bundling'), None)
1569
1575
1570 if csets:
1576 if csets:
1571 self.hook('outgoing', node=hex(csets[0]), source=source)
1577 self.hook('outgoing', node=hex(csets[0]), source=source)
1572
1578
1573 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1579 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1574
1580
1575 def changegroup(self, basenodes, source):
1581 def changegroup(self, basenodes, source):
1576 # to avoid a race we use changegroupsubset() (issue1320)
1582 # to avoid a race we use changegroupsubset() (issue1320)
1577 return self.changegroupsubset(basenodes, self.heads(), source)
1583 return self.changegroupsubset(basenodes, self.heads(), source)
1578
1584
1579 def _changegroup(self, nodes, source):
1585 def _changegroup(self, nodes, source):
1580 """Compute the changegroup of all nodes that we have that a recipient
1586 """Compute the changegroup of all nodes that we have that a recipient
1581 doesn't. Return a chunkbuffer object whose read() method will return
1587 doesn't. Return a chunkbuffer object whose read() method will return
1582 successive changegroup chunks.
1588 successive changegroup chunks.
1583
1589
1584 This is much easier than the previous function as we can assume that
1590 This is much easier than the previous function as we can assume that
1585 the recipient has any changenode we aren't sending them.
1591 the recipient has any changenode we aren't sending them.
1586
1592
1587 nodes is the set of nodes to send"""
1593 nodes is the set of nodes to send"""
1588
1594
1589 cl = self.changelog
1595 cl = self.changelog
1590 mf = self.manifest
1596 mf = self.manifest
1591 mfs = {}
1597 mfs = {}
1592 changedfiles = set()
1598 changedfiles = set()
1593 fstate = ['']
1599 fstate = ['']
1594 count = [0]
1600 count = [0]
1595
1601
1596 self.hook('preoutgoing', throw=True, source=source)
1602 self.hook('preoutgoing', throw=True, source=source)
1597 self.changegroupinfo(nodes, source)
1603 self.changegroupinfo(nodes, source)
1598
1604
1599 revset = set([cl.rev(n) for n in nodes])
1605 revset = set([cl.rev(n) for n in nodes])
1600
1606
1601 def gennodelst(log):
1607 def gennodelst(log):
1602 for r in log:
1608 for r in log:
1603 if log.linkrev(r) in revset:
1609 if log.linkrev(r) in revset:
1604 yield log.node(r)
1610 yield log.node(r)
1605
1611
1606 def lookup(revlog, x):
1612 def lookup(revlog, x):
1607 if revlog == cl:
1613 if revlog == cl:
1608 c = cl.read(x)
1614 c = cl.read(x)
1609 changedfiles.update(c[3])
1615 changedfiles.update(c[3])
1610 mfs.setdefault(c[0], x)
1616 mfs.setdefault(c[0], x)
1611 count[0] += 1
1617 count[0] += 1
1612 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1618 self.ui.progress(_('bundling'), count[0], unit=_('changesets'))
1613 return x
1619 return x
1614 elif revlog == mf:
1620 elif revlog == mf:
1615 count[0] += 1
1621 count[0] += 1
1616 self.ui.progress(_('bundling'), count[0],
1622 self.ui.progress(_('bundling'), count[0],
1617 unit=_('manifests'), total=len(mfs))
1623 unit=_('manifests'), total=len(mfs))
1618 return cl.node(revlog.linkrev(revlog.rev(x)))
1624 return cl.node(revlog.linkrev(revlog.rev(x)))
1619 else:
1625 else:
1620 self.ui.progress(
1626 self.ui.progress(
1621 _('bundling'), count[0], item=fstate[0],
1627 _('bundling'), count[0], item=fstate[0],
1622 total=len(changedfiles), unit=_('files'))
1628 total=len(changedfiles), unit=_('files'))
1623 return cl.node(revlog.linkrev(revlog.rev(x)))
1629 return cl.node(revlog.linkrev(revlog.rev(x)))
1624
1630
1625 bundler = changegroup.bundle10(lookup)
1631 bundler = changegroup.bundle10(lookup)
1626
1632
1627 def gengroup():
1633 def gengroup():
1628 '''yield a sequence of changegroup chunks (strings)'''
1634 '''yield a sequence of changegroup chunks (strings)'''
1629 # construct a list of all changed files
1635 # construct a list of all changed files
1630
1636
1631 for chunk in cl.group(nodes, bundler):
1637 for chunk in cl.group(nodes, bundler):
1632 yield chunk
1638 yield chunk
1633 self.ui.progress(_('bundling'), None)
1639 self.ui.progress(_('bundling'), None)
1634
1640
1635 count[0] = 0
1641 count[0] = 0
1636 for chunk in mf.group(gennodelst(mf), bundler):
1642 for chunk in mf.group(gennodelst(mf), bundler):
1637 yield chunk
1643 yield chunk
1638 self.ui.progress(_('bundling'), None)
1644 self.ui.progress(_('bundling'), None)
1639
1645
1640 count[0] = 0
1646 count[0] = 0
1641 for fname in sorted(changedfiles):
1647 for fname in sorted(changedfiles):
1642 filerevlog = self.file(fname)
1648 filerevlog = self.file(fname)
1643 if not len(filerevlog):
1649 if not len(filerevlog):
1644 raise util.Abort(_("empty or missing revlog for %s") % fname)
1650 raise util.Abort(_("empty or missing revlog for %s") % fname)
1645 fstate[0] = fname
1651 fstate[0] = fname
1646 first = True
1652 first = True
1647 for chunk in filerevlog.group(gennodelst(filerevlog), bundler):
1653 for chunk in filerevlog.group(gennodelst(filerevlog), bundler):
1648 if first:
1654 if first:
1649 if chunk == bundler.close():
1655 if chunk == bundler.close():
1650 break
1656 break
1651 count[0] += 1
1657 count[0] += 1
1652 yield bundler.fileheader(fname)
1658 yield bundler.fileheader(fname)
1653 first = False
1659 first = False
1654 yield chunk
1660 yield chunk
1655 yield bundler.close()
1661 yield bundler.close()
1656 self.ui.progress(_('bundling'), None)
1662 self.ui.progress(_('bundling'), None)
1657
1663
1658 if nodes:
1664 if nodes:
1659 self.hook('outgoing', node=hex(nodes[0]), source=source)
1665 self.hook('outgoing', node=hex(nodes[0]), source=source)
1660
1666
1661 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1667 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
1662
1668
1663 def addchangegroup(self, source, srctype, url, emptyok=False, lock=None):
1669 def addchangegroup(self, source, srctype, url, emptyok=False, lock=None):
1664 """Add the changegroup returned by source.read() to this repo.
1670 """Add the changegroup returned by source.read() to this repo.
1665 srctype is a string like 'push', 'pull', or 'unbundle'. url is
1671 srctype is a string like 'push', 'pull', or 'unbundle'. url is
1666 the URL of the repo where this changegroup is coming from.
1672 the URL of the repo where this changegroup is coming from.
1667 If lock is not None, the function takes ownership of the lock
1673 If lock is not None, the function takes ownership of the lock
1668 and releases it after the changegroup is added.
1674 and releases it after the changegroup is added.
1669
1675
1670 Return an integer summarizing the change to this repo:
1676 Return an integer summarizing the change to this repo:
1671 - nothing changed or no source: 0
1677 - nothing changed or no source: 0
1672 - more heads than before: 1+added heads (2..n)
1678 - more heads than before: 1+added heads (2..n)
1673 - fewer heads than before: -1-removed heads (-2..-n)
1679 - fewer heads than before: -1-removed heads (-2..-n)
1674 - number of heads stays the same: 1
1680 - number of heads stays the same: 1
1675 """
1681 """
1676 def csmap(x):
1682 def csmap(x):
1677 self.ui.debug("add changeset %s\n" % short(x))
1683 self.ui.debug("add changeset %s\n" % short(x))
1678 return len(cl)
1684 return len(cl)
1679
1685
1680 def revmap(x):
1686 def revmap(x):
1681 return cl.rev(x)
1687 return cl.rev(x)
1682
1688
1683 if not source:
1689 if not source:
1684 return 0
1690 return 0
1685
1691
1686 self.hook('prechangegroup', throw=True, source=srctype, url=url)
1692 self.hook('prechangegroup', throw=True, source=srctype, url=url)
1687
1693
1688 changesets = files = revisions = 0
1694 changesets = files = revisions = 0
1689 efiles = set()
1695 efiles = set()
1690
1696
1691 # write changelog data to temp files so concurrent readers will not see
1697 # write changelog data to temp files so concurrent readers will not see
1692 # inconsistent view
1698 # inconsistent view
1693 cl = self.changelog
1699 cl = self.changelog
1694 cl.delayupdate()
1700 cl.delayupdate()
1695 oldheads = cl.heads()
1701 oldheads = cl.heads()
1696
1702
1697 tr = self.transaction("\n".join([srctype, util.hidepassword(url)]))
1703 tr = self.transaction("\n".join([srctype, util.hidepassword(url)]))
1698 try:
1704 try:
1699 trp = weakref.proxy(tr)
1705 trp = weakref.proxy(tr)
1700 # pull off the changeset group
1706 # pull off the changeset group
1701 self.ui.status(_("adding changesets\n"))
1707 self.ui.status(_("adding changesets\n"))
1702 clstart = len(cl)
1708 clstart = len(cl)
1703 class prog(object):
1709 class prog(object):
1704 step = _('changesets')
1710 step = _('changesets')
1705 count = 1
1711 count = 1
1706 ui = self.ui
1712 ui = self.ui
1707 total = None
1713 total = None
1708 def __call__(self):
1714 def __call__(self):
1709 self.ui.progress(self.step, self.count, unit=_('chunks'),
1715 self.ui.progress(self.step, self.count, unit=_('chunks'),
1710 total=self.total)
1716 total=self.total)
1711 self.count += 1
1717 self.count += 1
1712 pr = prog()
1718 pr = prog()
1713 source.callback = pr
1719 source.callback = pr
1714
1720
1715 source.changelogheader()
1721 source.changelogheader()
1716 if (cl.addgroup(source, csmap, trp) is None
1722 if (cl.addgroup(source, csmap, trp) is None
1717 and not emptyok):
1723 and not emptyok):
1718 raise util.Abort(_("received changelog group is empty"))
1724 raise util.Abort(_("received changelog group is empty"))
1719 clend = len(cl)
1725 clend = len(cl)
1720 changesets = clend - clstart
1726 changesets = clend - clstart
1721 for c in xrange(clstart, clend):
1727 for c in xrange(clstart, clend):
1722 efiles.update(self[c].files())
1728 efiles.update(self[c].files())
1723 efiles = len(efiles)
1729 efiles = len(efiles)
1724 self.ui.progress(_('changesets'), None)
1730 self.ui.progress(_('changesets'), None)
1725
1731
1726 # pull off the manifest group
1732 # pull off the manifest group
1727 self.ui.status(_("adding manifests\n"))
1733 self.ui.status(_("adding manifests\n"))
1728 pr.step = _('manifests')
1734 pr.step = _('manifests')
1729 pr.count = 1
1735 pr.count = 1
1730 pr.total = changesets # manifests <= changesets
1736 pr.total = changesets # manifests <= changesets
1731 # no need to check for empty manifest group here:
1737 # no need to check for empty manifest group here:
1732 # if the result of the merge of 1 and 2 is the same in 3 and 4,
1738 # if the result of the merge of 1 and 2 is the same in 3 and 4,
1733 # no new manifest will be created and the manifest group will
1739 # no new manifest will be created and the manifest group will
1734 # be empty during the pull
1740 # be empty during the pull
1735 source.manifestheader()
1741 source.manifestheader()
1736 self.manifest.addgroup(source, revmap, trp)
1742 self.manifest.addgroup(source, revmap, trp)
1737 self.ui.progress(_('manifests'), None)
1743 self.ui.progress(_('manifests'), None)
1738
1744
1739 needfiles = {}
1745 needfiles = {}
1740 if self.ui.configbool('server', 'validate', default=False):
1746 if self.ui.configbool('server', 'validate', default=False):
1741 # validate incoming csets have their manifests
1747 # validate incoming csets have their manifests
1742 for cset in xrange(clstart, clend):
1748 for cset in xrange(clstart, clend):
1743 mfest = self.changelog.read(self.changelog.node(cset))[0]
1749 mfest = self.changelog.read(self.changelog.node(cset))[0]
1744 mfest = self.manifest.readdelta(mfest)
1750 mfest = self.manifest.readdelta(mfest)
1745 # store file nodes we must see
1751 # store file nodes we must see
1746 for f, n in mfest.iteritems():
1752 for f, n in mfest.iteritems():
1747 needfiles.setdefault(f, set()).add(n)
1753 needfiles.setdefault(f, set()).add(n)
1748
1754
1749 # process the files
1755 # process the files
1750 self.ui.status(_("adding file changes\n"))
1756 self.ui.status(_("adding file changes\n"))
1751 pr.step = 'files'
1757 pr.step = 'files'
1752 pr.count = 1
1758 pr.count = 1
1753 pr.total = efiles
1759 pr.total = efiles
1754 source.callback = None
1760 source.callback = None
1755
1761
1756 while 1:
1762 while 1:
1757 chunkdata = source.filelogheader()
1763 chunkdata = source.filelogheader()
1758 if not chunkdata:
1764 if not chunkdata:
1759 break
1765 break
1760 f = chunkdata["filename"]
1766 f = chunkdata["filename"]
1761 self.ui.debug("adding %s revisions\n" % f)
1767 self.ui.debug("adding %s revisions\n" % f)
1762 pr()
1768 pr()
1763 fl = self.file(f)
1769 fl = self.file(f)
1764 o = len(fl)
1770 o = len(fl)
1765 if fl.addgroup(source, revmap, trp) is None:
1771 if fl.addgroup(source, revmap, trp) is None:
1766 raise util.Abort(_("received file revlog group is empty"))
1772 raise util.Abort(_("received file revlog group is empty"))
1767 revisions += len(fl) - o
1773 revisions += len(fl) - o
1768 files += 1
1774 files += 1
1769 if f in needfiles:
1775 if f in needfiles:
1770 needs = needfiles[f]
1776 needs = needfiles[f]
1771 for new in xrange(o, len(fl)):
1777 for new in xrange(o, len(fl)):
1772 n = fl.node(new)
1778 n = fl.node(new)
1773 if n in needs:
1779 if n in needs:
1774 needs.remove(n)
1780 needs.remove(n)
1775 if not needs:
1781 if not needs:
1776 del needfiles[f]
1782 del needfiles[f]
1777 self.ui.progress(_('files'), None)
1783 self.ui.progress(_('files'), None)
1778
1784
1779 for f, needs in needfiles.iteritems():
1785 for f, needs in needfiles.iteritems():
1780 fl = self.file(f)
1786 fl = self.file(f)
1781 for n in needs:
1787 for n in needs:
1782 try:
1788 try:
1783 fl.rev(n)
1789 fl.rev(n)
1784 except error.LookupError:
1790 except error.LookupError:
1785 raise util.Abort(
1791 raise util.Abort(
1786 _('missing file data for %s:%s - run hg verify') %
1792 _('missing file data for %s:%s - run hg verify') %
1787 (f, hex(n)))
1793 (f, hex(n)))
1788
1794
1789 dh = 0
1795 dh = 0
1790 if oldheads:
1796 if oldheads:
1791 heads = cl.heads()
1797 heads = cl.heads()
1792 dh = len(heads) - len(oldheads)
1798 dh = len(heads) - len(oldheads)
1793 for h in heads:
1799 for h in heads:
1794 if h not in oldheads and 'close' in self[h].extra():
1800 if h not in oldheads and 'close' in self[h].extra():
1795 dh -= 1
1801 dh -= 1
1796 htext = ""
1802 htext = ""
1797 if dh:
1803 if dh:
1798 htext = _(" (%+d heads)") % dh
1804 htext = _(" (%+d heads)") % dh
1799
1805
1800 self.ui.status(_("added %d changesets"
1806 self.ui.status(_("added %d changesets"
1801 " with %d changes to %d files%s\n")
1807 " with %d changes to %d files%s\n")
1802 % (changesets, revisions, files, htext))
1808 % (changesets, revisions, files, htext))
1803
1809
1804 if changesets > 0:
1810 if changesets > 0:
1805 p = lambda: cl.writepending() and self.root or ""
1811 p = lambda: cl.writepending() and self.root or ""
1806 self.hook('pretxnchangegroup', throw=True,
1812 self.hook('pretxnchangegroup', throw=True,
1807 node=hex(cl.node(clstart)), source=srctype,
1813 node=hex(cl.node(clstart)), source=srctype,
1808 url=url, pending=p)
1814 url=url, pending=p)
1809
1815
1810 # make changelog see real files again
1816 # make changelog see real files again
1811 cl.finalize(trp)
1817 cl.finalize(trp)
1812
1818
1813 tr.close()
1819 tr.close()
1814 finally:
1820 finally:
1815 tr.release()
1821 tr.release()
1816 if lock:
1822 if lock:
1817 lock.release()
1823 lock.release()
1818
1824
1819 if changesets > 0:
1825 if changesets > 0:
1820 # forcefully update the on-disk branch cache
1826 # forcefully update the on-disk branch cache
1821 self.ui.debug("updating the branch cache\n")
1827 self.ui.debug("updating the branch cache\n")
1822 self.updatebranchcache()
1828 self.updatebranchcache()
1823 self.hook("changegroup", node=hex(cl.node(clstart)),
1829 self.hook("changegroup", node=hex(cl.node(clstart)),
1824 source=srctype, url=url)
1830 source=srctype, url=url)
1825
1831
1826 for i in xrange(clstart, clend):
1832 for i in xrange(clstart, clend):
1827 self.hook("incoming", node=hex(cl.node(i)),
1833 self.hook("incoming", node=hex(cl.node(i)),
1828 source=srctype, url=url)
1834 source=srctype, url=url)
1829
1835
1830 # never return 0 here:
1836 # never return 0 here:
1831 if dh < 0:
1837 if dh < 0:
1832 return dh - 1
1838 return dh - 1
1833 else:
1839 else:
1834 return dh + 1
1840 return dh + 1
1835
1841
1836 def stream_in(self, remote, requirements):
1842 def stream_in(self, remote, requirements):
1837 lock = self.lock()
1843 lock = self.lock()
1838 try:
1844 try:
1839 fp = remote.stream_out()
1845 fp = remote.stream_out()
1840 l = fp.readline()
1846 l = fp.readline()
1841 try:
1847 try:
1842 resp = int(l)
1848 resp = int(l)
1843 except ValueError:
1849 except ValueError:
1844 raise error.ResponseError(
1850 raise error.ResponseError(
1845 _('Unexpected response from remote server:'), l)
1851 _('Unexpected response from remote server:'), l)
1846 if resp == 1:
1852 if resp == 1:
1847 raise util.Abort(_('operation forbidden by server'))
1853 raise util.Abort(_('operation forbidden by server'))
1848 elif resp == 2:
1854 elif resp == 2:
1849 raise util.Abort(_('locking the remote repository failed'))
1855 raise util.Abort(_('locking the remote repository failed'))
1850 elif resp != 0:
1856 elif resp != 0:
1851 raise util.Abort(_('the server sent an unknown error code'))
1857 raise util.Abort(_('the server sent an unknown error code'))
1852 self.ui.status(_('streaming all changes\n'))
1858 self.ui.status(_('streaming all changes\n'))
1853 l = fp.readline()
1859 l = fp.readline()
1854 try:
1860 try:
1855 total_files, total_bytes = map(int, l.split(' ', 1))
1861 total_files, total_bytes = map(int, l.split(' ', 1))
1856 except (ValueError, TypeError):
1862 except (ValueError, TypeError):
1857 raise error.ResponseError(
1863 raise error.ResponseError(
1858 _('Unexpected response from remote server:'), l)
1864 _('Unexpected response from remote server:'), l)
1859 self.ui.status(_('%d files to transfer, %s of data\n') %
1865 self.ui.status(_('%d files to transfer, %s of data\n') %
1860 (total_files, util.bytecount(total_bytes)))
1866 (total_files, util.bytecount(total_bytes)))
1861 start = time.time()
1867 start = time.time()
1862 for i in xrange(total_files):
1868 for i in xrange(total_files):
1863 # XXX doesn't support '\n' or '\r' in filenames
1869 # XXX doesn't support '\n' or '\r' in filenames
1864 l = fp.readline()
1870 l = fp.readline()
1865 try:
1871 try:
1866 name, size = l.split('\0', 1)
1872 name, size = l.split('\0', 1)
1867 size = int(size)
1873 size = int(size)
1868 except (ValueError, TypeError):
1874 except (ValueError, TypeError):
1869 raise error.ResponseError(
1875 raise error.ResponseError(
1870 _('Unexpected response from remote server:'), l)
1876 _('Unexpected response from remote server:'), l)
1871 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
1877 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
1872 # for backwards compat, name was partially encoded
1878 # for backwards compat, name was partially encoded
1873 ofp = self.sopener(store.decodedir(name), 'w')
1879 ofp = self.sopener(store.decodedir(name), 'w')
1874 for chunk in util.filechunkiter(fp, limit=size):
1880 for chunk in util.filechunkiter(fp, limit=size):
1875 ofp.write(chunk)
1881 ofp.write(chunk)
1876 ofp.close()
1882 ofp.close()
1877 elapsed = time.time() - start
1883 elapsed = time.time() - start
1878 if elapsed <= 0:
1884 if elapsed <= 0:
1879 elapsed = 0.001
1885 elapsed = 0.001
1880 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
1886 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
1881 (util.bytecount(total_bytes), elapsed,
1887 (util.bytecount(total_bytes), elapsed,
1882 util.bytecount(total_bytes / elapsed)))
1888 util.bytecount(total_bytes / elapsed)))
1883
1889
1884 # new requirements = old non-format requirements + new format-related
1890 # new requirements = old non-format requirements + new format-related
1885 # requirements from the streamed-in repository
1891 # requirements from the streamed-in repository
1886 requirements.update(set(self.requirements) - self.supportedformats)
1892 requirements.update(set(self.requirements) - self.supportedformats)
1887 self._applyrequirements(requirements)
1893 self._applyrequirements(requirements)
1888 self._writerequirements()
1894 self._writerequirements()
1889
1895
1890 self.invalidate()
1896 self.invalidate()
1891 return len(self.heads()) + 1
1897 return len(self.heads()) + 1
1892 finally:
1898 finally:
1893 lock.release()
1899 lock.release()
1894
1900
1895 def clone(self, remote, heads=[], stream=False):
1901 def clone(self, remote, heads=[], stream=False):
1896 '''clone remote repository.
1902 '''clone remote repository.
1897
1903
1898 keyword arguments:
1904 keyword arguments:
1899 heads: list of revs to clone (forces use of pull)
1905 heads: list of revs to clone (forces use of pull)
1900 stream: use streaming clone if possible'''
1906 stream: use streaming clone if possible'''
1901
1907
1902 # now, all clients that can request uncompressed clones can
1908 # now, all clients that can request uncompressed clones can
1903 # read repo formats supported by all servers that can serve
1909 # read repo formats supported by all servers that can serve
1904 # them.
1910 # them.
1905
1911
1906 # if revlog format changes, client will have to check version
1912 # if revlog format changes, client will have to check version
1907 # and format flags on "stream" capability, and use
1913 # and format flags on "stream" capability, and use
1908 # uncompressed only if compatible.
1914 # uncompressed only if compatible.
1909
1915
1910 if stream and not heads:
1916 if stream and not heads:
1911 # 'stream' means remote revlog format is revlogv1 only
1917 # 'stream' means remote revlog format is revlogv1 only
1912 if remote.capable('stream'):
1918 if remote.capable('stream'):
1913 return self.stream_in(remote, set(('revlogv1',)))
1919 return self.stream_in(remote, set(('revlogv1',)))
1914 # otherwise, 'streamreqs' contains the remote revlog format
1920 # otherwise, 'streamreqs' contains the remote revlog format
1915 streamreqs = remote.capable('streamreqs')
1921 streamreqs = remote.capable('streamreqs')
1916 if streamreqs:
1922 if streamreqs:
1917 streamreqs = set(streamreqs.split(','))
1923 streamreqs = set(streamreqs.split(','))
1918 # if we support it, stream in and adjust our requirements
1924 # if we support it, stream in and adjust our requirements
1919 if not streamreqs - self.supportedformats:
1925 if not streamreqs - self.supportedformats:
1920 return self.stream_in(remote, streamreqs)
1926 return self.stream_in(remote, streamreqs)
1921 return self.pull(remote, heads)
1927 return self.pull(remote, heads)
1922
1928
1923 def pushkey(self, namespace, key, old, new):
1929 def pushkey(self, namespace, key, old, new):
1924 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
1930 self.hook('prepushkey', throw=True, namespace=namespace, key=key,
1925 old=old, new=new)
1931 old=old, new=new)
1926 ret = pushkey.push(self, namespace, key, old, new)
1932 ret = pushkey.push(self, namespace, key, old, new)
1927 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
1933 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
1928 ret=ret)
1934 ret=ret)
1929 return ret
1935 return ret
1930
1936
1931 def listkeys(self, namespace):
1937 def listkeys(self, namespace):
1932 self.hook('prelistkeys', throw=True, namespace=namespace)
1938 self.hook('prelistkeys', throw=True, namespace=namespace)
1933 values = pushkey.list(self, namespace)
1939 values = pushkey.list(self, namespace)
1934 self.hook('listkeys', namespace=namespace, values=values)
1940 self.hook('listkeys', namespace=namespace, values=values)
1935 return values
1941 return values
1936
1942
1937 def debugwireargs(self, one, two, three=None, four=None, five=None):
1943 def debugwireargs(self, one, two, three=None, four=None, five=None):
1938 '''used to test argument passing over the wire'''
1944 '''used to test argument passing over the wire'''
1939 return "%s %s %s %s %s" % (one, two, three, four, five)
1945 return "%s %s %s %s %s" % (one, two, three, four, five)
1940
1946
1941 # used to avoid circular references so destructors work
1947 # used to avoid circular references so destructors work
1942 def aftertrans(files):
1948 def aftertrans(files):
1943 renamefiles = [tuple(t) for t in files]
1949 renamefiles = [tuple(t) for t in files]
1944 def a():
1950 def a():
1945 for src, dest in renamefiles:
1951 for src, dest in renamefiles:
1946 util.rename(src, dest)
1952 util.rename(src, dest)
1947 return a
1953 return a
1948
1954
1949 def instance(ui, path, create):
1955 def instance(ui, path, create):
1950 return localrepository(ui, util.localpath(path), create)
1956 return localrepository(ui, util.localpath(path), create)
1951
1957
1952 def islocal(path):
1958 def islocal(path):
1953 return True
1959 return True
@@ -1,1870 +1,1870
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b
18 > env LOGNAME=$user hg --cwd a --debug push ../b
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > init_config()
24 > init_config()
25 > {
25 > {
26 > cat > fakegroups.py <<EOF
26 > cat > fakegroups.py <<EOF
27 > from hgext import acl
27 > from hgext import acl
28 > def fakegetusers(ui, group):
28 > def fakegetusers(ui, group):
29 > try:
29 > try:
30 > return acl._getusersorig(ui, group)
30 > return acl._getusersorig(ui, group)
31 > except:
31 > except:
32 > return ["fred", "betty"]
32 > return ["fred", "betty"]
33 > acl._getusersorig = acl._getusers
33 > acl._getusersorig = acl._getusers
34 > acl._getusers = fakegetusers
34 > acl._getusers = fakegetusers
35 > EOF
35 > EOF
36 > rm -f acl.config
36 > rm -f acl.config
37 > cat > $config <<EOF
37 > cat > $config <<EOF
38 > [hooks]
38 > [hooks]
39 > pretxnchangegroup.acl = python:hgext.acl.hook
39 > pretxnchangegroup.acl = python:hgext.acl.hook
40 > [acl]
40 > [acl]
41 > sources = push
41 > sources = push
42 > [extensions]
42 > [extensions]
43 > f=`pwd`/fakegroups.py
43 > f=`pwd`/fakegroups.py
44 > EOF
44 > EOF
45 > }
45 > }
46
46
47 $ hg init a
47 $ hg init a
48 $ cd a
48 $ cd a
49 $ mkdir foo foo/Bar quux
49 $ mkdir foo foo/Bar quux
50 $ echo 'in foo' > foo/file.txt
50 $ echo 'in foo' > foo/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
52 $ echo 'in quux' > quux/file.py
52 $ echo 'in quux' > quux/file.py
53 $ hg add -q
53 $ hg add -q
54 $ hg ci -m 'add files' -d '1000000 0'
54 $ hg ci -m 'add files' -d '1000000 0'
55 $ echo >> foo/file.txt
55 $ echo >> foo/file.txt
56 $ hg ci -m 'change foo/file' -d '1000001 0'
56 $ hg ci -m 'change foo/file' -d '1000001 0'
57 $ echo >> foo/Bar/file.txt
57 $ echo >> foo/Bar/file.txt
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
59 $ echo >> quux/file.py
59 $ echo >> quux/file.py
60 $ hg ci -m 'change quux/file' -d '1000003 0'
60 $ hg ci -m 'change quux/file' -d '1000003 0'
61 $ hg tip --quiet
61 $ hg tip --quiet
62 3:911600dab2ae
62 3:911600dab2ae
63
63
64 $ cd ..
64 $ cd ..
65 $ hg clone -r 0 a b
65 $ hg clone -r 0 a b
66 adding changesets
66 adding changesets
67 adding manifests
67 adding manifests
68 adding file changes
68 adding file changes
69 added 1 changesets with 3 changes to 3 files
69 added 1 changesets with 3 changes to 3 files
70 updating to branch default
70 updating to branch default
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
72
72
73 $ echo '[extensions]' >> $HGRCPATH
73 $ echo '[extensions]' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
75
75
76 $ config=b/.hg/hgrc
76 $ config=b/.hg/hgrc
77
77
78 Extension disabled for lack of a hook
78 Extension disabled for lack of a hook
79
79
80 $ do_push fred
80 $ do_push fred
81 Pushing as user fred
81 Pushing as user fred
82 hgrc = """
82 hgrc = """
83 """
83 """
84 pushing to ../b
84 pushing to ../b
85 searching for changes
85 searching for changes
86 3 changesets found
86 3 changesets found
87 list of changesets:
87 list of changesets:
88 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
88 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
89 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
89 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
90 911600dab2ae7a9baff75958b84fe606851ce955
90 911600dab2ae7a9baff75958b84fe606851ce955
91 adding changesets
91 adding changesets
92 bundling: 1 changesets
92 bundling: 1 changesets
93 bundling: 2 changesets
93 bundling: 2 changesets
94 bundling: 3 changesets
94 bundling: 3 changesets
95 bundling: 1/3 manifests (33.33%)
95 bundling: 1/3 manifests (33.33%)
96 bundling: 2/3 manifests (66.67%)
96 bundling: 2/3 manifests (66.67%)
97 bundling: 3/3 manifests (100.00%)
97 bundling: 3/3 manifests (100.00%)
98 bundling: foo/Bar/file.txt 0/3 files (0.00%)
98 bundling: foo/Bar/file.txt 0/3 files (0.00%)
99 bundling: foo/file.txt 1/3 files (33.33%)
99 bundling: foo/file.txt 1/3 files (33.33%)
100 bundling: quux/file.py 2/3 files (66.67%)
100 bundling: quux/file.py 2/3 files (66.67%)
101 changesets: 1 chunks
101 changesets: 1 chunks
102 add changeset ef1ea85a6374
102 add changeset ef1ea85a6374
103 changesets: 2 chunks
103 changesets: 2 chunks
104 add changeset f9cafe1212c8
104 add changeset f9cafe1212c8
105 changesets: 3 chunks
105 changesets: 3 chunks
106 add changeset 911600dab2ae
106 add changeset 911600dab2ae
107 adding manifests
107 adding manifests
108 manifests: 1/3 chunks (33.33%)
108 manifests: 1/3 chunks (33.33%)
109 manifests: 2/3 chunks (66.67%)
109 manifests: 2/3 chunks (66.67%)
110 manifests: 3/3 chunks (100.00%)
110 manifests: 3/3 chunks (100.00%)
111 adding file changes
111 adding file changes
112 adding foo/Bar/file.txt revisions
112 adding foo/Bar/file.txt revisions
113 files: 1/3 chunks (33.33%)
113 files: 1/3 chunks (33.33%)
114 adding foo/file.txt revisions
114 adding foo/file.txt revisions
115 files: 2/3 chunks (66.67%)
115 files: 2/3 chunks (66.67%)
116 adding quux/file.py revisions
116 adding quux/file.py revisions
117 files: 3/3 chunks (100.00%)
117 files: 3/3 chunks (100.00%)
118 added 3 changesets with 3 changes to 3 files
118 added 3 changesets with 3 changes to 3 files
119 updating the branch cache
119 updating the branch cache
120 checking for updated bookmarks
120 checking for updated bookmarks
121 repository tip rolled back to revision 0 (undo push)
121 repository tip rolled back to revision 0 (undo push)
122 working directory now based on revision 0
122 working directory now based on revision 0
123 0:6675d58eff77
123 0:6675d58eff77
124
124
125
125
126 $ echo '[hooks]' >> $config
126 $ echo '[hooks]' >> $config
127 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
127 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
128
128
129 Extension disabled for lack of acl.sources
129 Extension disabled for lack of acl.sources
130
130
131 $ do_push fred
131 $ do_push fred
132 Pushing as user fred
132 Pushing as user fred
133 hgrc = """
133 hgrc = """
134 [hooks]
134 [hooks]
135 pretxnchangegroup.acl = python:hgext.acl.hook
135 pretxnchangegroup.acl = python:hgext.acl.hook
136 """
136 """
137 pushing to ../b
137 pushing to ../b
138 searching for changes
138 searching for changes
139 invalidating branch cache (tip differs)
139 invalidating branch cache (tip differs)
140 3 changesets found
140 3 changesets found
141 list of changesets:
141 list of changesets:
142 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
142 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
143 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
143 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
144 911600dab2ae7a9baff75958b84fe606851ce955
144 911600dab2ae7a9baff75958b84fe606851ce955
145 adding changesets
145 adding changesets
146 bundling: 1 changesets
146 bundling: 1 changesets
147 bundling: 2 changesets
147 bundling: 2 changesets
148 bundling: 3 changesets
148 bundling: 3 changesets
149 bundling: 1/3 manifests (33.33%)
149 bundling: 1/3 manifests (33.33%)
150 bundling: 2/3 manifests (66.67%)
150 bundling: 2/3 manifests (66.67%)
151 bundling: 3/3 manifests (100.00%)
151 bundling: 3/3 manifests (100.00%)
152 bundling: foo/Bar/file.txt 0/3 files (0.00%)
152 bundling: foo/Bar/file.txt 0/3 files (0.00%)
153 bundling: foo/file.txt 1/3 files (33.33%)
153 bundling: foo/file.txt 1/3 files (33.33%)
154 bundling: quux/file.py 2/3 files (66.67%)
154 bundling: quux/file.py 2/3 files (66.67%)
155 changesets: 1 chunks
155 changesets: 1 chunks
156 add changeset ef1ea85a6374
156 add changeset ef1ea85a6374
157 changesets: 2 chunks
157 changesets: 2 chunks
158 add changeset f9cafe1212c8
158 add changeset f9cafe1212c8
159 changesets: 3 chunks
159 changesets: 3 chunks
160 add changeset 911600dab2ae
160 add changeset 911600dab2ae
161 adding manifests
161 adding manifests
162 manifests: 1/3 chunks (33.33%)
162 manifests: 1/3 chunks (33.33%)
163 manifests: 2/3 chunks (66.67%)
163 manifests: 2/3 chunks (66.67%)
164 manifests: 3/3 chunks (100.00%)
164 manifests: 3/3 chunks (100.00%)
165 adding file changes
165 adding file changes
166 adding foo/Bar/file.txt revisions
166 adding foo/Bar/file.txt revisions
167 files: 1/3 chunks (33.33%)
167 files: 1/3 chunks (33.33%)
168 adding foo/file.txt revisions
168 adding foo/file.txt revisions
169 files: 2/3 chunks (66.67%)
169 files: 2/3 chunks (66.67%)
170 adding quux/file.py revisions
170 adding quux/file.py revisions
171 files: 3/3 chunks (100.00%)
171 files: 3/3 chunks (100.00%)
172 added 3 changesets with 3 changes to 3 files
172 added 3 changesets with 3 changes to 3 files
173 calling hook pretxnchangegroup.acl: hgext.acl.hook
173 calling hook pretxnchangegroup.acl: hgext.acl.hook
174 acl: changes have source "push" - skipping
174 acl: changes have source "push" - skipping
175 updating the branch cache
175 updating the branch cache
176 checking for updated bookmarks
176 checking for updated bookmarks
177 repository tip rolled back to revision 0 (undo push)
177 repository tip rolled back to revision 0 (undo push)
178 working directory now based on revision 0
178 working directory now based on revision 0
179 0:6675d58eff77
179 0:6675d58eff77
180
180
181
181
182 No [acl.allow]/[acl.deny]
182 No [acl.allow]/[acl.deny]
183
183
184 $ echo '[acl]' >> $config
184 $ echo '[acl]' >> $config
185 $ echo 'sources = push' >> $config
185 $ echo 'sources = push' >> $config
186 $ do_push fred
186 $ do_push fred
187 Pushing as user fred
187 Pushing as user fred
188 hgrc = """
188 hgrc = """
189 [hooks]
189 [hooks]
190 pretxnchangegroup.acl = python:hgext.acl.hook
190 pretxnchangegroup.acl = python:hgext.acl.hook
191 [acl]
191 [acl]
192 sources = push
192 sources = push
193 """
193 """
194 pushing to ../b
194 pushing to ../b
195 searching for changes
195 searching for changes
196 invalidating branch cache (tip differs)
196 invalidating branch cache (tip differs)
197 3 changesets found
197 3 changesets found
198 list of changesets:
198 list of changesets:
199 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
199 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
200 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
200 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
201 911600dab2ae7a9baff75958b84fe606851ce955
201 911600dab2ae7a9baff75958b84fe606851ce955
202 adding changesets
202 adding changesets
203 bundling: 1 changesets
203 bundling: 1 changesets
204 bundling: 2 changesets
204 bundling: 2 changesets
205 bundling: 3 changesets
205 bundling: 3 changesets
206 bundling: 1/3 manifests (33.33%)
206 bundling: 1/3 manifests (33.33%)
207 bundling: 2/3 manifests (66.67%)
207 bundling: 2/3 manifests (66.67%)
208 bundling: 3/3 manifests (100.00%)
208 bundling: 3/3 manifests (100.00%)
209 bundling: foo/Bar/file.txt 0/3 files (0.00%)
209 bundling: foo/Bar/file.txt 0/3 files (0.00%)
210 bundling: foo/file.txt 1/3 files (33.33%)
210 bundling: foo/file.txt 1/3 files (33.33%)
211 bundling: quux/file.py 2/3 files (66.67%)
211 bundling: quux/file.py 2/3 files (66.67%)
212 changesets: 1 chunks
212 changesets: 1 chunks
213 add changeset ef1ea85a6374
213 add changeset ef1ea85a6374
214 changesets: 2 chunks
214 changesets: 2 chunks
215 add changeset f9cafe1212c8
215 add changeset f9cafe1212c8
216 changesets: 3 chunks
216 changesets: 3 chunks
217 add changeset 911600dab2ae
217 add changeset 911600dab2ae
218 adding manifests
218 adding manifests
219 manifests: 1/3 chunks (33.33%)
219 manifests: 1/3 chunks (33.33%)
220 manifests: 2/3 chunks (66.67%)
220 manifests: 2/3 chunks (66.67%)
221 manifests: 3/3 chunks (100.00%)
221 manifests: 3/3 chunks (100.00%)
222 adding file changes
222 adding file changes
223 adding foo/Bar/file.txt revisions
223 adding foo/Bar/file.txt revisions
224 files: 1/3 chunks (33.33%)
224 files: 1/3 chunks (33.33%)
225 adding foo/file.txt revisions
225 adding foo/file.txt revisions
226 files: 2/3 chunks (66.67%)
226 files: 2/3 chunks (66.67%)
227 adding quux/file.py revisions
227 adding quux/file.py revisions
228 files: 3/3 chunks (100.00%)
228 files: 3/3 chunks (100.00%)
229 added 3 changesets with 3 changes to 3 files
229 added 3 changesets with 3 changes to 3 files
230 calling hook pretxnchangegroup.acl: hgext.acl.hook
230 calling hook pretxnchangegroup.acl: hgext.acl.hook
231 acl: acl.allow.branches not enabled
231 acl: acl.allow.branches not enabled
232 acl: acl.deny.branches not enabled
232 acl: acl.deny.branches not enabled
233 acl: acl.allow not enabled
233 acl: acl.allow not enabled
234 acl: acl.deny not enabled
234 acl: acl.deny not enabled
235 acl: branch access granted: "ef1ea85a6374" on branch "default"
235 acl: branch access granted: "ef1ea85a6374" on branch "default"
236 acl: allowing changeset ef1ea85a6374
236 acl: allowing changeset ef1ea85a6374
237 acl: branch access granted: "f9cafe1212c8" on branch "default"
237 acl: branch access granted: "f9cafe1212c8" on branch "default"
238 acl: allowing changeset f9cafe1212c8
238 acl: allowing changeset f9cafe1212c8
239 acl: branch access granted: "911600dab2ae" on branch "default"
239 acl: branch access granted: "911600dab2ae" on branch "default"
240 acl: allowing changeset 911600dab2ae
240 acl: allowing changeset 911600dab2ae
241 updating the branch cache
241 updating the branch cache
242 checking for updated bookmarks
242 checking for updated bookmarks
243 repository tip rolled back to revision 0 (undo push)
243 repository tip rolled back to revision 0 (undo push)
244 working directory now based on revision 0
244 working directory now based on revision 0
245 0:6675d58eff77
245 0:6675d58eff77
246
246
247
247
248 Empty [acl.allow]
248 Empty [acl.allow]
249
249
250 $ echo '[acl.allow]' >> $config
250 $ echo '[acl.allow]' >> $config
251 $ do_push fred
251 $ do_push fred
252 Pushing as user fred
252 Pushing as user fred
253 hgrc = """
253 hgrc = """
254 [hooks]
254 [hooks]
255 pretxnchangegroup.acl = python:hgext.acl.hook
255 pretxnchangegroup.acl = python:hgext.acl.hook
256 [acl]
256 [acl]
257 sources = push
257 sources = push
258 [acl.allow]
258 [acl.allow]
259 """
259 """
260 pushing to ../b
260 pushing to ../b
261 searching for changes
261 searching for changes
262 invalidating branch cache (tip differs)
262 invalidating branch cache (tip differs)
263 3 changesets found
263 3 changesets found
264 list of changesets:
264 list of changesets:
265 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
265 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
266 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
266 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
267 911600dab2ae7a9baff75958b84fe606851ce955
267 911600dab2ae7a9baff75958b84fe606851ce955
268 adding changesets
268 adding changesets
269 bundling: 1 changesets
269 bundling: 1 changesets
270 bundling: 2 changesets
270 bundling: 2 changesets
271 bundling: 3 changesets
271 bundling: 3 changesets
272 bundling: 1/3 manifests (33.33%)
272 bundling: 1/3 manifests (33.33%)
273 bundling: 2/3 manifests (66.67%)
273 bundling: 2/3 manifests (66.67%)
274 bundling: 3/3 manifests (100.00%)
274 bundling: 3/3 manifests (100.00%)
275 bundling: foo/Bar/file.txt 0/3 files (0.00%)
275 bundling: foo/Bar/file.txt 0/3 files (0.00%)
276 bundling: foo/file.txt 1/3 files (33.33%)
276 bundling: foo/file.txt 1/3 files (33.33%)
277 bundling: quux/file.py 2/3 files (66.67%)
277 bundling: quux/file.py 2/3 files (66.67%)
278 changesets: 1 chunks
278 changesets: 1 chunks
279 add changeset ef1ea85a6374
279 add changeset ef1ea85a6374
280 changesets: 2 chunks
280 changesets: 2 chunks
281 add changeset f9cafe1212c8
281 add changeset f9cafe1212c8
282 changesets: 3 chunks
282 changesets: 3 chunks
283 add changeset 911600dab2ae
283 add changeset 911600dab2ae
284 adding manifests
284 adding manifests
285 manifests: 1/3 chunks (33.33%)
285 manifests: 1/3 chunks (33.33%)
286 manifests: 2/3 chunks (66.67%)
286 manifests: 2/3 chunks (66.67%)
287 manifests: 3/3 chunks (100.00%)
287 manifests: 3/3 chunks (100.00%)
288 adding file changes
288 adding file changes
289 adding foo/Bar/file.txt revisions
289 adding foo/Bar/file.txt revisions
290 files: 1/3 chunks (33.33%)
290 files: 1/3 chunks (33.33%)
291 adding foo/file.txt revisions
291 adding foo/file.txt revisions
292 files: 2/3 chunks (66.67%)
292 files: 2/3 chunks (66.67%)
293 adding quux/file.py revisions
293 adding quux/file.py revisions
294 files: 3/3 chunks (100.00%)
294 files: 3/3 chunks (100.00%)
295 added 3 changesets with 3 changes to 3 files
295 added 3 changesets with 3 changes to 3 files
296 calling hook pretxnchangegroup.acl: hgext.acl.hook
296 calling hook pretxnchangegroup.acl: hgext.acl.hook
297 acl: acl.allow.branches not enabled
297 acl: acl.allow.branches not enabled
298 acl: acl.deny.branches not enabled
298 acl: acl.deny.branches not enabled
299 acl: acl.allow enabled, 0 entries for user fred
299 acl: acl.allow enabled, 0 entries for user fred
300 acl: acl.deny not enabled
300 acl: acl.deny not enabled
301 acl: branch access granted: "ef1ea85a6374" on branch "default"
301 acl: branch access granted: "ef1ea85a6374" on branch "default"
302 acl: user fred not allowed on foo/file.txt
302 acl: user fred not allowed on foo/file.txt
303 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
303 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
304 transaction abort!
304 transaction abort!
305 rollback completed
305 rollback completed
306 abort: acl: access denied for changeset ef1ea85a6374
306 abort: acl: access denied for changeset ef1ea85a6374
307 no rollback information available
307 no rollback information available
308 0:6675d58eff77
308 0:6675d58eff77
309
309
310
310
311 fred is allowed inside foo/
311 fred is allowed inside foo/
312
312
313 $ echo 'foo/** = fred' >> $config
313 $ echo 'foo/** = fred' >> $config
314 $ do_push fred
314 $ do_push fred
315 Pushing as user fred
315 Pushing as user fred
316 hgrc = """
316 hgrc = """
317 [hooks]
317 [hooks]
318 pretxnchangegroup.acl = python:hgext.acl.hook
318 pretxnchangegroup.acl = python:hgext.acl.hook
319 [acl]
319 [acl]
320 sources = push
320 sources = push
321 [acl.allow]
321 [acl.allow]
322 foo/** = fred
322 foo/** = fred
323 """
323 """
324 pushing to ../b
324 pushing to ../b
325 searching for changes
325 searching for changes
326 3 changesets found
326 3 changesets found
327 list of changesets:
327 list of changesets:
328 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
328 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
329 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
329 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
330 911600dab2ae7a9baff75958b84fe606851ce955
330 911600dab2ae7a9baff75958b84fe606851ce955
331 adding changesets
331 adding changesets
332 bundling: 1 changesets
332 bundling: 1 changesets
333 bundling: 2 changesets
333 bundling: 2 changesets
334 bundling: 3 changesets
334 bundling: 3 changesets
335 bundling: 1/3 manifests (33.33%)
335 bundling: 1/3 manifests (33.33%)
336 bundling: 2/3 manifests (66.67%)
336 bundling: 2/3 manifests (66.67%)
337 bundling: 3/3 manifests (100.00%)
337 bundling: 3/3 manifests (100.00%)
338 bundling: foo/Bar/file.txt 0/3 files (0.00%)
338 bundling: foo/Bar/file.txt 0/3 files (0.00%)
339 bundling: foo/file.txt 1/3 files (33.33%)
339 bundling: foo/file.txt 1/3 files (33.33%)
340 bundling: quux/file.py 2/3 files (66.67%)
340 bundling: quux/file.py 2/3 files (66.67%)
341 changesets: 1 chunks
341 changesets: 1 chunks
342 add changeset ef1ea85a6374
342 add changeset ef1ea85a6374
343 changesets: 2 chunks
343 changesets: 2 chunks
344 add changeset f9cafe1212c8
344 add changeset f9cafe1212c8
345 changesets: 3 chunks
345 changesets: 3 chunks
346 add changeset 911600dab2ae
346 add changeset 911600dab2ae
347 adding manifests
347 adding manifests
348 manifests: 1/3 chunks (33.33%)
348 manifests: 1/3 chunks (33.33%)
349 manifests: 2/3 chunks (66.67%)
349 manifests: 2/3 chunks (66.67%)
350 manifests: 3/3 chunks (100.00%)
350 manifests: 3/3 chunks (100.00%)
351 adding file changes
351 adding file changes
352 adding foo/Bar/file.txt revisions
352 adding foo/Bar/file.txt revisions
353 files: 1/3 chunks (33.33%)
353 files: 1/3 chunks (33.33%)
354 adding foo/file.txt revisions
354 adding foo/file.txt revisions
355 files: 2/3 chunks (66.67%)
355 files: 2/3 chunks (66.67%)
356 adding quux/file.py revisions
356 adding quux/file.py revisions
357 files: 3/3 chunks (100.00%)
357 files: 3/3 chunks (100.00%)
358 added 3 changesets with 3 changes to 3 files
358 added 3 changesets with 3 changes to 3 files
359 calling hook pretxnchangegroup.acl: hgext.acl.hook
359 calling hook pretxnchangegroup.acl: hgext.acl.hook
360 acl: acl.allow.branches not enabled
360 acl: acl.allow.branches not enabled
361 acl: acl.deny.branches not enabled
361 acl: acl.deny.branches not enabled
362 acl: acl.allow enabled, 1 entries for user fred
362 acl: acl.allow enabled, 1 entries for user fred
363 acl: acl.deny not enabled
363 acl: acl.deny not enabled
364 acl: branch access granted: "ef1ea85a6374" on branch "default"
364 acl: branch access granted: "ef1ea85a6374" on branch "default"
365 acl: allowing changeset ef1ea85a6374
365 acl: allowing changeset ef1ea85a6374
366 acl: branch access granted: "f9cafe1212c8" on branch "default"
366 acl: branch access granted: "f9cafe1212c8" on branch "default"
367 acl: allowing changeset f9cafe1212c8
367 acl: allowing changeset f9cafe1212c8
368 acl: branch access granted: "911600dab2ae" on branch "default"
368 acl: branch access granted: "911600dab2ae" on branch "default"
369 acl: user fred not allowed on quux/file.py
369 acl: user fred not allowed on quux/file.py
370 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
370 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
371 transaction abort!
371 transaction abort!
372 rollback completed
372 rollback completed
373 abort: acl: access denied for changeset 911600dab2ae
373 abort: acl: access denied for changeset 911600dab2ae
374 no rollback information available
374 no rollback information available
375 0:6675d58eff77
375 0:6675d58eff77
376
376
377
377
378 Empty [acl.deny]
378 Empty [acl.deny]
379
379
380 $ echo '[acl.deny]' >> $config
380 $ echo '[acl.deny]' >> $config
381 $ do_push barney
381 $ do_push barney
382 Pushing as user barney
382 Pushing as user barney
383 hgrc = """
383 hgrc = """
384 [hooks]
384 [hooks]
385 pretxnchangegroup.acl = python:hgext.acl.hook
385 pretxnchangegroup.acl = python:hgext.acl.hook
386 [acl]
386 [acl]
387 sources = push
387 sources = push
388 [acl.allow]
388 [acl.allow]
389 foo/** = fred
389 foo/** = fred
390 [acl.deny]
390 [acl.deny]
391 """
391 """
392 pushing to ../b
392 pushing to ../b
393 searching for changes
393 searching for changes
394 3 changesets found
394 3 changesets found
395 list of changesets:
395 list of changesets:
396 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
396 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
397 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
397 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
398 911600dab2ae7a9baff75958b84fe606851ce955
398 911600dab2ae7a9baff75958b84fe606851ce955
399 adding changesets
399 adding changesets
400 bundling: 1 changesets
400 bundling: 1 changesets
401 bundling: 2 changesets
401 bundling: 2 changesets
402 bundling: 3 changesets
402 bundling: 3 changesets
403 bundling: 1/3 manifests (33.33%)
403 bundling: 1/3 manifests (33.33%)
404 bundling: 2/3 manifests (66.67%)
404 bundling: 2/3 manifests (66.67%)
405 bundling: 3/3 manifests (100.00%)
405 bundling: 3/3 manifests (100.00%)
406 bundling: foo/Bar/file.txt 0/3 files (0.00%)
406 bundling: foo/Bar/file.txt 0/3 files (0.00%)
407 bundling: foo/file.txt 1/3 files (33.33%)
407 bundling: foo/file.txt 1/3 files (33.33%)
408 bundling: quux/file.py 2/3 files (66.67%)
408 bundling: quux/file.py 2/3 files (66.67%)
409 changesets: 1 chunks
409 changesets: 1 chunks
410 add changeset ef1ea85a6374
410 add changeset ef1ea85a6374
411 changesets: 2 chunks
411 changesets: 2 chunks
412 add changeset f9cafe1212c8
412 add changeset f9cafe1212c8
413 changesets: 3 chunks
413 changesets: 3 chunks
414 add changeset 911600dab2ae
414 add changeset 911600dab2ae
415 adding manifests
415 adding manifests
416 manifests: 1/3 chunks (33.33%)
416 manifests: 1/3 chunks (33.33%)
417 manifests: 2/3 chunks (66.67%)
417 manifests: 2/3 chunks (66.67%)
418 manifests: 3/3 chunks (100.00%)
418 manifests: 3/3 chunks (100.00%)
419 adding file changes
419 adding file changes
420 adding foo/Bar/file.txt revisions
420 adding foo/Bar/file.txt revisions
421 files: 1/3 chunks (33.33%)
421 files: 1/3 chunks (33.33%)
422 adding foo/file.txt revisions
422 adding foo/file.txt revisions
423 files: 2/3 chunks (66.67%)
423 files: 2/3 chunks (66.67%)
424 adding quux/file.py revisions
424 adding quux/file.py revisions
425 files: 3/3 chunks (100.00%)
425 files: 3/3 chunks (100.00%)
426 added 3 changesets with 3 changes to 3 files
426 added 3 changesets with 3 changes to 3 files
427 calling hook pretxnchangegroup.acl: hgext.acl.hook
427 calling hook pretxnchangegroup.acl: hgext.acl.hook
428 acl: acl.allow.branches not enabled
428 acl: acl.allow.branches not enabled
429 acl: acl.deny.branches not enabled
429 acl: acl.deny.branches not enabled
430 acl: acl.allow enabled, 0 entries for user barney
430 acl: acl.allow enabled, 0 entries for user barney
431 acl: acl.deny enabled, 0 entries for user barney
431 acl: acl.deny enabled, 0 entries for user barney
432 acl: branch access granted: "ef1ea85a6374" on branch "default"
432 acl: branch access granted: "ef1ea85a6374" on branch "default"
433 acl: user barney not allowed on foo/file.txt
433 acl: user barney not allowed on foo/file.txt
434 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
434 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
435 transaction abort!
435 transaction abort!
436 rollback completed
436 rollback completed
437 abort: acl: access denied for changeset ef1ea85a6374
437 abort: acl: access denied for changeset ef1ea85a6374
438 no rollback information available
438 no rollback information available
439 0:6675d58eff77
439 0:6675d58eff77
440
440
441
441
442 fred is allowed inside foo/, but not foo/bar/ (case matters)
442 fred is allowed inside foo/, but not foo/bar/ (case matters)
443
443
444 $ echo 'foo/bar/** = fred' >> $config
444 $ echo 'foo/bar/** = fred' >> $config
445 $ do_push fred
445 $ do_push fred
446 Pushing as user fred
446 Pushing as user fred
447 hgrc = """
447 hgrc = """
448 [hooks]
448 [hooks]
449 pretxnchangegroup.acl = python:hgext.acl.hook
449 pretxnchangegroup.acl = python:hgext.acl.hook
450 [acl]
450 [acl]
451 sources = push
451 sources = push
452 [acl.allow]
452 [acl.allow]
453 foo/** = fred
453 foo/** = fred
454 [acl.deny]
454 [acl.deny]
455 foo/bar/** = fred
455 foo/bar/** = fred
456 """
456 """
457 pushing to ../b
457 pushing to ../b
458 searching for changes
458 searching for changes
459 3 changesets found
459 3 changesets found
460 list of changesets:
460 list of changesets:
461 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
461 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
462 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
462 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
463 911600dab2ae7a9baff75958b84fe606851ce955
463 911600dab2ae7a9baff75958b84fe606851ce955
464 adding changesets
464 adding changesets
465 bundling: 1 changesets
465 bundling: 1 changesets
466 bundling: 2 changesets
466 bundling: 2 changesets
467 bundling: 3 changesets
467 bundling: 3 changesets
468 bundling: 1/3 manifests (33.33%)
468 bundling: 1/3 manifests (33.33%)
469 bundling: 2/3 manifests (66.67%)
469 bundling: 2/3 manifests (66.67%)
470 bundling: 3/3 manifests (100.00%)
470 bundling: 3/3 manifests (100.00%)
471 bundling: foo/Bar/file.txt 0/3 files (0.00%)
471 bundling: foo/Bar/file.txt 0/3 files (0.00%)
472 bundling: foo/file.txt 1/3 files (33.33%)
472 bundling: foo/file.txt 1/3 files (33.33%)
473 bundling: quux/file.py 2/3 files (66.67%)
473 bundling: quux/file.py 2/3 files (66.67%)
474 changesets: 1 chunks
474 changesets: 1 chunks
475 add changeset ef1ea85a6374
475 add changeset ef1ea85a6374
476 changesets: 2 chunks
476 changesets: 2 chunks
477 add changeset f9cafe1212c8
477 add changeset f9cafe1212c8
478 changesets: 3 chunks
478 changesets: 3 chunks
479 add changeset 911600dab2ae
479 add changeset 911600dab2ae
480 adding manifests
480 adding manifests
481 manifests: 1/3 chunks (33.33%)
481 manifests: 1/3 chunks (33.33%)
482 manifests: 2/3 chunks (66.67%)
482 manifests: 2/3 chunks (66.67%)
483 manifests: 3/3 chunks (100.00%)
483 manifests: 3/3 chunks (100.00%)
484 adding file changes
484 adding file changes
485 adding foo/Bar/file.txt revisions
485 adding foo/Bar/file.txt revisions
486 files: 1/3 chunks (33.33%)
486 files: 1/3 chunks (33.33%)
487 adding foo/file.txt revisions
487 adding foo/file.txt revisions
488 files: 2/3 chunks (66.67%)
488 files: 2/3 chunks (66.67%)
489 adding quux/file.py revisions
489 adding quux/file.py revisions
490 files: 3/3 chunks (100.00%)
490 files: 3/3 chunks (100.00%)
491 added 3 changesets with 3 changes to 3 files
491 added 3 changesets with 3 changes to 3 files
492 calling hook pretxnchangegroup.acl: hgext.acl.hook
492 calling hook pretxnchangegroup.acl: hgext.acl.hook
493 acl: acl.allow.branches not enabled
493 acl: acl.allow.branches not enabled
494 acl: acl.deny.branches not enabled
494 acl: acl.deny.branches not enabled
495 acl: acl.allow enabled, 1 entries for user fred
495 acl: acl.allow enabled, 1 entries for user fred
496 acl: acl.deny enabled, 1 entries for user fred
496 acl: acl.deny enabled, 1 entries for user fred
497 acl: branch access granted: "ef1ea85a6374" on branch "default"
497 acl: branch access granted: "ef1ea85a6374" on branch "default"
498 acl: allowing changeset ef1ea85a6374
498 acl: allowing changeset ef1ea85a6374
499 acl: branch access granted: "f9cafe1212c8" on branch "default"
499 acl: branch access granted: "f9cafe1212c8" on branch "default"
500 acl: allowing changeset f9cafe1212c8
500 acl: allowing changeset f9cafe1212c8
501 acl: branch access granted: "911600dab2ae" on branch "default"
501 acl: branch access granted: "911600dab2ae" on branch "default"
502 acl: user fred not allowed on quux/file.py
502 acl: user fred not allowed on quux/file.py
503 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
503 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
504 transaction abort!
504 transaction abort!
505 rollback completed
505 rollback completed
506 abort: acl: access denied for changeset 911600dab2ae
506 abort: acl: access denied for changeset 911600dab2ae
507 no rollback information available
507 no rollback information available
508 0:6675d58eff77
508 0:6675d58eff77
509
509
510
510
511 fred is allowed inside foo/, but not foo/Bar/
511 fred is allowed inside foo/, but not foo/Bar/
512
512
513 $ echo 'foo/Bar/** = fred' >> $config
513 $ echo 'foo/Bar/** = fred' >> $config
514 $ do_push fred
514 $ do_push fred
515 Pushing as user fred
515 Pushing as user fred
516 hgrc = """
516 hgrc = """
517 [hooks]
517 [hooks]
518 pretxnchangegroup.acl = python:hgext.acl.hook
518 pretxnchangegroup.acl = python:hgext.acl.hook
519 [acl]
519 [acl]
520 sources = push
520 sources = push
521 [acl.allow]
521 [acl.allow]
522 foo/** = fred
522 foo/** = fred
523 [acl.deny]
523 [acl.deny]
524 foo/bar/** = fred
524 foo/bar/** = fred
525 foo/Bar/** = fred
525 foo/Bar/** = fred
526 """
526 """
527 pushing to ../b
527 pushing to ../b
528 searching for changes
528 searching for changes
529 3 changesets found
529 3 changesets found
530 list of changesets:
530 list of changesets:
531 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
531 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
532 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
532 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
533 911600dab2ae7a9baff75958b84fe606851ce955
533 911600dab2ae7a9baff75958b84fe606851ce955
534 adding changesets
534 adding changesets
535 bundling: 1 changesets
535 bundling: 1 changesets
536 bundling: 2 changesets
536 bundling: 2 changesets
537 bundling: 3 changesets
537 bundling: 3 changesets
538 bundling: 1/3 manifests (33.33%)
538 bundling: 1/3 manifests (33.33%)
539 bundling: 2/3 manifests (66.67%)
539 bundling: 2/3 manifests (66.67%)
540 bundling: 3/3 manifests (100.00%)
540 bundling: 3/3 manifests (100.00%)
541 bundling: foo/Bar/file.txt 0/3 files (0.00%)
541 bundling: foo/Bar/file.txt 0/3 files (0.00%)
542 bundling: foo/file.txt 1/3 files (33.33%)
542 bundling: foo/file.txt 1/3 files (33.33%)
543 bundling: quux/file.py 2/3 files (66.67%)
543 bundling: quux/file.py 2/3 files (66.67%)
544 changesets: 1 chunks
544 changesets: 1 chunks
545 add changeset ef1ea85a6374
545 add changeset ef1ea85a6374
546 changesets: 2 chunks
546 changesets: 2 chunks
547 add changeset f9cafe1212c8
547 add changeset f9cafe1212c8
548 changesets: 3 chunks
548 changesets: 3 chunks
549 add changeset 911600dab2ae
549 add changeset 911600dab2ae
550 adding manifests
550 adding manifests
551 manifests: 1/3 chunks (33.33%)
551 manifests: 1/3 chunks (33.33%)
552 manifests: 2/3 chunks (66.67%)
552 manifests: 2/3 chunks (66.67%)
553 manifests: 3/3 chunks (100.00%)
553 manifests: 3/3 chunks (100.00%)
554 adding file changes
554 adding file changes
555 adding foo/Bar/file.txt revisions
555 adding foo/Bar/file.txt revisions
556 files: 1/3 chunks (33.33%)
556 files: 1/3 chunks (33.33%)
557 adding foo/file.txt revisions
557 adding foo/file.txt revisions
558 files: 2/3 chunks (66.67%)
558 files: 2/3 chunks (66.67%)
559 adding quux/file.py revisions
559 adding quux/file.py revisions
560 files: 3/3 chunks (100.00%)
560 files: 3/3 chunks (100.00%)
561 added 3 changesets with 3 changes to 3 files
561 added 3 changesets with 3 changes to 3 files
562 calling hook pretxnchangegroup.acl: hgext.acl.hook
562 calling hook pretxnchangegroup.acl: hgext.acl.hook
563 acl: acl.allow.branches not enabled
563 acl: acl.allow.branches not enabled
564 acl: acl.deny.branches not enabled
564 acl: acl.deny.branches not enabled
565 acl: acl.allow enabled, 1 entries for user fred
565 acl: acl.allow enabled, 1 entries for user fred
566 acl: acl.deny enabled, 2 entries for user fred
566 acl: acl.deny enabled, 2 entries for user fred
567 acl: branch access granted: "ef1ea85a6374" on branch "default"
567 acl: branch access granted: "ef1ea85a6374" on branch "default"
568 acl: allowing changeset ef1ea85a6374
568 acl: allowing changeset ef1ea85a6374
569 acl: branch access granted: "f9cafe1212c8" on branch "default"
569 acl: branch access granted: "f9cafe1212c8" on branch "default"
570 acl: user fred denied on foo/Bar/file.txt
570 acl: user fred denied on foo/Bar/file.txt
571 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
571 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
572 transaction abort!
572 transaction abort!
573 rollback completed
573 rollback completed
574 abort: acl: access denied for changeset f9cafe1212c8
574 abort: acl: access denied for changeset f9cafe1212c8
575 no rollback information available
575 no rollback information available
576 0:6675d58eff77
576 0:6675d58eff77
577
577
578
578
579 $ echo 'barney is not mentioned => not allowed anywhere'
579 $ echo 'barney is not mentioned => not allowed anywhere'
580 barney is not mentioned => not allowed anywhere
580 barney is not mentioned => not allowed anywhere
581 $ do_push barney
581 $ do_push barney
582 Pushing as user barney
582 Pushing as user barney
583 hgrc = """
583 hgrc = """
584 [hooks]
584 [hooks]
585 pretxnchangegroup.acl = python:hgext.acl.hook
585 pretxnchangegroup.acl = python:hgext.acl.hook
586 [acl]
586 [acl]
587 sources = push
587 sources = push
588 [acl.allow]
588 [acl.allow]
589 foo/** = fred
589 foo/** = fred
590 [acl.deny]
590 [acl.deny]
591 foo/bar/** = fred
591 foo/bar/** = fred
592 foo/Bar/** = fred
592 foo/Bar/** = fred
593 """
593 """
594 pushing to ../b
594 pushing to ../b
595 searching for changes
595 searching for changes
596 3 changesets found
596 3 changesets found
597 list of changesets:
597 list of changesets:
598 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
598 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
599 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
599 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
600 911600dab2ae7a9baff75958b84fe606851ce955
600 911600dab2ae7a9baff75958b84fe606851ce955
601 adding changesets
601 adding changesets
602 bundling: 1 changesets
602 bundling: 1 changesets
603 bundling: 2 changesets
603 bundling: 2 changesets
604 bundling: 3 changesets
604 bundling: 3 changesets
605 bundling: 1/3 manifests (33.33%)
605 bundling: 1/3 manifests (33.33%)
606 bundling: 2/3 manifests (66.67%)
606 bundling: 2/3 manifests (66.67%)
607 bundling: 3/3 manifests (100.00%)
607 bundling: 3/3 manifests (100.00%)
608 bundling: foo/Bar/file.txt 0/3 files (0.00%)
608 bundling: foo/Bar/file.txt 0/3 files (0.00%)
609 bundling: foo/file.txt 1/3 files (33.33%)
609 bundling: foo/file.txt 1/3 files (33.33%)
610 bundling: quux/file.py 2/3 files (66.67%)
610 bundling: quux/file.py 2/3 files (66.67%)
611 changesets: 1 chunks
611 changesets: 1 chunks
612 add changeset ef1ea85a6374
612 add changeset ef1ea85a6374
613 changesets: 2 chunks
613 changesets: 2 chunks
614 add changeset f9cafe1212c8
614 add changeset f9cafe1212c8
615 changesets: 3 chunks
615 changesets: 3 chunks
616 add changeset 911600dab2ae
616 add changeset 911600dab2ae
617 adding manifests
617 adding manifests
618 manifests: 1/3 chunks (33.33%)
618 manifests: 1/3 chunks (33.33%)
619 manifests: 2/3 chunks (66.67%)
619 manifests: 2/3 chunks (66.67%)
620 manifests: 3/3 chunks (100.00%)
620 manifests: 3/3 chunks (100.00%)
621 adding file changes
621 adding file changes
622 adding foo/Bar/file.txt revisions
622 adding foo/Bar/file.txt revisions
623 files: 1/3 chunks (33.33%)
623 files: 1/3 chunks (33.33%)
624 adding foo/file.txt revisions
624 adding foo/file.txt revisions
625 files: 2/3 chunks (66.67%)
625 files: 2/3 chunks (66.67%)
626 adding quux/file.py revisions
626 adding quux/file.py revisions
627 files: 3/3 chunks (100.00%)
627 files: 3/3 chunks (100.00%)
628 added 3 changesets with 3 changes to 3 files
628 added 3 changesets with 3 changes to 3 files
629 calling hook pretxnchangegroup.acl: hgext.acl.hook
629 calling hook pretxnchangegroup.acl: hgext.acl.hook
630 acl: acl.allow.branches not enabled
630 acl: acl.allow.branches not enabled
631 acl: acl.deny.branches not enabled
631 acl: acl.deny.branches not enabled
632 acl: acl.allow enabled, 0 entries for user barney
632 acl: acl.allow enabled, 0 entries for user barney
633 acl: acl.deny enabled, 0 entries for user barney
633 acl: acl.deny enabled, 0 entries for user barney
634 acl: branch access granted: "ef1ea85a6374" on branch "default"
634 acl: branch access granted: "ef1ea85a6374" on branch "default"
635 acl: user barney not allowed on foo/file.txt
635 acl: user barney not allowed on foo/file.txt
636 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
636 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
637 transaction abort!
637 transaction abort!
638 rollback completed
638 rollback completed
639 abort: acl: access denied for changeset ef1ea85a6374
639 abort: acl: access denied for changeset ef1ea85a6374
640 no rollback information available
640 no rollback information available
641 0:6675d58eff77
641 0:6675d58eff77
642
642
643
643
644 barney is allowed everywhere
644 barney is allowed everywhere
645
645
646 $ echo '[acl.allow]' >> $config
646 $ echo '[acl.allow]' >> $config
647 $ echo '** = barney' >> $config
647 $ echo '** = barney' >> $config
648 $ do_push barney
648 $ do_push barney
649 Pushing as user barney
649 Pushing as user barney
650 hgrc = """
650 hgrc = """
651 [hooks]
651 [hooks]
652 pretxnchangegroup.acl = python:hgext.acl.hook
652 pretxnchangegroup.acl = python:hgext.acl.hook
653 [acl]
653 [acl]
654 sources = push
654 sources = push
655 [acl.allow]
655 [acl.allow]
656 foo/** = fred
656 foo/** = fred
657 [acl.deny]
657 [acl.deny]
658 foo/bar/** = fred
658 foo/bar/** = fred
659 foo/Bar/** = fred
659 foo/Bar/** = fred
660 [acl.allow]
660 [acl.allow]
661 ** = barney
661 ** = barney
662 """
662 """
663 pushing to ../b
663 pushing to ../b
664 searching for changes
664 searching for changes
665 3 changesets found
665 3 changesets found
666 list of changesets:
666 list of changesets:
667 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
667 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
668 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
668 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
669 911600dab2ae7a9baff75958b84fe606851ce955
669 911600dab2ae7a9baff75958b84fe606851ce955
670 adding changesets
670 adding changesets
671 bundling: 1 changesets
671 bundling: 1 changesets
672 bundling: 2 changesets
672 bundling: 2 changesets
673 bundling: 3 changesets
673 bundling: 3 changesets
674 bundling: 1/3 manifests (33.33%)
674 bundling: 1/3 manifests (33.33%)
675 bundling: 2/3 manifests (66.67%)
675 bundling: 2/3 manifests (66.67%)
676 bundling: 3/3 manifests (100.00%)
676 bundling: 3/3 manifests (100.00%)
677 bundling: foo/Bar/file.txt 0/3 files (0.00%)
677 bundling: foo/Bar/file.txt 0/3 files (0.00%)
678 bundling: foo/file.txt 1/3 files (33.33%)
678 bundling: foo/file.txt 1/3 files (33.33%)
679 bundling: quux/file.py 2/3 files (66.67%)
679 bundling: quux/file.py 2/3 files (66.67%)
680 changesets: 1 chunks
680 changesets: 1 chunks
681 add changeset ef1ea85a6374
681 add changeset ef1ea85a6374
682 changesets: 2 chunks
682 changesets: 2 chunks
683 add changeset f9cafe1212c8
683 add changeset f9cafe1212c8
684 changesets: 3 chunks
684 changesets: 3 chunks
685 add changeset 911600dab2ae
685 add changeset 911600dab2ae
686 adding manifests
686 adding manifests
687 manifests: 1/3 chunks (33.33%)
687 manifests: 1/3 chunks (33.33%)
688 manifests: 2/3 chunks (66.67%)
688 manifests: 2/3 chunks (66.67%)
689 manifests: 3/3 chunks (100.00%)
689 manifests: 3/3 chunks (100.00%)
690 adding file changes
690 adding file changes
691 adding foo/Bar/file.txt revisions
691 adding foo/Bar/file.txt revisions
692 files: 1/3 chunks (33.33%)
692 files: 1/3 chunks (33.33%)
693 adding foo/file.txt revisions
693 adding foo/file.txt revisions
694 files: 2/3 chunks (66.67%)
694 files: 2/3 chunks (66.67%)
695 adding quux/file.py revisions
695 adding quux/file.py revisions
696 files: 3/3 chunks (100.00%)
696 files: 3/3 chunks (100.00%)
697 added 3 changesets with 3 changes to 3 files
697 added 3 changesets with 3 changes to 3 files
698 calling hook pretxnchangegroup.acl: hgext.acl.hook
698 calling hook pretxnchangegroup.acl: hgext.acl.hook
699 acl: acl.allow.branches not enabled
699 acl: acl.allow.branches not enabled
700 acl: acl.deny.branches not enabled
700 acl: acl.deny.branches not enabled
701 acl: acl.allow enabled, 1 entries for user barney
701 acl: acl.allow enabled, 1 entries for user barney
702 acl: acl.deny enabled, 0 entries for user barney
702 acl: acl.deny enabled, 0 entries for user barney
703 acl: branch access granted: "ef1ea85a6374" on branch "default"
703 acl: branch access granted: "ef1ea85a6374" on branch "default"
704 acl: allowing changeset ef1ea85a6374
704 acl: allowing changeset ef1ea85a6374
705 acl: branch access granted: "f9cafe1212c8" on branch "default"
705 acl: branch access granted: "f9cafe1212c8" on branch "default"
706 acl: allowing changeset f9cafe1212c8
706 acl: allowing changeset f9cafe1212c8
707 acl: branch access granted: "911600dab2ae" on branch "default"
707 acl: branch access granted: "911600dab2ae" on branch "default"
708 acl: allowing changeset 911600dab2ae
708 acl: allowing changeset 911600dab2ae
709 updating the branch cache
709 updating the branch cache
710 checking for updated bookmarks
710 checking for updated bookmarks
711 repository tip rolled back to revision 0 (undo push)
711 repository tip rolled back to revision 0 (undo push)
712 working directory now based on revision 0
712 working directory now based on revision 0
713 0:6675d58eff77
713 0:6675d58eff77
714
714
715
715
716 wilma can change files with a .txt extension
716 wilma can change files with a .txt extension
717
717
718 $ echo '**/*.txt = wilma' >> $config
718 $ echo '**/*.txt = wilma' >> $config
719 $ do_push wilma
719 $ do_push wilma
720 Pushing as user wilma
720 Pushing as user wilma
721 hgrc = """
721 hgrc = """
722 [hooks]
722 [hooks]
723 pretxnchangegroup.acl = python:hgext.acl.hook
723 pretxnchangegroup.acl = python:hgext.acl.hook
724 [acl]
724 [acl]
725 sources = push
725 sources = push
726 [acl.allow]
726 [acl.allow]
727 foo/** = fred
727 foo/** = fred
728 [acl.deny]
728 [acl.deny]
729 foo/bar/** = fred
729 foo/bar/** = fred
730 foo/Bar/** = fred
730 foo/Bar/** = fred
731 [acl.allow]
731 [acl.allow]
732 ** = barney
732 ** = barney
733 **/*.txt = wilma
733 **/*.txt = wilma
734 """
734 """
735 pushing to ../b
735 pushing to ../b
736 searching for changes
736 searching for changes
737 invalidating branch cache (tip differs)
737 invalidating branch cache (tip differs)
738 3 changesets found
738 3 changesets found
739 list of changesets:
739 list of changesets:
740 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
740 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
741 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
741 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
742 911600dab2ae7a9baff75958b84fe606851ce955
742 911600dab2ae7a9baff75958b84fe606851ce955
743 adding changesets
743 adding changesets
744 bundling: 1 changesets
744 bundling: 1 changesets
745 bundling: 2 changesets
745 bundling: 2 changesets
746 bundling: 3 changesets
746 bundling: 3 changesets
747 bundling: 1/3 manifests (33.33%)
747 bundling: 1/3 manifests (33.33%)
748 bundling: 2/3 manifests (66.67%)
748 bundling: 2/3 manifests (66.67%)
749 bundling: 3/3 manifests (100.00%)
749 bundling: 3/3 manifests (100.00%)
750 bundling: foo/Bar/file.txt 0/3 files (0.00%)
750 bundling: foo/Bar/file.txt 0/3 files (0.00%)
751 bundling: foo/file.txt 1/3 files (33.33%)
751 bundling: foo/file.txt 1/3 files (33.33%)
752 bundling: quux/file.py 2/3 files (66.67%)
752 bundling: quux/file.py 2/3 files (66.67%)
753 changesets: 1 chunks
753 changesets: 1 chunks
754 add changeset ef1ea85a6374
754 add changeset ef1ea85a6374
755 changesets: 2 chunks
755 changesets: 2 chunks
756 add changeset f9cafe1212c8
756 add changeset f9cafe1212c8
757 changesets: 3 chunks
757 changesets: 3 chunks
758 add changeset 911600dab2ae
758 add changeset 911600dab2ae
759 adding manifests
759 adding manifests
760 manifests: 1/3 chunks (33.33%)
760 manifests: 1/3 chunks (33.33%)
761 manifests: 2/3 chunks (66.67%)
761 manifests: 2/3 chunks (66.67%)
762 manifests: 3/3 chunks (100.00%)
762 manifests: 3/3 chunks (100.00%)
763 adding file changes
763 adding file changes
764 adding foo/Bar/file.txt revisions
764 adding foo/Bar/file.txt revisions
765 files: 1/3 chunks (33.33%)
765 files: 1/3 chunks (33.33%)
766 adding foo/file.txt revisions
766 adding foo/file.txt revisions
767 files: 2/3 chunks (66.67%)
767 files: 2/3 chunks (66.67%)
768 adding quux/file.py revisions
768 adding quux/file.py revisions
769 files: 3/3 chunks (100.00%)
769 files: 3/3 chunks (100.00%)
770 added 3 changesets with 3 changes to 3 files
770 added 3 changesets with 3 changes to 3 files
771 calling hook pretxnchangegroup.acl: hgext.acl.hook
771 calling hook pretxnchangegroup.acl: hgext.acl.hook
772 acl: acl.allow.branches not enabled
772 acl: acl.allow.branches not enabled
773 acl: acl.deny.branches not enabled
773 acl: acl.deny.branches not enabled
774 acl: acl.allow enabled, 1 entries for user wilma
774 acl: acl.allow enabled, 1 entries for user wilma
775 acl: acl.deny enabled, 0 entries for user wilma
775 acl: acl.deny enabled, 0 entries for user wilma
776 acl: branch access granted: "ef1ea85a6374" on branch "default"
776 acl: branch access granted: "ef1ea85a6374" on branch "default"
777 acl: allowing changeset ef1ea85a6374
777 acl: allowing changeset ef1ea85a6374
778 acl: branch access granted: "f9cafe1212c8" on branch "default"
778 acl: branch access granted: "f9cafe1212c8" on branch "default"
779 acl: allowing changeset f9cafe1212c8
779 acl: allowing changeset f9cafe1212c8
780 acl: branch access granted: "911600dab2ae" on branch "default"
780 acl: branch access granted: "911600dab2ae" on branch "default"
781 acl: user wilma not allowed on quux/file.py
781 acl: user wilma not allowed on quux/file.py
782 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
782 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
783 transaction abort!
783 transaction abort!
784 rollback completed
784 rollback completed
785 abort: acl: access denied for changeset 911600dab2ae
785 abort: acl: access denied for changeset 911600dab2ae
786 no rollback information available
786 no rollback information available
787 0:6675d58eff77
787 0:6675d58eff77
788
788
789
789
790 file specified by acl.config does not exist
790 file specified by acl.config does not exist
791
791
792 $ echo '[acl]' >> $config
792 $ echo '[acl]' >> $config
793 $ echo 'config = ../acl.config' >> $config
793 $ echo 'config = ../acl.config' >> $config
794 $ do_push barney
794 $ do_push barney
795 Pushing as user barney
795 Pushing as user barney
796 hgrc = """
796 hgrc = """
797 [hooks]
797 [hooks]
798 pretxnchangegroup.acl = python:hgext.acl.hook
798 pretxnchangegroup.acl = python:hgext.acl.hook
799 [acl]
799 [acl]
800 sources = push
800 sources = push
801 [acl.allow]
801 [acl.allow]
802 foo/** = fred
802 foo/** = fred
803 [acl.deny]
803 [acl.deny]
804 foo/bar/** = fred
804 foo/bar/** = fred
805 foo/Bar/** = fred
805 foo/Bar/** = fred
806 [acl.allow]
806 [acl.allow]
807 ** = barney
807 ** = barney
808 **/*.txt = wilma
808 **/*.txt = wilma
809 [acl]
809 [acl]
810 config = ../acl.config
810 config = ../acl.config
811 """
811 """
812 pushing to ../b
812 pushing to ../b
813 searching for changes
813 searching for changes
814 3 changesets found
814 3 changesets found
815 list of changesets:
815 list of changesets:
816 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
816 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
817 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
817 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
818 911600dab2ae7a9baff75958b84fe606851ce955
818 911600dab2ae7a9baff75958b84fe606851ce955
819 adding changesets
819 adding changesets
820 bundling: 1 changesets
820 bundling: 1 changesets
821 bundling: 2 changesets
821 bundling: 2 changesets
822 bundling: 3 changesets
822 bundling: 3 changesets
823 bundling: 1/3 manifests (33.33%)
823 bundling: 1/3 manifests (33.33%)
824 bundling: 2/3 manifests (66.67%)
824 bundling: 2/3 manifests (66.67%)
825 bundling: 3/3 manifests (100.00%)
825 bundling: 3/3 manifests (100.00%)
826 bundling: foo/Bar/file.txt 0/3 files (0.00%)
826 bundling: foo/Bar/file.txt 0/3 files (0.00%)
827 bundling: foo/file.txt 1/3 files (33.33%)
827 bundling: foo/file.txt 1/3 files (33.33%)
828 bundling: quux/file.py 2/3 files (66.67%)
828 bundling: quux/file.py 2/3 files (66.67%)
829 changesets: 1 chunks
829 changesets: 1 chunks
830 add changeset ef1ea85a6374
830 add changeset ef1ea85a6374
831 changesets: 2 chunks
831 changesets: 2 chunks
832 add changeset f9cafe1212c8
832 add changeset f9cafe1212c8
833 changesets: 3 chunks
833 changesets: 3 chunks
834 add changeset 911600dab2ae
834 add changeset 911600dab2ae
835 adding manifests
835 adding manifests
836 manifests: 1/3 chunks (33.33%)
836 manifests: 1/3 chunks (33.33%)
837 manifests: 2/3 chunks (66.67%)
837 manifests: 2/3 chunks (66.67%)
838 manifests: 3/3 chunks (100.00%)
838 manifests: 3/3 chunks (100.00%)
839 adding file changes
839 adding file changes
840 adding foo/Bar/file.txt revisions
840 adding foo/Bar/file.txt revisions
841 files: 1/3 chunks (33.33%)
841 files: 1/3 chunks (33.33%)
842 adding foo/file.txt revisions
842 adding foo/file.txt revisions
843 files: 2/3 chunks (66.67%)
843 files: 2/3 chunks (66.67%)
844 adding quux/file.py revisions
844 adding quux/file.py revisions
845 files: 3/3 chunks (100.00%)
845 files: 3/3 chunks (100.00%)
846 added 3 changesets with 3 changes to 3 files
846 added 3 changesets with 3 changes to 3 files
847 calling hook pretxnchangegroup.acl: hgext.acl.hook
847 calling hook pretxnchangegroup.acl: hgext.acl.hook
848 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
848 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
849 transaction abort!
849 transaction abort!
850 rollback completed
850 rollback completed
851 abort: No such file or directory: ../acl.config
851 abort: No such file or directory: ../acl.config
852 no rollback information available
852 no rollback information available
853 0:6675d58eff77
853 0:6675d58eff77
854
854
855
855
856 betty is allowed inside foo/ by a acl.config file
856 betty is allowed inside foo/ by a acl.config file
857
857
858 $ echo '[acl.allow]' >> acl.config
858 $ echo '[acl.allow]' >> acl.config
859 $ echo 'foo/** = betty' >> acl.config
859 $ echo 'foo/** = betty' >> acl.config
860 $ do_push betty
860 $ do_push betty
861 Pushing as user betty
861 Pushing as user betty
862 hgrc = """
862 hgrc = """
863 [hooks]
863 [hooks]
864 pretxnchangegroup.acl = python:hgext.acl.hook
864 pretxnchangegroup.acl = python:hgext.acl.hook
865 [acl]
865 [acl]
866 sources = push
866 sources = push
867 [acl.allow]
867 [acl.allow]
868 foo/** = fred
868 foo/** = fred
869 [acl.deny]
869 [acl.deny]
870 foo/bar/** = fred
870 foo/bar/** = fred
871 foo/Bar/** = fred
871 foo/Bar/** = fred
872 [acl.allow]
872 [acl.allow]
873 ** = barney
873 ** = barney
874 **/*.txt = wilma
874 **/*.txt = wilma
875 [acl]
875 [acl]
876 config = ../acl.config
876 config = ../acl.config
877 """
877 """
878 acl.config = """
878 acl.config = """
879 [acl.allow]
879 [acl.allow]
880 foo/** = betty
880 foo/** = betty
881 """
881 """
882 pushing to ../b
882 pushing to ../b
883 searching for changes
883 searching for changes
884 3 changesets found
884 3 changesets found
885 list of changesets:
885 list of changesets:
886 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
886 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
887 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
887 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
888 911600dab2ae7a9baff75958b84fe606851ce955
888 911600dab2ae7a9baff75958b84fe606851ce955
889 adding changesets
889 adding changesets
890 bundling: 1 changesets
890 bundling: 1 changesets
891 bundling: 2 changesets
891 bundling: 2 changesets
892 bundling: 3 changesets
892 bundling: 3 changesets
893 bundling: 1/3 manifests (33.33%)
893 bundling: 1/3 manifests (33.33%)
894 bundling: 2/3 manifests (66.67%)
894 bundling: 2/3 manifests (66.67%)
895 bundling: 3/3 manifests (100.00%)
895 bundling: 3/3 manifests (100.00%)
896 bundling: foo/Bar/file.txt 0/3 files (0.00%)
896 bundling: foo/Bar/file.txt 0/3 files (0.00%)
897 bundling: foo/file.txt 1/3 files (33.33%)
897 bundling: foo/file.txt 1/3 files (33.33%)
898 bundling: quux/file.py 2/3 files (66.67%)
898 bundling: quux/file.py 2/3 files (66.67%)
899 changesets: 1 chunks
899 changesets: 1 chunks
900 add changeset ef1ea85a6374
900 add changeset ef1ea85a6374
901 changesets: 2 chunks
901 changesets: 2 chunks
902 add changeset f9cafe1212c8
902 add changeset f9cafe1212c8
903 changesets: 3 chunks
903 changesets: 3 chunks
904 add changeset 911600dab2ae
904 add changeset 911600dab2ae
905 adding manifests
905 adding manifests
906 manifests: 1/3 chunks (33.33%)
906 manifests: 1/3 chunks (33.33%)
907 manifests: 2/3 chunks (66.67%)
907 manifests: 2/3 chunks (66.67%)
908 manifests: 3/3 chunks (100.00%)
908 manifests: 3/3 chunks (100.00%)
909 adding file changes
909 adding file changes
910 adding foo/Bar/file.txt revisions
910 adding foo/Bar/file.txt revisions
911 files: 1/3 chunks (33.33%)
911 files: 1/3 chunks (33.33%)
912 adding foo/file.txt revisions
912 adding foo/file.txt revisions
913 files: 2/3 chunks (66.67%)
913 files: 2/3 chunks (66.67%)
914 adding quux/file.py revisions
914 adding quux/file.py revisions
915 files: 3/3 chunks (100.00%)
915 files: 3/3 chunks (100.00%)
916 added 3 changesets with 3 changes to 3 files
916 added 3 changesets with 3 changes to 3 files
917 calling hook pretxnchangegroup.acl: hgext.acl.hook
917 calling hook pretxnchangegroup.acl: hgext.acl.hook
918 acl: acl.allow.branches not enabled
918 acl: acl.allow.branches not enabled
919 acl: acl.deny.branches not enabled
919 acl: acl.deny.branches not enabled
920 acl: acl.allow enabled, 1 entries for user betty
920 acl: acl.allow enabled, 1 entries for user betty
921 acl: acl.deny enabled, 0 entries for user betty
921 acl: acl.deny enabled, 0 entries for user betty
922 acl: branch access granted: "ef1ea85a6374" on branch "default"
922 acl: branch access granted: "ef1ea85a6374" on branch "default"
923 acl: allowing changeset ef1ea85a6374
923 acl: allowing changeset ef1ea85a6374
924 acl: branch access granted: "f9cafe1212c8" on branch "default"
924 acl: branch access granted: "f9cafe1212c8" on branch "default"
925 acl: allowing changeset f9cafe1212c8
925 acl: allowing changeset f9cafe1212c8
926 acl: branch access granted: "911600dab2ae" on branch "default"
926 acl: branch access granted: "911600dab2ae" on branch "default"
927 acl: user betty not allowed on quux/file.py
927 acl: user betty not allowed on quux/file.py
928 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
928 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
929 transaction abort!
929 transaction abort!
930 rollback completed
930 rollback completed
931 abort: acl: access denied for changeset 911600dab2ae
931 abort: acl: access denied for changeset 911600dab2ae
932 no rollback information available
932 no rollback information available
933 0:6675d58eff77
933 0:6675d58eff77
934
934
935
935
936 acl.config can set only [acl.allow]/[acl.deny]
936 acl.config can set only [acl.allow]/[acl.deny]
937
937
938 $ echo '[hooks]' >> acl.config
938 $ echo '[hooks]' >> acl.config
939 $ echo 'changegroup.acl = false' >> acl.config
939 $ echo 'changegroup.acl = false' >> acl.config
940 $ do_push barney
940 $ do_push barney
941 Pushing as user barney
941 Pushing as user barney
942 hgrc = """
942 hgrc = """
943 [hooks]
943 [hooks]
944 pretxnchangegroup.acl = python:hgext.acl.hook
944 pretxnchangegroup.acl = python:hgext.acl.hook
945 [acl]
945 [acl]
946 sources = push
946 sources = push
947 [acl.allow]
947 [acl.allow]
948 foo/** = fred
948 foo/** = fred
949 [acl.deny]
949 [acl.deny]
950 foo/bar/** = fred
950 foo/bar/** = fred
951 foo/Bar/** = fred
951 foo/Bar/** = fred
952 [acl.allow]
952 [acl.allow]
953 ** = barney
953 ** = barney
954 **/*.txt = wilma
954 **/*.txt = wilma
955 [acl]
955 [acl]
956 config = ../acl.config
956 config = ../acl.config
957 """
957 """
958 acl.config = """
958 acl.config = """
959 [acl.allow]
959 [acl.allow]
960 foo/** = betty
960 foo/** = betty
961 [hooks]
961 [hooks]
962 changegroup.acl = false
962 changegroup.acl = false
963 """
963 """
964 pushing to ../b
964 pushing to ../b
965 searching for changes
965 searching for changes
966 3 changesets found
966 3 changesets found
967 list of changesets:
967 list of changesets:
968 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
968 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
969 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
969 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
970 911600dab2ae7a9baff75958b84fe606851ce955
970 911600dab2ae7a9baff75958b84fe606851ce955
971 adding changesets
971 adding changesets
972 bundling: 1 changesets
972 bundling: 1 changesets
973 bundling: 2 changesets
973 bundling: 2 changesets
974 bundling: 3 changesets
974 bundling: 3 changesets
975 bundling: 1/3 manifests (33.33%)
975 bundling: 1/3 manifests (33.33%)
976 bundling: 2/3 manifests (66.67%)
976 bundling: 2/3 manifests (66.67%)
977 bundling: 3/3 manifests (100.00%)
977 bundling: 3/3 manifests (100.00%)
978 bundling: foo/Bar/file.txt 0/3 files (0.00%)
978 bundling: foo/Bar/file.txt 0/3 files (0.00%)
979 bundling: foo/file.txt 1/3 files (33.33%)
979 bundling: foo/file.txt 1/3 files (33.33%)
980 bundling: quux/file.py 2/3 files (66.67%)
980 bundling: quux/file.py 2/3 files (66.67%)
981 changesets: 1 chunks
981 changesets: 1 chunks
982 add changeset ef1ea85a6374
982 add changeset ef1ea85a6374
983 changesets: 2 chunks
983 changesets: 2 chunks
984 add changeset f9cafe1212c8
984 add changeset f9cafe1212c8
985 changesets: 3 chunks
985 changesets: 3 chunks
986 add changeset 911600dab2ae
986 add changeset 911600dab2ae
987 adding manifests
987 adding manifests
988 manifests: 1/3 chunks (33.33%)
988 manifests: 1/3 chunks (33.33%)
989 manifests: 2/3 chunks (66.67%)
989 manifests: 2/3 chunks (66.67%)
990 manifests: 3/3 chunks (100.00%)
990 manifests: 3/3 chunks (100.00%)
991 adding file changes
991 adding file changes
992 adding foo/Bar/file.txt revisions
992 adding foo/Bar/file.txt revisions
993 files: 1/3 chunks (33.33%)
993 files: 1/3 chunks (33.33%)
994 adding foo/file.txt revisions
994 adding foo/file.txt revisions
995 files: 2/3 chunks (66.67%)
995 files: 2/3 chunks (66.67%)
996 adding quux/file.py revisions
996 adding quux/file.py revisions
997 files: 3/3 chunks (100.00%)
997 files: 3/3 chunks (100.00%)
998 added 3 changesets with 3 changes to 3 files
998 added 3 changesets with 3 changes to 3 files
999 calling hook pretxnchangegroup.acl: hgext.acl.hook
999 calling hook pretxnchangegroup.acl: hgext.acl.hook
1000 acl: acl.allow.branches not enabled
1000 acl: acl.allow.branches not enabled
1001 acl: acl.deny.branches not enabled
1001 acl: acl.deny.branches not enabled
1002 acl: acl.allow enabled, 1 entries for user barney
1002 acl: acl.allow enabled, 1 entries for user barney
1003 acl: acl.deny enabled, 0 entries for user barney
1003 acl: acl.deny enabled, 0 entries for user barney
1004 acl: branch access granted: "ef1ea85a6374" on branch "default"
1004 acl: branch access granted: "ef1ea85a6374" on branch "default"
1005 acl: allowing changeset ef1ea85a6374
1005 acl: allowing changeset ef1ea85a6374
1006 acl: branch access granted: "f9cafe1212c8" on branch "default"
1006 acl: branch access granted: "f9cafe1212c8" on branch "default"
1007 acl: allowing changeset f9cafe1212c8
1007 acl: allowing changeset f9cafe1212c8
1008 acl: branch access granted: "911600dab2ae" on branch "default"
1008 acl: branch access granted: "911600dab2ae" on branch "default"
1009 acl: allowing changeset 911600dab2ae
1009 acl: allowing changeset 911600dab2ae
1010 updating the branch cache
1010 updating the branch cache
1011 checking for updated bookmarks
1011 checking for updated bookmarks
1012 repository tip rolled back to revision 0 (undo push)
1012 repository tip rolled back to revision 0 (undo push)
1013 working directory now based on revision 0
1013 working directory now based on revision 0
1014 0:6675d58eff77
1014 0:6675d58eff77
1015
1015
1016
1016
1017 asterisk
1017 asterisk
1018
1018
1019 $ init_config
1019 $ init_config
1020
1020
1021 asterisk test
1021 asterisk test
1022
1022
1023 $ echo '[acl.allow]' >> $config
1023 $ echo '[acl.allow]' >> $config
1024 $ echo "** = fred" >> $config
1024 $ echo "** = fred" >> $config
1025
1025
1026 fred is always allowed
1026 fred is always allowed
1027
1027
1028 $ do_push fred
1028 $ do_push fred
1029 Pushing as user fred
1029 Pushing as user fred
1030 hgrc = """
1030 hgrc = """
1031 [acl]
1031 [acl]
1032 sources = push
1032 sources = push
1033 [extensions]
1033 [extensions]
1034 [acl.allow]
1034 [acl.allow]
1035 ** = fred
1035 ** = fred
1036 """
1036 """
1037 pushing to ../b
1037 pushing to ../b
1038 searching for changes
1038 searching for changes
1039 invalidating branch cache (tip differs)
1039 invalidating branch cache (tip differs)
1040 3 changesets found
1040 3 changesets found
1041 list of changesets:
1041 list of changesets:
1042 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1042 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1043 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1043 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1044 911600dab2ae7a9baff75958b84fe606851ce955
1044 911600dab2ae7a9baff75958b84fe606851ce955
1045 adding changesets
1045 adding changesets
1046 bundling: 1 changesets
1046 bundling: 1 changesets
1047 bundling: 2 changesets
1047 bundling: 2 changesets
1048 bundling: 3 changesets
1048 bundling: 3 changesets
1049 bundling: 1/3 manifests (33.33%)
1049 bundling: 1/3 manifests (33.33%)
1050 bundling: 2/3 manifests (66.67%)
1050 bundling: 2/3 manifests (66.67%)
1051 bundling: 3/3 manifests (100.00%)
1051 bundling: 3/3 manifests (100.00%)
1052 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1052 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1053 bundling: foo/file.txt 1/3 files (33.33%)
1053 bundling: foo/file.txt 1/3 files (33.33%)
1054 bundling: quux/file.py 2/3 files (66.67%)
1054 bundling: quux/file.py 2/3 files (66.67%)
1055 changesets: 1 chunks
1055 changesets: 1 chunks
1056 add changeset ef1ea85a6374
1056 add changeset ef1ea85a6374
1057 changesets: 2 chunks
1057 changesets: 2 chunks
1058 add changeset f9cafe1212c8
1058 add changeset f9cafe1212c8
1059 changesets: 3 chunks
1059 changesets: 3 chunks
1060 add changeset 911600dab2ae
1060 add changeset 911600dab2ae
1061 adding manifests
1061 adding manifests
1062 manifests: 1/3 chunks (33.33%)
1062 manifests: 1/3 chunks (33.33%)
1063 manifests: 2/3 chunks (66.67%)
1063 manifests: 2/3 chunks (66.67%)
1064 manifests: 3/3 chunks (100.00%)
1064 manifests: 3/3 chunks (100.00%)
1065 adding file changes
1065 adding file changes
1066 adding foo/Bar/file.txt revisions
1066 adding foo/Bar/file.txt revisions
1067 files: 1/3 chunks (33.33%)
1067 files: 1/3 chunks (33.33%)
1068 adding foo/file.txt revisions
1068 adding foo/file.txt revisions
1069 files: 2/3 chunks (66.67%)
1069 files: 2/3 chunks (66.67%)
1070 adding quux/file.py revisions
1070 adding quux/file.py revisions
1071 files: 3/3 chunks (100.00%)
1071 files: 3/3 chunks (100.00%)
1072 added 3 changesets with 3 changes to 3 files
1072 added 3 changesets with 3 changes to 3 files
1073 calling hook pretxnchangegroup.acl: hgext.acl.hook
1073 calling hook pretxnchangegroup.acl: hgext.acl.hook
1074 acl: acl.allow.branches not enabled
1074 acl: acl.allow.branches not enabled
1075 acl: acl.deny.branches not enabled
1075 acl: acl.deny.branches not enabled
1076 acl: acl.allow enabled, 1 entries for user fred
1076 acl: acl.allow enabled, 1 entries for user fred
1077 acl: acl.deny not enabled
1077 acl: acl.deny not enabled
1078 acl: branch access granted: "ef1ea85a6374" on branch "default"
1078 acl: branch access granted: "ef1ea85a6374" on branch "default"
1079 acl: allowing changeset ef1ea85a6374
1079 acl: allowing changeset ef1ea85a6374
1080 acl: branch access granted: "f9cafe1212c8" on branch "default"
1080 acl: branch access granted: "f9cafe1212c8" on branch "default"
1081 acl: allowing changeset f9cafe1212c8
1081 acl: allowing changeset f9cafe1212c8
1082 acl: branch access granted: "911600dab2ae" on branch "default"
1082 acl: branch access granted: "911600dab2ae" on branch "default"
1083 acl: allowing changeset 911600dab2ae
1083 acl: allowing changeset 911600dab2ae
1084 updating the branch cache
1084 updating the branch cache
1085 checking for updated bookmarks
1085 checking for updated bookmarks
1086 repository tip rolled back to revision 0 (undo push)
1086 repository tip rolled back to revision 0 (undo push)
1087 working directory now based on revision 0
1087 working directory now based on revision 0
1088 0:6675d58eff77
1088 0:6675d58eff77
1089
1089
1090
1090
1091 $ echo '[acl.deny]' >> $config
1091 $ echo '[acl.deny]' >> $config
1092 $ echo "foo/Bar/** = *" >> $config
1092 $ echo "foo/Bar/** = *" >> $config
1093
1093
1094 no one is allowed inside foo/Bar/
1094 no one is allowed inside foo/Bar/
1095
1095
1096 $ do_push fred
1096 $ do_push fred
1097 Pushing as user fred
1097 Pushing as user fred
1098 hgrc = """
1098 hgrc = """
1099 [acl]
1099 [acl]
1100 sources = push
1100 sources = push
1101 [extensions]
1101 [extensions]
1102 [acl.allow]
1102 [acl.allow]
1103 ** = fred
1103 ** = fred
1104 [acl.deny]
1104 [acl.deny]
1105 foo/Bar/** = *
1105 foo/Bar/** = *
1106 """
1106 """
1107 pushing to ../b
1107 pushing to ../b
1108 searching for changes
1108 searching for changes
1109 invalidating branch cache (tip differs)
1109 invalidating branch cache (tip differs)
1110 3 changesets found
1110 3 changesets found
1111 list of changesets:
1111 list of changesets:
1112 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1112 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1113 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1113 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1114 911600dab2ae7a9baff75958b84fe606851ce955
1114 911600dab2ae7a9baff75958b84fe606851ce955
1115 adding changesets
1115 adding changesets
1116 bundling: 1 changesets
1116 bundling: 1 changesets
1117 bundling: 2 changesets
1117 bundling: 2 changesets
1118 bundling: 3 changesets
1118 bundling: 3 changesets
1119 bundling: 1/3 manifests (33.33%)
1119 bundling: 1/3 manifests (33.33%)
1120 bundling: 2/3 manifests (66.67%)
1120 bundling: 2/3 manifests (66.67%)
1121 bundling: 3/3 manifests (100.00%)
1121 bundling: 3/3 manifests (100.00%)
1122 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1122 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1123 bundling: foo/file.txt 1/3 files (33.33%)
1123 bundling: foo/file.txt 1/3 files (33.33%)
1124 bundling: quux/file.py 2/3 files (66.67%)
1124 bundling: quux/file.py 2/3 files (66.67%)
1125 changesets: 1 chunks
1125 changesets: 1 chunks
1126 add changeset ef1ea85a6374
1126 add changeset ef1ea85a6374
1127 changesets: 2 chunks
1127 changesets: 2 chunks
1128 add changeset f9cafe1212c8
1128 add changeset f9cafe1212c8
1129 changesets: 3 chunks
1129 changesets: 3 chunks
1130 add changeset 911600dab2ae
1130 add changeset 911600dab2ae
1131 adding manifests
1131 adding manifests
1132 manifests: 1/3 chunks (33.33%)
1132 manifests: 1/3 chunks (33.33%)
1133 manifests: 2/3 chunks (66.67%)
1133 manifests: 2/3 chunks (66.67%)
1134 manifests: 3/3 chunks (100.00%)
1134 manifests: 3/3 chunks (100.00%)
1135 adding file changes
1135 adding file changes
1136 adding foo/Bar/file.txt revisions
1136 adding foo/Bar/file.txt revisions
1137 files: 1/3 chunks (33.33%)
1137 files: 1/3 chunks (33.33%)
1138 adding foo/file.txt revisions
1138 adding foo/file.txt revisions
1139 files: 2/3 chunks (66.67%)
1139 files: 2/3 chunks (66.67%)
1140 adding quux/file.py revisions
1140 adding quux/file.py revisions
1141 files: 3/3 chunks (100.00%)
1141 files: 3/3 chunks (100.00%)
1142 added 3 changesets with 3 changes to 3 files
1142 added 3 changesets with 3 changes to 3 files
1143 calling hook pretxnchangegroup.acl: hgext.acl.hook
1143 calling hook pretxnchangegroup.acl: hgext.acl.hook
1144 acl: acl.allow.branches not enabled
1144 acl: acl.allow.branches not enabled
1145 acl: acl.deny.branches not enabled
1145 acl: acl.deny.branches not enabled
1146 acl: acl.allow enabled, 1 entries for user fred
1146 acl: acl.allow enabled, 1 entries for user fred
1147 acl: acl.deny enabled, 1 entries for user fred
1147 acl: acl.deny enabled, 1 entries for user fred
1148 acl: branch access granted: "ef1ea85a6374" on branch "default"
1148 acl: branch access granted: "ef1ea85a6374" on branch "default"
1149 acl: allowing changeset ef1ea85a6374
1149 acl: allowing changeset ef1ea85a6374
1150 acl: branch access granted: "f9cafe1212c8" on branch "default"
1150 acl: branch access granted: "f9cafe1212c8" on branch "default"
1151 acl: user fred denied on foo/Bar/file.txt
1151 acl: user fred denied on foo/Bar/file.txt
1152 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
1152 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
1153 transaction abort!
1153 transaction abort!
1154 rollback completed
1154 rollback completed
1155 abort: acl: access denied for changeset f9cafe1212c8
1155 abort: acl: access denied for changeset f9cafe1212c8
1156 no rollback information available
1156 no rollback information available
1157 0:6675d58eff77
1157 0:6675d58eff77
1158
1158
1159
1159
1160 Groups
1160 Groups
1161
1161
1162 $ init_config
1162 $ init_config
1163
1163
1164 OS-level groups
1164 OS-level groups
1165
1165
1166 $ echo '[acl.allow]' >> $config
1166 $ echo '[acl.allow]' >> $config
1167 $ echo "** = @group1" >> $config
1167 $ echo "** = @group1" >> $config
1168
1168
1169 @group1 is always allowed
1169 @group1 is always allowed
1170
1170
1171 $ do_push fred
1171 $ do_push fred
1172 Pushing as user fred
1172 Pushing as user fred
1173 hgrc = """
1173 hgrc = """
1174 [acl]
1174 [acl]
1175 sources = push
1175 sources = push
1176 [extensions]
1176 [extensions]
1177 [acl.allow]
1177 [acl.allow]
1178 ** = @group1
1178 ** = @group1
1179 """
1179 """
1180 pushing to ../b
1180 pushing to ../b
1181 searching for changes
1181 searching for changes
1182 3 changesets found
1182 3 changesets found
1183 list of changesets:
1183 list of changesets:
1184 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1184 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1185 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1185 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1186 911600dab2ae7a9baff75958b84fe606851ce955
1186 911600dab2ae7a9baff75958b84fe606851ce955
1187 adding changesets
1187 adding changesets
1188 bundling: 1 changesets
1188 bundling: 1 changesets
1189 bundling: 2 changesets
1189 bundling: 2 changesets
1190 bundling: 3 changesets
1190 bundling: 3 changesets
1191 bundling: 1/3 manifests (33.33%)
1191 bundling: 1/3 manifests (33.33%)
1192 bundling: 2/3 manifests (66.67%)
1192 bundling: 2/3 manifests (66.67%)
1193 bundling: 3/3 manifests (100.00%)
1193 bundling: 3/3 manifests (100.00%)
1194 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1194 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1195 bundling: foo/file.txt 1/3 files (33.33%)
1195 bundling: foo/file.txt 1/3 files (33.33%)
1196 bundling: quux/file.py 2/3 files (66.67%)
1196 bundling: quux/file.py 2/3 files (66.67%)
1197 changesets: 1 chunks
1197 changesets: 1 chunks
1198 add changeset ef1ea85a6374
1198 add changeset ef1ea85a6374
1199 changesets: 2 chunks
1199 changesets: 2 chunks
1200 add changeset f9cafe1212c8
1200 add changeset f9cafe1212c8
1201 changesets: 3 chunks
1201 changesets: 3 chunks
1202 add changeset 911600dab2ae
1202 add changeset 911600dab2ae
1203 adding manifests
1203 adding manifests
1204 manifests: 1/3 chunks (33.33%)
1204 manifests: 1/3 chunks (33.33%)
1205 manifests: 2/3 chunks (66.67%)
1205 manifests: 2/3 chunks (66.67%)
1206 manifests: 3/3 chunks (100.00%)
1206 manifests: 3/3 chunks (100.00%)
1207 adding file changes
1207 adding file changes
1208 adding foo/Bar/file.txt revisions
1208 adding foo/Bar/file.txt revisions
1209 files: 1/3 chunks (33.33%)
1209 files: 1/3 chunks (33.33%)
1210 adding foo/file.txt revisions
1210 adding foo/file.txt revisions
1211 files: 2/3 chunks (66.67%)
1211 files: 2/3 chunks (66.67%)
1212 adding quux/file.py revisions
1212 adding quux/file.py revisions
1213 files: 3/3 chunks (100.00%)
1213 files: 3/3 chunks (100.00%)
1214 added 3 changesets with 3 changes to 3 files
1214 added 3 changesets with 3 changes to 3 files
1215 calling hook pretxnchangegroup.acl: hgext.acl.hook
1215 calling hook pretxnchangegroup.acl: hgext.acl.hook
1216 acl: acl.allow.branches not enabled
1216 acl: acl.allow.branches not enabled
1217 acl: acl.deny.branches not enabled
1217 acl: acl.deny.branches not enabled
1218 acl: "group1" not defined in [acl.groups]
1218 acl: "group1" not defined in [acl.groups]
1219 acl: acl.allow enabled, 1 entries for user fred
1219 acl: acl.allow enabled, 1 entries for user fred
1220 acl: acl.deny not enabled
1220 acl: acl.deny not enabled
1221 acl: branch access granted: "ef1ea85a6374" on branch "default"
1221 acl: branch access granted: "ef1ea85a6374" on branch "default"
1222 acl: allowing changeset ef1ea85a6374
1222 acl: allowing changeset ef1ea85a6374
1223 acl: branch access granted: "f9cafe1212c8" on branch "default"
1223 acl: branch access granted: "f9cafe1212c8" on branch "default"
1224 acl: allowing changeset f9cafe1212c8
1224 acl: allowing changeset f9cafe1212c8
1225 acl: branch access granted: "911600dab2ae" on branch "default"
1225 acl: branch access granted: "911600dab2ae" on branch "default"
1226 acl: allowing changeset 911600dab2ae
1226 acl: allowing changeset 911600dab2ae
1227 updating the branch cache
1227 updating the branch cache
1228 checking for updated bookmarks
1228 checking for updated bookmarks
1229 repository tip rolled back to revision 0 (undo push)
1229 repository tip rolled back to revision 0 (undo push)
1230 working directory now based on revision 0
1230 working directory now based on revision 0
1231 0:6675d58eff77
1231 0:6675d58eff77
1232
1232
1233
1233
1234 $ echo '[acl.deny]' >> $config
1234 $ echo '[acl.deny]' >> $config
1235 $ echo "foo/Bar/** = @group1" >> $config
1235 $ echo "foo/Bar/** = @group1" >> $config
1236
1236
1237 @group is allowed inside anything but foo/Bar/
1237 @group is allowed inside anything but foo/Bar/
1238
1238
1239 $ do_push fred
1239 $ do_push fred
1240 Pushing as user fred
1240 Pushing as user fred
1241 hgrc = """
1241 hgrc = """
1242 [acl]
1242 [acl]
1243 sources = push
1243 sources = push
1244 [extensions]
1244 [extensions]
1245 [acl.allow]
1245 [acl.allow]
1246 ** = @group1
1246 ** = @group1
1247 [acl.deny]
1247 [acl.deny]
1248 foo/Bar/** = @group1
1248 foo/Bar/** = @group1
1249 """
1249 """
1250 pushing to ../b
1250 pushing to ../b
1251 searching for changes
1251 searching for changes
1252 invalidating branch cache (tip differs)
1252 invalidating branch cache (tip differs)
1253 3 changesets found
1253 3 changesets found
1254 list of changesets:
1254 list of changesets:
1255 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1255 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1256 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1256 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1257 911600dab2ae7a9baff75958b84fe606851ce955
1257 911600dab2ae7a9baff75958b84fe606851ce955
1258 adding changesets
1258 adding changesets
1259 bundling: 1 changesets
1259 bundling: 1 changesets
1260 bundling: 2 changesets
1260 bundling: 2 changesets
1261 bundling: 3 changesets
1261 bundling: 3 changesets
1262 bundling: 1/3 manifests (33.33%)
1262 bundling: 1/3 manifests (33.33%)
1263 bundling: 2/3 manifests (66.67%)
1263 bundling: 2/3 manifests (66.67%)
1264 bundling: 3/3 manifests (100.00%)
1264 bundling: 3/3 manifests (100.00%)
1265 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1265 bundling: foo/Bar/file.txt 0/3 files (0.00%)
1266 bundling: foo/file.txt 1/3 files (33.33%)
1266 bundling: foo/file.txt 1/3 files (33.33%)
1267 bundling: quux/file.py 2/3 files (66.67%)
1267 bundling: quux/file.py 2/3 files (66.67%)
1268 changesets: 1 chunks
1268 changesets: 1 chunks
1269 add changeset ef1ea85a6374
1269 add changeset ef1ea85a6374
1270 changesets: 2 chunks
1270 changesets: 2 chunks
1271 add changeset f9cafe1212c8
1271 add changeset f9cafe1212c8
1272 changesets: 3 chunks
1272 changesets: 3 chunks
1273 add changeset 911600dab2ae
1273 add changeset 911600dab2ae
1274 adding manifests
1274 adding manifests
1275 manifests: 1/3 chunks (33.33%)
1275 manifests: 1/3 chunks (33.33%)
1276 manifests: 2/3 chunks (66.67%)
1276 manifests: 2/3 chunks (66.67%)
1277 manifests: 3/3 chunks (100.00%)
1277 manifests: 3/3 chunks (100.00%)
1278 adding file changes
1278 adding file changes
1279 adding foo/Bar/file.txt revisions
1279 adding foo/Bar/file.txt revisions
1280 files: 1/3 chunks (33.33%)
1280 files: 1/3 chunks (33.33%)
1281 adding foo/file.txt revisions
1281 adding foo/file.txt revisions
1282 files: 2/3 chunks (66.67%)
1282 files: 2/3 chunks (66.67%)
1283 adding quux/file.py revisions
1283 adding quux/file.py revisions
1284 files: 3/3 chunks (100.00%)
1284 files: 3/3 chunks (100.00%)
1285 added 3 changesets with 3 changes to 3 files
1285 added 3 changesets with 3 changes to 3 files
1286 calling hook pretxnchangegroup.acl: hgext.acl.hook
1286 calling hook pretxnchangegroup.acl: hgext.acl.hook
1287 acl: acl.allow.branches not enabled
1287 acl: acl.allow.branches not enabled
1288 acl: acl.deny.branches not enabled
1288 acl: acl.deny.branches not enabled
1289 acl: "group1" not defined in [acl.groups]
1289 acl: "group1" not defined in [acl.groups]
1290 acl: acl.allow enabled, 1 entries for user fred
1290 acl: acl.allow enabled, 1 entries for user fred
1291 acl: "group1" not defined in [acl.groups]
1291 acl: "group1" not defined in [acl.groups]
1292 acl: acl.deny enabled, 1 entries for user fred
1292 acl: acl.deny enabled, 1 entries for user fred
1293 acl: branch access granted: "ef1ea85a6374" on branch "default"
1293 acl: branch access granted: "ef1ea85a6374" on branch "default"
1294 acl: allowing changeset ef1ea85a6374
1294 acl: allowing changeset ef1ea85a6374
1295 acl: branch access granted: "f9cafe1212c8" on branch "default"
1295 acl: branch access granted: "f9cafe1212c8" on branch "default"
1296 acl: user fred denied on foo/Bar/file.txt
1296 acl: user fred denied on foo/Bar/file.txt
1297 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
1297 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
1298 transaction abort!
1298 transaction abort!
1299 rollback completed
1299 rollback completed
1300 abort: acl: access denied for changeset f9cafe1212c8
1300 abort: acl: access denied for changeset f9cafe1212c8
1301 no rollback information available
1301 no rollback information available
1302 0:6675d58eff77
1302 0:6675d58eff77
1303
1303
1304
1304
1305 Invalid group
1305 Invalid group
1306
1306
1307 Disable the fakegroups trick to get real failures
1307 Disable the fakegroups trick to get real failures
1308
1308
1309 $ grep -v fakegroups $config > config.tmp
1309 $ grep -v fakegroups $config > config.tmp
1310 $ mv config.tmp $config
1310 $ mv config.tmp $config
1311 $ echo '[acl.allow]' >> $config
1311 $ echo '[acl.allow]' >> $config
1312 $ echo "** = @unlikelytoexist" >> $config
1312 $ echo "** = @unlikelytoexist" >> $config
1313 $ do_push fred 2>&1 | grep unlikelytoexist
1313 $ do_push fred 2>&1 | grep unlikelytoexist
1314 ** = @unlikelytoexist
1314 ** = @unlikelytoexist
1315 acl: "unlikelytoexist" not defined in [acl.groups]
1315 acl: "unlikelytoexist" not defined in [acl.groups]
1316 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1316 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1317 abort: group 'unlikelytoexist' is undefined
1317 abort: group 'unlikelytoexist' is undefined
1318
1318
1319
1319
1320 Branch acl tests setup
1320 Branch acl tests setup
1321
1321
1322 $ init_config
1322 $ init_config
1323 $ cd b
1323 $ cd b
1324 $ hg up
1324 $ hg up
1325 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1325 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1326 $ hg branch foobar
1326 $ hg branch foobar
1327 marked working directory as branch foobar
1327 marked working directory as branch foobar
1328 $ hg commit -m 'create foobar'
1328 $ hg commit -m 'create foobar'
1329 $ echo 'foo contents' > abc.txt
1329 $ echo 'foo contents' > abc.txt
1330 $ hg add abc.txt
1330 $ hg add abc.txt
1331 $ hg commit -m 'foobar contents'
1331 $ hg commit -m 'foobar contents'
1332 $ cd ..
1332 $ cd ..
1333 $ hg --cwd a pull ../b
1333 $ hg --cwd a pull ../b
1334 pulling from ../b
1334 pulling from ../b
1335 searching for changes
1335 searching for changes
1336 adding changesets
1336 adding changesets
1337 adding manifests
1337 adding manifests
1338 adding file changes
1338 adding file changes
1339 added 2 changesets with 1 changes to 1 files (+1 heads)
1339 added 2 changesets with 1 changes to 1 files (+1 heads)
1340 (run 'hg heads' to see heads)
1340 (run 'hg heads' to see heads)
1341
1341
1342 Create additional changeset on foobar branch
1342 Create additional changeset on foobar branch
1343
1343
1344 $ cd a
1344 $ cd a
1345 $ hg up -C foobar
1345 $ hg up -C foobar
1346 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1346 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1347 $ echo 'foo contents2' > abc.txt
1347 $ echo 'foo contents2' > abc.txt
1348 $ hg commit -m 'foobar contents2'
1348 $ hg commit -m 'foobar contents2'
1349 $ cd ..
1349 $ cd ..
1350
1350
1351
1351
1352 No branch acls specified
1352 No branch acls specified
1353
1353
1354 $ do_push astro
1354 $ do_push astro
1355 Pushing as user astro
1355 Pushing as user astro
1356 hgrc = """
1356 hgrc = """
1357 [acl]
1357 [acl]
1358 sources = push
1358 sources = push
1359 [extensions]
1359 [extensions]
1360 """
1360 """
1361 pushing to ../b
1361 pushing to ../b
1362 searching for changes
1362 searching for changes
1363 4 changesets found
1363 4 changesets found
1364 list of changesets:
1364 list of changesets:
1365 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1365 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1366 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1366 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1367 911600dab2ae7a9baff75958b84fe606851ce955
1367 911600dab2ae7a9baff75958b84fe606851ce955
1368 4ea792ff64284af438188103a0ee8aca1724fb8c
1368 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1369 adding changesets
1369 adding changesets
1370 bundling: 1 changesets
1370 bundling: 1 changesets
1371 bundling: 2 changesets
1371 bundling: 2 changesets
1372 bundling: 3 changesets
1372 bundling: 3 changesets
1373 bundling: 4 changesets
1373 bundling: 4 changesets
1374 bundling: 1/4 manifests (25.00%)
1374 bundling: 1/4 manifests (25.00%)
1375 bundling: 2/4 manifests (50.00%)
1375 bundling: 2/4 manifests (50.00%)
1376 bundling: 3/4 manifests (75.00%)
1376 bundling: 3/4 manifests (75.00%)
1377 bundling: 4/4 manifests (100.00%)
1377 bundling: 4/4 manifests (100.00%)
1378 bundling: abc.txt 0/4 files (0.00%)
1378 bundling: abc.txt 0/4 files (0.00%)
1379 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1379 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1380 bundling: foo/file.txt 2/4 files (50.00%)
1380 bundling: foo/file.txt 2/4 files (50.00%)
1381 bundling: quux/file.py 3/4 files (75.00%)
1381 bundling: quux/file.py 3/4 files (75.00%)
1382 changesets: 1 chunks
1382 changesets: 1 chunks
1383 add changeset ef1ea85a6374
1383 add changeset ef1ea85a6374
1384 changesets: 2 chunks
1384 changesets: 2 chunks
1385 add changeset f9cafe1212c8
1385 add changeset f9cafe1212c8
1386 changesets: 3 chunks
1386 changesets: 3 chunks
1387 add changeset 911600dab2ae
1387 add changeset 911600dab2ae
1388 changesets: 4 chunks
1388 changesets: 4 chunks
1389 add changeset 4ea792ff6428
1389 add changeset e8fc755d4d82
1390 adding manifests
1390 adding manifests
1391 manifests: 1/4 chunks (25.00%)
1391 manifests: 1/4 chunks (25.00%)
1392 manifests: 2/4 chunks (50.00%)
1392 manifests: 2/4 chunks (50.00%)
1393 manifests: 3/4 chunks (75.00%)
1393 manifests: 3/4 chunks (75.00%)
1394 manifests: 4/4 chunks (100.00%)
1394 manifests: 4/4 chunks (100.00%)
1395 adding file changes
1395 adding file changes
1396 adding abc.txt revisions
1396 adding abc.txt revisions
1397 files: 1/4 chunks (25.00%)
1397 files: 1/4 chunks (25.00%)
1398 adding foo/Bar/file.txt revisions
1398 adding foo/Bar/file.txt revisions
1399 files: 2/4 chunks (50.00%)
1399 files: 2/4 chunks (50.00%)
1400 adding foo/file.txt revisions
1400 adding foo/file.txt revisions
1401 files: 3/4 chunks (75.00%)
1401 files: 3/4 chunks (75.00%)
1402 adding quux/file.py revisions
1402 adding quux/file.py revisions
1403 files: 4/4 chunks (100.00%)
1403 files: 4/4 chunks (100.00%)
1404 added 4 changesets with 4 changes to 4 files (+1 heads)
1404 added 4 changesets with 4 changes to 4 files (+1 heads)
1405 calling hook pretxnchangegroup.acl: hgext.acl.hook
1405 calling hook pretxnchangegroup.acl: hgext.acl.hook
1406 acl: acl.allow.branches not enabled
1406 acl: acl.allow.branches not enabled
1407 acl: acl.deny.branches not enabled
1407 acl: acl.deny.branches not enabled
1408 acl: acl.allow not enabled
1408 acl: acl.allow not enabled
1409 acl: acl.deny not enabled
1409 acl: acl.deny not enabled
1410 acl: branch access granted: "ef1ea85a6374" on branch "default"
1410 acl: branch access granted: "ef1ea85a6374" on branch "default"
1411 acl: allowing changeset ef1ea85a6374
1411 acl: allowing changeset ef1ea85a6374
1412 acl: branch access granted: "f9cafe1212c8" on branch "default"
1412 acl: branch access granted: "f9cafe1212c8" on branch "default"
1413 acl: allowing changeset f9cafe1212c8
1413 acl: allowing changeset f9cafe1212c8
1414 acl: branch access granted: "911600dab2ae" on branch "default"
1414 acl: branch access granted: "911600dab2ae" on branch "default"
1415 acl: allowing changeset 911600dab2ae
1415 acl: allowing changeset 911600dab2ae
1416 acl: branch access granted: "4ea792ff6428" on branch "foobar"
1416 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1417 acl: allowing changeset 4ea792ff6428
1417 acl: allowing changeset e8fc755d4d82
1418 updating the branch cache
1418 updating the branch cache
1419 checking for updated bookmarks
1419 checking for updated bookmarks
1420 repository tip rolled back to revision 2 (undo push)
1420 repository tip rolled back to revision 2 (undo push)
1421 working directory now based on revision 2
1421 working directory now based on revision 2
1422 2:07e028174695
1422 2:fb35475503ef
1423
1423
1424
1424
1425 Branch acl deny test
1425 Branch acl deny test
1426
1426
1427 $ echo "[acl.deny.branches]" >> $config
1427 $ echo "[acl.deny.branches]" >> $config
1428 $ echo "foobar = *" >> $config
1428 $ echo "foobar = *" >> $config
1429 $ do_push astro
1429 $ do_push astro
1430 Pushing as user astro
1430 Pushing as user astro
1431 hgrc = """
1431 hgrc = """
1432 [acl]
1432 [acl]
1433 sources = push
1433 sources = push
1434 [extensions]
1434 [extensions]
1435 [acl.deny.branches]
1435 [acl.deny.branches]
1436 foobar = *
1436 foobar = *
1437 """
1437 """
1438 pushing to ../b
1438 pushing to ../b
1439 searching for changes
1439 searching for changes
1440 invalidating branch cache (tip differs)
1440 invalidating branch cache (tip differs)
1441 4 changesets found
1441 4 changesets found
1442 list of changesets:
1442 list of changesets:
1443 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1443 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1444 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1444 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1445 911600dab2ae7a9baff75958b84fe606851ce955
1445 911600dab2ae7a9baff75958b84fe606851ce955
1446 4ea792ff64284af438188103a0ee8aca1724fb8c
1446 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1447 adding changesets
1447 adding changesets
1448 bundling: 1 changesets
1448 bundling: 1 changesets
1449 bundling: 2 changesets
1449 bundling: 2 changesets
1450 bundling: 3 changesets
1450 bundling: 3 changesets
1451 bundling: 4 changesets
1451 bundling: 4 changesets
1452 bundling: 1/4 manifests (25.00%)
1452 bundling: 1/4 manifests (25.00%)
1453 bundling: 2/4 manifests (50.00%)
1453 bundling: 2/4 manifests (50.00%)
1454 bundling: 3/4 manifests (75.00%)
1454 bundling: 3/4 manifests (75.00%)
1455 bundling: 4/4 manifests (100.00%)
1455 bundling: 4/4 manifests (100.00%)
1456 bundling: abc.txt 0/4 files (0.00%)
1456 bundling: abc.txt 0/4 files (0.00%)
1457 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1457 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1458 bundling: foo/file.txt 2/4 files (50.00%)
1458 bundling: foo/file.txt 2/4 files (50.00%)
1459 bundling: quux/file.py 3/4 files (75.00%)
1459 bundling: quux/file.py 3/4 files (75.00%)
1460 changesets: 1 chunks
1460 changesets: 1 chunks
1461 add changeset ef1ea85a6374
1461 add changeset ef1ea85a6374
1462 changesets: 2 chunks
1462 changesets: 2 chunks
1463 add changeset f9cafe1212c8
1463 add changeset f9cafe1212c8
1464 changesets: 3 chunks
1464 changesets: 3 chunks
1465 add changeset 911600dab2ae
1465 add changeset 911600dab2ae
1466 changesets: 4 chunks
1466 changesets: 4 chunks
1467 add changeset 4ea792ff6428
1467 add changeset e8fc755d4d82
1468 adding manifests
1468 adding manifests
1469 manifests: 1/4 chunks (25.00%)
1469 manifests: 1/4 chunks (25.00%)
1470 manifests: 2/4 chunks (50.00%)
1470 manifests: 2/4 chunks (50.00%)
1471 manifests: 3/4 chunks (75.00%)
1471 manifests: 3/4 chunks (75.00%)
1472 manifests: 4/4 chunks (100.00%)
1472 manifests: 4/4 chunks (100.00%)
1473 adding file changes
1473 adding file changes
1474 adding abc.txt revisions
1474 adding abc.txt revisions
1475 files: 1/4 chunks (25.00%)
1475 files: 1/4 chunks (25.00%)
1476 adding foo/Bar/file.txt revisions
1476 adding foo/Bar/file.txt revisions
1477 files: 2/4 chunks (50.00%)
1477 files: 2/4 chunks (50.00%)
1478 adding foo/file.txt revisions
1478 adding foo/file.txt revisions
1479 files: 3/4 chunks (75.00%)
1479 files: 3/4 chunks (75.00%)
1480 adding quux/file.py revisions
1480 adding quux/file.py revisions
1481 files: 4/4 chunks (100.00%)
1481 files: 4/4 chunks (100.00%)
1482 added 4 changesets with 4 changes to 4 files (+1 heads)
1482 added 4 changesets with 4 changes to 4 files (+1 heads)
1483 calling hook pretxnchangegroup.acl: hgext.acl.hook
1483 calling hook pretxnchangegroup.acl: hgext.acl.hook
1484 acl: acl.allow.branches not enabled
1484 acl: acl.allow.branches not enabled
1485 acl: acl.deny.branches enabled, 1 entries for user astro
1485 acl: acl.deny.branches enabled, 1 entries for user astro
1486 acl: acl.allow not enabled
1486 acl: acl.allow not enabled
1487 acl: acl.deny not enabled
1487 acl: acl.deny not enabled
1488 acl: branch access granted: "ef1ea85a6374" on branch "default"
1488 acl: branch access granted: "ef1ea85a6374" on branch "default"
1489 acl: allowing changeset ef1ea85a6374
1489 acl: allowing changeset ef1ea85a6374
1490 acl: branch access granted: "f9cafe1212c8" on branch "default"
1490 acl: branch access granted: "f9cafe1212c8" on branch "default"
1491 acl: allowing changeset f9cafe1212c8
1491 acl: allowing changeset f9cafe1212c8
1492 acl: branch access granted: "911600dab2ae" on branch "default"
1492 acl: branch access granted: "911600dab2ae" on branch "default"
1493 acl: allowing changeset 911600dab2ae
1493 acl: allowing changeset 911600dab2ae
1494 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "4ea792ff6428")
1494 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1495 transaction abort!
1495 transaction abort!
1496 rollback completed
1496 rollback completed
1497 abort: acl: user "astro" denied on branch "foobar" (changeset "4ea792ff6428")
1497 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1498 no rollback information available
1498 no rollback information available
1499 2:07e028174695
1499 2:fb35475503ef
1500
1500
1501
1501
1502 Branch acl empty allow test
1502 Branch acl empty allow test
1503
1503
1504 $ init_config
1504 $ init_config
1505 $ echo "[acl.allow.branches]" >> $config
1505 $ echo "[acl.allow.branches]" >> $config
1506 $ do_push astro
1506 $ do_push astro
1507 Pushing as user astro
1507 Pushing as user astro
1508 hgrc = """
1508 hgrc = """
1509 [acl]
1509 [acl]
1510 sources = push
1510 sources = push
1511 [extensions]
1511 [extensions]
1512 [acl.allow.branches]
1512 [acl.allow.branches]
1513 """
1513 """
1514 pushing to ../b
1514 pushing to ../b
1515 searching for changes
1515 searching for changes
1516 4 changesets found
1516 4 changesets found
1517 list of changesets:
1517 list of changesets:
1518 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1518 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1519 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1519 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1520 911600dab2ae7a9baff75958b84fe606851ce955
1520 911600dab2ae7a9baff75958b84fe606851ce955
1521 4ea792ff64284af438188103a0ee8aca1724fb8c
1521 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1522 adding changesets
1522 adding changesets
1523 bundling: 1 changesets
1523 bundling: 1 changesets
1524 bundling: 2 changesets
1524 bundling: 2 changesets
1525 bundling: 3 changesets
1525 bundling: 3 changesets
1526 bundling: 4 changesets
1526 bundling: 4 changesets
1527 bundling: 1/4 manifests (25.00%)
1527 bundling: 1/4 manifests (25.00%)
1528 bundling: 2/4 manifests (50.00%)
1528 bundling: 2/4 manifests (50.00%)
1529 bundling: 3/4 manifests (75.00%)
1529 bundling: 3/4 manifests (75.00%)
1530 bundling: 4/4 manifests (100.00%)
1530 bundling: 4/4 manifests (100.00%)
1531 bundling: abc.txt 0/4 files (0.00%)
1531 bundling: abc.txt 0/4 files (0.00%)
1532 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1532 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1533 bundling: foo/file.txt 2/4 files (50.00%)
1533 bundling: foo/file.txt 2/4 files (50.00%)
1534 bundling: quux/file.py 3/4 files (75.00%)
1534 bundling: quux/file.py 3/4 files (75.00%)
1535 changesets: 1 chunks
1535 changesets: 1 chunks
1536 add changeset ef1ea85a6374
1536 add changeset ef1ea85a6374
1537 changesets: 2 chunks
1537 changesets: 2 chunks
1538 add changeset f9cafe1212c8
1538 add changeset f9cafe1212c8
1539 changesets: 3 chunks
1539 changesets: 3 chunks
1540 add changeset 911600dab2ae
1540 add changeset 911600dab2ae
1541 changesets: 4 chunks
1541 changesets: 4 chunks
1542 add changeset 4ea792ff6428
1542 add changeset e8fc755d4d82
1543 adding manifests
1543 adding manifests
1544 manifests: 1/4 chunks (25.00%)
1544 manifests: 1/4 chunks (25.00%)
1545 manifests: 2/4 chunks (50.00%)
1545 manifests: 2/4 chunks (50.00%)
1546 manifests: 3/4 chunks (75.00%)
1546 manifests: 3/4 chunks (75.00%)
1547 manifests: 4/4 chunks (100.00%)
1547 manifests: 4/4 chunks (100.00%)
1548 adding file changes
1548 adding file changes
1549 adding abc.txt revisions
1549 adding abc.txt revisions
1550 files: 1/4 chunks (25.00%)
1550 files: 1/4 chunks (25.00%)
1551 adding foo/Bar/file.txt revisions
1551 adding foo/Bar/file.txt revisions
1552 files: 2/4 chunks (50.00%)
1552 files: 2/4 chunks (50.00%)
1553 adding foo/file.txt revisions
1553 adding foo/file.txt revisions
1554 files: 3/4 chunks (75.00%)
1554 files: 3/4 chunks (75.00%)
1555 adding quux/file.py revisions
1555 adding quux/file.py revisions
1556 files: 4/4 chunks (100.00%)
1556 files: 4/4 chunks (100.00%)
1557 added 4 changesets with 4 changes to 4 files (+1 heads)
1557 added 4 changesets with 4 changes to 4 files (+1 heads)
1558 calling hook pretxnchangegroup.acl: hgext.acl.hook
1558 calling hook pretxnchangegroup.acl: hgext.acl.hook
1559 acl: acl.allow.branches enabled, 0 entries for user astro
1559 acl: acl.allow.branches enabled, 0 entries for user astro
1560 acl: acl.deny.branches not enabled
1560 acl: acl.deny.branches not enabled
1561 acl: acl.allow not enabled
1561 acl: acl.allow not enabled
1562 acl: acl.deny not enabled
1562 acl: acl.deny not enabled
1563 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1563 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1564 transaction abort!
1564 transaction abort!
1565 rollback completed
1565 rollback completed
1566 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1566 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1567 no rollback information available
1567 no rollback information available
1568 2:07e028174695
1568 2:fb35475503ef
1569
1569
1570
1570
1571 Branch acl allow other
1571 Branch acl allow other
1572
1572
1573 $ init_config
1573 $ init_config
1574 $ echo "[acl.allow.branches]" >> $config
1574 $ echo "[acl.allow.branches]" >> $config
1575 $ echo "* = george" >> $config
1575 $ echo "* = george" >> $config
1576 $ do_push astro
1576 $ do_push astro
1577 Pushing as user astro
1577 Pushing as user astro
1578 hgrc = """
1578 hgrc = """
1579 [acl]
1579 [acl]
1580 sources = push
1580 sources = push
1581 [extensions]
1581 [extensions]
1582 [acl.allow.branches]
1582 [acl.allow.branches]
1583 * = george
1583 * = george
1584 """
1584 """
1585 pushing to ../b
1585 pushing to ../b
1586 searching for changes
1586 searching for changes
1587 4 changesets found
1587 4 changesets found
1588 list of changesets:
1588 list of changesets:
1589 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1589 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1590 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1590 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1591 911600dab2ae7a9baff75958b84fe606851ce955
1591 911600dab2ae7a9baff75958b84fe606851ce955
1592 4ea792ff64284af438188103a0ee8aca1724fb8c
1592 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1593 adding changesets
1593 adding changesets
1594 bundling: 1 changesets
1594 bundling: 1 changesets
1595 bundling: 2 changesets
1595 bundling: 2 changesets
1596 bundling: 3 changesets
1596 bundling: 3 changesets
1597 bundling: 4 changesets
1597 bundling: 4 changesets
1598 bundling: 1/4 manifests (25.00%)
1598 bundling: 1/4 manifests (25.00%)
1599 bundling: 2/4 manifests (50.00%)
1599 bundling: 2/4 manifests (50.00%)
1600 bundling: 3/4 manifests (75.00%)
1600 bundling: 3/4 manifests (75.00%)
1601 bundling: 4/4 manifests (100.00%)
1601 bundling: 4/4 manifests (100.00%)
1602 bundling: abc.txt 0/4 files (0.00%)
1602 bundling: abc.txt 0/4 files (0.00%)
1603 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1603 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1604 bundling: foo/file.txt 2/4 files (50.00%)
1604 bundling: foo/file.txt 2/4 files (50.00%)
1605 bundling: quux/file.py 3/4 files (75.00%)
1605 bundling: quux/file.py 3/4 files (75.00%)
1606 changesets: 1 chunks
1606 changesets: 1 chunks
1607 add changeset ef1ea85a6374
1607 add changeset ef1ea85a6374
1608 changesets: 2 chunks
1608 changesets: 2 chunks
1609 add changeset f9cafe1212c8
1609 add changeset f9cafe1212c8
1610 changesets: 3 chunks
1610 changesets: 3 chunks
1611 add changeset 911600dab2ae
1611 add changeset 911600dab2ae
1612 changesets: 4 chunks
1612 changesets: 4 chunks
1613 add changeset 4ea792ff6428
1613 add changeset e8fc755d4d82
1614 adding manifests
1614 adding manifests
1615 manifests: 1/4 chunks (25.00%)
1615 manifests: 1/4 chunks (25.00%)
1616 manifests: 2/4 chunks (50.00%)
1616 manifests: 2/4 chunks (50.00%)
1617 manifests: 3/4 chunks (75.00%)
1617 manifests: 3/4 chunks (75.00%)
1618 manifests: 4/4 chunks (100.00%)
1618 manifests: 4/4 chunks (100.00%)
1619 adding file changes
1619 adding file changes
1620 adding abc.txt revisions
1620 adding abc.txt revisions
1621 files: 1/4 chunks (25.00%)
1621 files: 1/4 chunks (25.00%)
1622 adding foo/Bar/file.txt revisions
1622 adding foo/Bar/file.txt revisions
1623 files: 2/4 chunks (50.00%)
1623 files: 2/4 chunks (50.00%)
1624 adding foo/file.txt revisions
1624 adding foo/file.txt revisions
1625 files: 3/4 chunks (75.00%)
1625 files: 3/4 chunks (75.00%)
1626 adding quux/file.py revisions
1626 adding quux/file.py revisions
1627 files: 4/4 chunks (100.00%)
1627 files: 4/4 chunks (100.00%)
1628 added 4 changesets with 4 changes to 4 files (+1 heads)
1628 added 4 changesets with 4 changes to 4 files (+1 heads)
1629 calling hook pretxnchangegroup.acl: hgext.acl.hook
1629 calling hook pretxnchangegroup.acl: hgext.acl.hook
1630 acl: acl.allow.branches enabled, 0 entries for user astro
1630 acl: acl.allow.branches enabled, 0 entries for user astro
1631 acl: acl.deny.branches not enabled
1631 acl: acl.deny.branches not enabled
1632 acl: acl.allow not enabled
1632 acl: acl.allow not enabled
1633 acl: acl.deny not enabled
1633 acl: acl.deny not enabled
1634 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1634 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1635 transaction abort!
1635 transaction abort!
1636 rollback completed
1636 rollback completed
1637 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1637 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1638 no rollback information available
1638 no rollback information available
1639 2:07e028174695
1639 2:fb35475503ef
1640
1640
1641 $ do_push george
1641 $ do_push george
1642 Pushing as user george
1642 Pushing as user george
1643 hgrc = """
1643 hgrc = """
1644 [acl]
1644 [acl]
1645 sources = push
1645 sources = push
1646 [extensions]
1646 [extensions]
1647 [acl.allow.branches]
1647 [acl.allow.branches]
1648 * = george
1648 * = george
1649 """
1649 """
1650 pushing to ../b
1650 pushing to ../b
1651 searching for changes
1651 searching for changes
1652 4 changesets found
1652 4 changesets found
1653 list of changesets:
1653 list of changesets:
1654 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1654 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1655 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1655 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1656 911600dab2ae7a9baff75958b84fe606851ce955
1656 911600dab2ae7a9baff75958b84fe606851ce955
1657 4ea792ff64284af438188103a0ee8aca1724fb8c
1657 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1658 adding changesets
1658 adding changesets
1659 bundling: 1 changesets
1659 bundling: 1 changesets
1660 bundling: 2 changesets
1660 bundling: 2 changesets
1661 bundling: 3 changesets
1661 bundling: 3 changesets
1662 bundling: 4 changesets
1662 bundling: 4 changesets
1663 bundling: 1/4 manifests (25.00%)
1663 bundling: 1/4 manifests (25.00%)
1664 bundling: 2/4 manifests (50.00%)
1664 bundling: 2/4 manifests (50.00%)
1665 bundling: 3/4 manifests (75.00%)
1665 bundling: 3/4 manifests (75.00%)
1666 bundling: 4/4 manifests (100.00%)
1666 bundling: 4/4 manifests (100.00%)
1667 bundling: abc.txt 0/4 files (0.00%)
1667 bundling: abc.txt 0/4 files (0.00%)
1668 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1668 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1669 bundling: foo/file.txt 2/4 files (50.00%)
1669 bundling: foo/file.txt 2/4 files (50.00%)
1670 bundling: quux/file.py 3/4 files (75.00%)
1670 bundling: quux/file.py 3/4 files (75.00%)
1671 changesets: 1 chunks
1671 changesets: 1 chunks
1672 add changeset ef1ea85a6374
1672 add changeset ef1ea85a6374
1673 changesets: 2 chunks
1673 changesets: 2 chunks
1674 add changeset f9cafe1212c8
1674 add changeset f9cafe1212c8
1675 changesets: 3 chunks
1675 changesets: 3 chunks
1676 add changeset 911600dab2ae
1676 add changeset 911600dab2ae
1677 changesets: 4 chunks
1677 changesets: 4 chunks
1678 add changeset 4ea792ff6428
1678 add changeset e8fc755d4d82
1679 adding manifests
1679 adding manifests
1680 manifests: 1/4 chunks (25.00%)
1680 manifests: 1/4 chunks (25.00%)
1681 manifests: 2/4 chunks (50.00%)
1681 manifests: 2/4 chunks (50.00%)
1682 manifests: 3/4 chunks (75.00%)
1682 manifests: 3/4 chunks (75.00%)
1683 manifests: 4/4 chunks (100.00%)
1683 manifests: 4/4 chunks (100.00%)
1684 adding file changes
1684 adding file changes
1685 adding abc.txt revisions
1685 adding abc.txt revisions
1686 files: 1/4 chunks (25.00%)
1686 files: 1/4 chunks (25.00%)
1687 adding foo/Bar/file.txt revisions
1687 adding foo/Bar/file.txt revisions
1688 files: 2/4 chunks (50.00%)
1688 files: 2/4 chunks (50.00%)
1689 adding foo/file.txt revisions
1689 adding foo/file.txt revisions
1690 files: 3/4 chunks (75.00%)
1690 files: 3/4 chunks (75.00%)
1691 adding quux/file.py revisions
1691 adding quux/file.py revisions
1692 files: 4/4 chunks (100.00%)
1692 files: 4/4 chunks (100.00%)
1693 added 4 changesets with 4 changes to 4 files (+1 heads)
1693 added 4 changesets with 4 changes to 4 files (+1 heads)
1694 calling hook pretxnchangegroup.acl: hgext.acl.hook
1694 calling hook pretxnchangegroup.acl: hgext.acl.hook
1695 acl: acl.allow.branches enabled, 1 entries for user george
1695 acl: acl.allow.branches enabled, 1 entries for user george
1696 acl: acl.deny.branches not enabled
1696 acl: acl.deny.branches not enabled
1697 acl: acl.allow not enabled
1697 acl: acl.allow not enabled
1698 acl: acl.deny not enabled
1698 acl: acl.deny not enabled
1699 acl: branch access granted: "ef1ea85a6374" on branch "default"
1699 acl: branch access granted: "ef1ea85a6374" on branch "default"
1700 acl: allowing changeset ef1ea85a6374
1700 acl: allowing changeset ef1ea85a6374
1701 acl: branch access granted: "f9cafe1212c8" on branch "default"
1701 acl: branch access granted: "f9cafe1212c8" on branch "default"
1702 acl: allowing changeset f9cafe1212c8
1702 acl: allowing changeset f9cafe1212c8
1703 acl: branch access granted: "911600dab2ae" on branch "default"
1703 acl: branch access granted: "911600dab2ae" on branch "default"
1704 acl: allowing changeset 911600dab2ae
1704 acl: allowing changeset 911600dab2ae
1705 acl: branch access granted: "4ea792ff6428" on branch "foobar"
1705 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1706 acl: allowing changeset 4ea792ff6428
1706 acl: allowing changeset e8fc755d4d82
1707 updating the branch cache
1707 updating the branch cache
1708 checking for updated bookmarks
1708 checking for updated bookmarks
1709 repository tip rolled back to revision 2 (undo push)
1709 repository tip rolled back to revision 2 (undo push)
1710 working directory now based on revision 2
1710 working directory now based on revision 2
1711 2:07e028174695
1711 2:fb35475503ef
1712
1712
1713
1713
1714 Branch acl conflicting allow
1714 Branch acl conflicting allow
1715 asterisk ends up applying to all branches and allowing george to
1715 asterisk ends up applying to all branches and allowing george to
1716 push foobar into the remote
1716 push foobar into the remote
1717
1717
1718 $ init_config
1718 $ init_config
1719 $ echo "[acl.allow.branches]" >> $config
1719 $ echo "[acl.allow.branches]" >> $config
1720 $ echo "foobar = astro" >> $config
1720 $ echo "foobar = astro" >> $config
1721 $ echo "* = george" >> $config
1721 $ echo "* = george" >> $config
1722 $ do_push george
1722 $ do_push george
1723 Pushing as user george
1723 Pushing as user george
1724 hgrc = """
1724 hgrc = """
1725 [acl]
1725 [acl]
1726 sources = push
1726 sources = push
1727 [extensions]
1727 [extensions]
1728 [acl.allow.branches]
1728 [acl.allow.branches]
1729 foobar = astro
1729 foobar = astro
1730 * = george
1730 * = george
1731 """
1731 """
1732 pushing to ../b
1732 pushing to ../b
1733 searching for changes
1733 searching for changes
1734 invalidating branch cache (tip differs)
1734 invalidating branch cache (tip differs)
1735 4 changesets found
1735 4 changesets found
1736 list of changesets:
1736 list of changesets:
1737 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1737 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1738 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1738 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1739 911600dab2ae7a9baff75958b84fe606851ce955
1739 911600dab2ae7a9baff75958b84fe606851ce955
1740 4ea792ff64284af438188103a0ee8aca1724fb8c
1740 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1741 adding changesets
1741 adding changesets
1742 bundling: 1 changesets
1742 bundling: 1 changesets
1743 bundling: 2 changesets
1743 bundling: 2 changesets
1744 bundling: 3 changesets
1744 bundling: 3 changesets
1745 bundling: 4 changesets
1745 bundling: 4 changesets
1746 bundling: 1/4 manifests (25.00%)
1746 bundling: 1/4 manifests (25.00%)
1747 bundling: 2/4 manifests (50.00%)
1747 bundling: 2/4 manifests (50.00%)
1748 bundling: 3/4 manifests (75.00%)
1748 bundling: 3/4 manifests (75.00%)
1749 bundling: 4/4 manifests (100.00%)
1749 bundling: 4/4 manifests (100.00%)
1750 bundling: abc.txt 0/4 files (0.00%)
1750 bundling: abc.txt 0/4 files (0.00%)
1751 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1751 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1752 bundling: foo/file.txt 2/4 files (50.00%)
1752 bundling: foo/file.txt 2/4 files (50.00%)
1753 bundling: quux/file.py 3/4 files (75.00%)
1753 bundling: quux/file.py 3/4 files (75.00%)
1754 changesets: 1 chunks
1754 changesets: 1 chunks
1755 add changeset ef1ea85a6374
1755 add changeset ef1ea85a6374
1756 changesets: 2 chunks
1756 changesets: 2 chunks
1757 add changeset f9cafe1212c8
1757 add changeset f9cafe1212c8
1758 changesets: 3 chunks
1758 changesets: 3 chunks
1759 add changeset 911600dab2ae
1759 add changeset 911600dab2ae
1760 changesets: 4 chunks
1760 changesets: 4 chunks
1761 add changeset 4ea792ff6428
1761 add changeset e8fc755d4d82
1762 adding manifests
1762 adding manifests
1763 manifests: 1/4 chunks (25.00%)
1763 manifests: 1/4 chunks (25.00%)
1764 manifests: 2/4 chunks (50.00%)
1764 manifests: 2/4 chunks (50.00%)
1765 manifests: 3/4 chunks (75.00%)
1765 manifests: 3/4 chunks (75.00%)
1766 manifests: 4/4 chunks (100.00%)
1766 manifests: 4/4 chunks (100.00%)
1767 adding file changes
1767 adding file changes
1768 adding abc.txt revisions
1768 adding abc.txt revisions
1769 files: 1/4 chunks (25.00%)
1769 files: 1/4 chunks (25.00%)
1770 adding foo/Bar/file.txt revisions
1770 adding foo/Bar/file.txt revisions
1771 files: 2/4 chunks (50.00%)
1771 files: 2/4 chunks (50.00%)
1772 adding foo/file.txt revisions
1772 adding foo/file.txt revisions
1773 files: 3/4 chunks (75.00%)
1773 files: 3/4 chunks (75.00%)
1774 adding quux/file.py revisions
1774 adding quux/file.py revisions
1775 files: 4/4 chunks (100.00%)
1775 files: 4/4 chunks (100.00%)
1776 added 4 changesets with 4 changes to 4 files (+1 heads)
1776 added 4 changesets with 4 changes to 4 files (+1 heads)
1777 calling hook pretxnchangegroup.acl: hgext.acl.hook
1777 calling hook pretxnchangegroup.acl: hgext.acl.hook
1778 acl: acl.allow.branches enabled, 1 entries for user george
1778 acl: acl.allow.branches enabled, 1 entries for user george
1779 acl: acl.deny.branches not enabled
1779 acl: acl.deny.branches not enabled
1780 acl: acl.allow not enabled
1780 acl: acl.allow not enabled
1781 acl: acl.deny not enabled
1781 acl: acl.deny not enabled
1782 acl: branch access granted: "ef1ea85a6374" on branch "default"
1782 acl: branch access granted: "ef1ea85a6374" on branch "default"
1783 acl: allowing changeset ef1ea85a6374
1783 acl: allowing changeset ef1ea85a6374
1784 acl: branch access granted: "f9cafe1212c8" on branch "default"
1784 acl: branch access granted: "f9cafe1212c8" on branch "default"
1785 acl: allowing changeset f9cafe1212c8
1785 acl: allowing changeset f9cafe1212c8
1786 acl: branch access granted: "911600dab2ae" on branch "default"
1786 acl: branch access granted: "911600dab2ae" on branch "default"
1787 acl: allowing changeset 911600dab2ae
1787 acl: allowing changeset 911600dab2ae
1788 acl: branch access granted: "4ea792ff6428" on branch "foobar"
1788 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1789 acl: allowing changeset 4ea792ff6428
1789 acl: allowing changeset e8fc755d4d82
1790 updating the branch cache
1790 updating the branch cache
1791 checking for updated bookmarks
1791 checking for updated bookmarks
1792 repository tip rolled back to revision 2 (undo push)
1792 repository tip rolled back to revision 2 (undo push)
1793 working directory now based on revision 2
1793 working directory now based on revision 2
1794 2:07e028174695
1794 2:fb35475503ef
1795
1795
1796 Branch acl conflicting deny
1796 Branch acl conflicting deny
1797
1797
1798 $ init_config
1798 $ init_config
1799 $ echo "[acl.deny.branches]" >> $config
1799 $ echo "[acl.deny.branches]" >> $config
1800 $ echo "foobar = astro" >> $config
1800 $ echo "foobar = astro" >> $config
1801 $ echo "default = astro" >> $config
1801 $ echo "default = astro" >> $config
1802 $ echo "* = george" >> $config
1802 $ echo "* = george" >> $config
1803 $ do_push george
1803 $ do_push george
1804 Pushing as user george
1804 Pushing as user george
1805 hgrc = """
1805 hgrc = """
1806 [acl]
1806 [acl]
1807 sources = push
1807 sources = push
1808 [extensions]
1808 [extensions]
1809 [acl.deny.branches]
1809 [acl.deny.branches]
1810 foobar = astro
1810 foobar = astro
1811 default = astro
1811 default = astro
1812 * = george
1812 * = george
1813 """
1813 """
1814 pushing to ../b
1814 pushing to ../b
1815 searching for changes
1815 searching for changes
1816 invalidating branch cache (tip differs)
1816 invalidating branch cache (tip differs)
1817 4 changesets found
1817 4 changesets found
1818 list of changesets:
1818 list of changesets:
1819 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1819 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1820 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1820 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1821 911600dab2ae7a9baff75958b84fe606851ce955
1821 911600dab2ae7a9baff75958b84fe606851ce955
1822 4ea792ff64284af438188103a0ee8aca1724fb8c
1822 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1823 adding changesets
1823 adding changesets
1824 bundling: 1 changesets
1824 bundling: 1 changesets
1825 bundling: 2 changesets
1825 bundling: 2 changesets
1826 bundling: 3 changesets
1826 bundling: 3 changesets
1827 bundling: 4 changesets
1827 bundling: 4 changesets
1828 bundling: 1/4 manifests (25.00%)
1828 bundling: 1/4 manifests (25.00%)
1829 bundling: 2/4 manifests (50.00%)
1829 bundling: 2/4 manifests (50.00%)
1830 bundling: 3/4 manifests (75.00%)
1830 bundling: 3/4 manifests (75.00%)
1831 bundling: 4/4 manifests (100.00%)
1831 bundling: 4/4 manifests (100.00%)
1832 bundling: abc.txt 0/4 files (0.00%)
1832 bundling: abc.txt 0/4 files (0.00%)
1833 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1833 bundling: foo/Bar/file.txt 1/4 files (25.00%)
1834 bundling: foo/file.txt 2/4 files (50.00%)
1834 bundling: foo/file.txt 2/4 files (50.00%)
1835 bundling: quux/file.py 3/4 files (75.00%)
1835 bundling: quux/file.py 3/4 files (75.00%)
1836 changesets: 1 chunks
1836 changesets: 1 chunks
1837 add changeset ef1ea85a6374
1837 add changeset ef1ea85a6374
1838 changesets: 2 chunks
1838 changesets: 2 chunks
1839 add changeset f9cafe1212c8
1839 add changeset f9cafe1212c8
1840 changesets: 3 chunks
1840 changesets: 3 chunks
1841 add changeset 911600dab2ae
1841 add changeset 911600dab2ae
1842 changesets: 4 chunks
1842 changesets: 4 chunks
1843 add changeset 4ea792ff6428
1843 add changeset e8fc755d4d82
1844 adding manifests
1844 adding manifests
1845 manifests: 1/4 chunks (25.00%)
1845 manifests: 1/4 chunks (25.00%)
1846 manifests: 2/4 chunks (50.00%)
1846 manifests: 2/4 chunks (50.00%)
1847 manifests: 3/4 chunks (75.00%)
1847 manifests: 3/4 chunks (75.00%)
1848 manifests: 4/4 chunks (100.00%)
1848 manifests: 4/4 chunks (100.00%)
1849 adding file changes
1849 adding file changes
1850 adding abc.txt revisions
1850 adding abc.txt revisions
1851 files: 1/4 chunks (25.00%)
1851 files: 1/4 chunks (25.00%)
1852 adding foo/Bar/file.txt revisions
1852 adding foo/Bar/file.txt revisions
1853 files: 2/4 chunks (50.00%)
1853 files: 2/4 chunks (50.00%)
1854 adding foo/file.txt revisions
1854 adding foo/file.txt revisions
1855 files: 3/4 chunks (75.00%)
1855 files: 3/4 chunks (75.00%)
1856 adding quux/file.py revisions
1856 adding quux/file.py revisions
1857 files: 4/4 chunks (100.00%)
1857 files: 4/4 chunks (100.00%)
1858 added 4 changesets with 4 changes to 4 files (+1 heads)
1858 added 4 changesets with 4 changes to 4 files (+1 heads)
1859 calling hook pretxnchangegroup.acl: hgext.acl.hook
1859 calling hook pretxnchangegroup.acl: hgext.acl.hook
1860 acl: acl.allow.branches not enabled
1860 acl: acl.allow.branches not enabled
1861 acl: acl.deny.branches enabled, 1 entries for user george
1861 acl: acl.deny.branches enabled, 1 entries for user george
1862 acl: acl.allow not enabled
1862 acl: acl.allow not enabled
1863 acl: acl.deny not enabled
1863 acl: acl.deny not enabled
1864 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1864 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1865 transaction abort!
1865 transaction abort!
1866 rollback completed
1866 rollback completed
1867 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1867 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1868 no rollback information available
1868 no rollback information available
1869 2:07e028174695
1869 2:fb35475503ef
1870
1870
@@ -1,62 +1,62
1 Initial setup.
1 Initial setup.
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5 $ touch thefile
5 $ touch thefile
6 $ hg ci -A -m 'Initial commit.'
6 $ hg ci -A -m 'Initial commit.'
7 adding thefile
7 adding thefile
8
8
9 Create a tag.
9 Create a tag.
10
10
11 $ hg tag branchortag
11 $ hg tag branchortag
12
12
13 Create a branch with the same name as the tag.
13 Create a branch with the same name as the tag.
14
14
15 $ hg branch branchortag
15 $ hg branch branchortag
16 marked working directory as branch branchortag
16 marked working directory as branch branchortag
17 $ hg ci -m 'Create a branch with the same name as a tag.'
17 $ hg ci -m 'Create a branch with the same name as a tag.'
18
18
19 This is what we have:
19 This is what we have:
20
20
21 $ hg log
21 $ hg log
22 changeset: 2:02b1af9b58c2
22 changeset: 2:10519b3f489a
23 branch: branchortag
23 branch: branchortag
24 tag: tip
24 tag: tip
25 user: test
25 user: test
26 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
27 summary: Create a branch with the same name as a tag.
27 summary: Create a branch with the same name as a tag.
28
28
29 changeset: 1:2635c45ca99b
29 changeset: 1:2635c45ca99b
30 user: test
30 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
31 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: Added tag branchortag for changeset f57387372b5d
32 summary: Added tag branchortag for changeset f57387372b5d
33
33
34 changeset: 0:f57387372b5d
34 changeset: 0:f57387372b5d
35 tag: branchortag
35 tag: branchortag
36 user: test
36 user: test
37 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
38 summary: Initial commit.
38 summary: Initial commit.
39
39
40 Update to the tag:
40 Update to the tag:
41
41
42 $ hg up 'tag(branchortag)'
42 $ hg up 'tag(branchortag)'
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 $ hg parents
44 $ hg parents
45 changeset: 0:f57387372b5d
45 changeset: 0:f57387372b5d
46 tag: branchortag
46 tag: branchortag
47 user: test
47 user: test
48 date: Thu Jan 01 00:00:00 1970 +0000
48 date: Thu Jan 01 00:00:00 1970 +0000
49 summary: Initial commit.
49 summary: Initial commit.
50
50
51 Updating to the branch:
51 Updating to the branch:
52
52
53 $ hg up 'branch(branchortag)'
53 $ hg up 'branch(branchortag)'
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ hg parents
55 $ hg parents
56 changeset: 2:02b1af9b58c2
56 changeset: 2:10519b3f489a
57 branch: branchortag
57 branch: branchortag
58 tag: tip
58 tag: tip
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Create a branch with the same name as a tag.
61 summary: Create a branch with the same name as a tag.
62
62
@@ -1,400 +1,400
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo 'root' >root
3 $ echo 'root' >root
4 $ hg add root
4 $ hg add root
5 $ hg commit -d '0 0' -m "Adding root node"
5 $ hg commit -d '0 0' -m "Adding root node"
6
6
7 $ echo 'a' >a
7 $ echo 'a' >a
8 $ hg add a
8 $ hg add a
9 $ hg branch a
9 $ hg branch a
10 marked working directory as branch a
10 marked working directory as branch a
11 $ hg commit -d '1 0' -m "Adding a branch"
11 $ hg commit -d '1 0' -m "Adding a branch"
12
12
13 $ hg branch q
13 $ hg branch q
14 marked working directory as branch q
14 marked working directory as branch q
15 $ echo 'aa' >a
15 $ echo 'aa' >a
16 $ hg branch -C
16 $ hg branch -C
17 reset working directory to branch a
17 reset working directory to branch a
18 $ hg commit -d '2 0' -m "Adding to a branch"
18 $ hg commit -d '2 0' -m "Adding to a branch"
19
19
20 $ hg update -C 0
20 $ hg update -C 0
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 $ echo 'b' >b
22 $ echo 'b' >b
23 $ hg add b
23 $ hg add b
24 $ hg branch b
24 $ hg branch b
25 marked working directory as branch b
25 marked working directory as branch b
26 $ hg commit -d '2 0' -m "Adding b branch"
26 $ hg commit -d '2 0' -m "Adding b branch"
27
27
28 $ echo 'bh1' >bh1
28 $ echo 'bh1' >bh1
29 $ hg add bh1
29 $ hg add bh1
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
31
31
32 $ hg update -C 2
32 $ hg update -C 2
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 $ echo 'bh2' >bh2
34 $ echo 'bh2' >bh2
35 $ hg add bh2
35 $ hg add bh2
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
37
37
38 $ echo 'c' >c
38 $ echo 'c' >c
39 $ hg add c
39 $ hg add c
40 $ hg branch c
40 $ hg branch c
41 marked working directory as branch c
41 marked working directory as branch c
42 $ hg commit -d '5 0' -m "Adding c branch"
42 $ hg commit -d '5 0' -m "Adding c branch"
43
43
44 $ hg branch tip
44 $ hg branch tip
45 abort: the name 'tip' is reserved
45 abort: the name 'tip' is reserved
46 [255]
46 [255]
47 $ hg branch null
47 $ hg branch null
48 abort: the name 'null' is reserved
48 abort: the name 'null' is reserved
49 [255]
49 [255]
50 $ hg branch .
50 $ hg branch .
51 abort: the name '.' is reserved
51 abort: the name '.' is reserved
52 [255]
52 [255]
53
53
54 $ echo 'd' >d
54 $ echo 'd' >d
55 $ hg add d
55 $ hg add d
56 $ hg branch 'a branch name much longer than the default justification used by branches'
56 $ hg branch 'a branch name much longer than the default justification used by branches'
57 marked working directory as branch a branch name much longer than the default justification used by branches
57 marked working directory as branch a branch name much longer than the default justification used by branches
58 $ hg commit -d '6 0' -m "Adding d branch"
58 $ hg commit -d '6 0' -m "Adding d branch"
59
59
60 $ hg branches
60 $ hg branches
61 a branch name much longer than the default justification used by branches 7:10ff5895aa57
61 a branch name much longer than the default justification used by branches 7:10ff5895aa57
62 b 4:aee39cd168d0
62 b 4:aee39cd168d0
63 c 6:589736a22561 (inactive)
63 c 6:589736a22561 (inactive)
64 a 5:d8cbc61dbaa6 (inactive)
64 a 5:d8cbc61dbaa6 (inactive)
65 default 0:19709c5a4e75 (inactive)
65 default 0:19709c5a4e75 (inactive)
66
66
67 -------
67 -------
68
68
69 $ hg branches -a
69 $ hg branches -a
70 a branch name much longer than the default justification used by branches 7:10ff5895aa57
70 a branch name much longer than the default justification used by branches 7:10ff5895aa57
71 b 4:aee39cd168d0
71 b 4:aee39cd168d0
72
72
73 --- Branch a
73 --- Branch a
74
74
75 $ hg log -b a
75 $ hg log -b a
76 changeset: 5:d8cbc61dbaa6
76 changeset: 5:d8cbc61dbaa6
77 branch: a
77 branch: a
78 parent: 2:881fe2b92ad0
78 parent: 2:881fe2b92ad0
79 user: test
79 user: test
80 date: Thu Jan 01 00:00:04 1970 +0000
80 date: Thu Jan 01 00:00:04 1970 +0000
81 summary: Adding b branch head 2
81 summary: Adding b branch head 2
82
82
83 changeset: 2:881fe2b92ad0
83 changeset: 2:881fe2b92ad0
84 branch: a
84 branch: a
85 user: test
85 user: test
86 date: Thu Jan 01 00:00:02 1970 +0000
86 date: Thu Jan 01 00:00:02 1970 +0000
87 summary: Adding to a branch
87 summary: Adding to a branch
88
88
89 changeset: 1:dd6b440dd85a
89 changeset: 1:dd6b440dd85a
90 branch: a
90 branch: a
91 user: test
91 user: test
92 date: Thu Jan 01 00:00:01 1970 +0000
92 date: Thu Jan 01 00:00:01 1970 +0000
93 summary: Adding a branch
93 summary: Adding a branch
94
94
95
95
96 ---- Branch b
96 ---- Branch b
97
97
98 $ hg log -b b
98 $ hg log -b b
99 changeset: 4:aee39cd168d0
99 changeset: 4:aee39cd168d0
100 branch: b
100 branch: b
101 user: test
101 user: test
102 date: Thu Jan 01 00:00:03 1970 +0000
102 date: Thu Jan 01 00:00:03 1970 +0000
103 summary: Adding b branch head 1
103 summary: Adding b branch head 1
104
104
105 changeset: 3:ac22033332d1
105 changeset: 3:ac22033332d1
106 branch: b
106 branch: b
107 parent: 0:19709c5a4e75
107 parent: 0:19709c5a4e75
108 user: test
108 user: test
109 date: Thu Jan 01 00:00:02 1970 +0000
109 date: Thu Jan 01 00:00:02 1970 +0000
110 summary: Adding b branch
110 summary: Adding b branch
111
111
112
112
113 ---- going to test branch closing
113 ---- going to test branch closing
114
114
115 $ hg branches
115 $ hg branches
116 a branch name much longer than the default justification used by branches 7:10ff5895aa57
116 a branch name much longer than the default justification used by branches 7:10ff5895aa57
117 b 4:aee39cd168d0
117 b 4:aee39cd168d0
118 c 6:589736a22561 (inactive)
118 c 6:589736a22561 (inactive)
119 a 5:d8cbc61dbaa6 (inactive)
119 a 5:d8cbc61dbaa6 (inactive)
120 default 0:19709c5a4e75 (inactive)
120 default 0:19709c5a4e75 (inactive)
121 $ hg up -C b
121 $ hg up -C b
122 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
122 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
123 $ echo 'xxx1' >> b
123 $ echo 'xxx1' >> b
124 $ hg commit -d '7 0' -m 'adding cset to branch b'
124 $ hg commit -d '7 0' -m 'adding cset to branch b'
125 $ hg up -C aee39cd168d0
125 $ hg up -C aee39cd168d0
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 $ echo 'xxx2' >> b
127 $ echo 'xxx2' >> b
128 $ hg commit -d '8 0' -m 'adding head to branch b'
128 $ hg commit -d '8 0' -m 'adding head to branch b'
129 created new head
129 created new head
130 $ echo 'xxx3' >> b
130 $ echo 'xxx3' >> b
131 $ hg commit -d '9 0' -m 'adding another cset to branch b'
131 $ hg commit -d '9 0' -m 'adding another cset to branch b'
132 $ hg branches
132 $ hg branches
133 b 10:bfbe841b666e
133 b 10:bfbe841b666e
134 a branch name much longer than the default justification used by branches 7:10ff5895aa57
134 a branch name much longer than the default justification used by branches 7:10ff5895aa57
135 c 6:589736a22561 (inactive)
135 c 6:589736a22561 (inactive)
136 a 5:d8cbc61dbaa6 (inactive)
136 a 5:d8cbc61dbaa6 (inactive)
137 default 0:19709c5a4e75 (inactive)
137 default 0:19709c5a4e75 (inactive)
138 $ hg heads --closed
138 $ hg heads --closed
139 changeset: 10:bfbe841b666e
139 changeset: 10:bfbe841b666e
140 branch: b
140 branch: b
141 tag: tip
141 tag: tip
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:09 1970 +0000
143 date: Thu Jan 01 00:00:09 1970 +0000
144 summary: adding another cset to branch b
144 summary: adding another cset to branch b
145
145
146 changeset: 8:eebb944467c9
146 changeset: 8:eebb944467c9
147 branch: b
147 branch: b
148 parent: 4:aee39cd168d0
148 parent: 4:aee39cd168d0
149 user: test
149 user: test
150 date: Thu Jan 01 00:00:07 1970 +0000
150 date: Thu Jan 01 00:00:07 1970 +0000
151 summary: adding cset to branch b
151 summary: adding cset to branch b
152
152
153 changeset: 7:10ff5895aa57
153 changeset: 7:10ff5895aa57
154 branch: a branch name much longer than the default justification used by branches
154 branch: a branch name much longer than the default justification used by branches
155 user: test
155 user: test
156 date: Thu Jan 01 00:00:06 1970 +0000
156 date: Thu Jan 01 00:00:06 1970 +0000
157 summary: Adding d branch
157 summary: Adding d branch
158
158
159 changeset: 6:589736a22561
159 changeset: 6:589736a22561
160 branch: c
160 branch: c
161 user: test
161 user: test
162 date: Thu Jan 01 00:00:05 1970 +0000
162 date: Thu Jan 01 00:00:05 1970 +0000
163 summary: Adding c branch
163 summary: Adding c branch
164
164
165 changeset: 5:d8cbc61dbaa6
165 changeset: 5:d8cbc61dbaa6
166 branch: a
166 branch: a
167 parent: 2:881fe2b92ad0
167 parent: 2:881fe2b92ad0
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:04 1970 +0000
169 date: Thu Jan 01 00:00:04 1970 +0000
170 summary: Adding b branch head 2
170 summary: Adding b branch head 2
171
171
172 changeset: 0:19709c5a4e75
172 changeset: 0:19709c5a4e75
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
174 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: Adding root node
175 summary: Adding root node
176
176
177 $ hg heads
177 $ hg heads
178 changeset: 10:bfbe841b666e
178 changeset: 10:bfbe841b666e
179 branch: b
179 branch: b
180 tag: tip
180 tag: tip
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:09 1970 +0000
182 date: Thu Jan 01 00:00:09 1970 +0000
183 summary: adding another cset to branch b
183 summary: adding another cset to branch b
184
184
185 changeset: 8:eebb944467c9
185 changeset: 8:eebb944467c9
186 branch: b
186 branch: b
187 parent: 4:aee39cd168d0
187 parent: 4:aee39cd168d0
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:07 1970 +0000
189 date: Thu Jan 01 00:00:07 1970 +0000
190 summary: adding cset to branch b
190 summary: adding cset to branch b
191
191
192 changeset: 7:10ff5895aa57
192 changeset: 7:10ff5895aa57
193 branch: a branch name much longer than the default justification used by branches
193 branch: a branch name much longer than the default justification used by branches
194 user: test
194 user: test
195 date: Thu Jan 01 00:00:06 1970 +0000
195 date: Thu Jan 01 00:00:06 1970 +0000
196 summary: Adding d branch
196 summary: Adding d branch
197
197
198 changeset: 6:589736a22561
198 changeset: 6:589736a22561
199 branch: c
199 branch: c
200 user: test
200 user: test
201 date: Thu Jan 01 00:00:05 1970 +0000
201 date: Thu Jan 01 00:00:05 1970 +0000
202 summary: Adding c branch
202 summary: Adding c branch
203
203
204 changeset: 5:d8cbc61dbaa6
204 changeset: 5:d8cbc61dbaa6
205 branch: a
205 branch: a
206 parent: 2:881fe2b92ad0
206 parent: 2:881fe2b92ad0
207 user: test
207 user: test
208 date: Thu Jan 01 00:00:04 1970 +0000
208 date: Thu Jan 01 00:00:04 1970 +0000
209 summary: Adding b branch head 2
209 summary: Adding b branch head 2
210
210
211 changeset: 0:19709c5a4e75
211 changeset: 0:19709c5a4e75
212 user: test
212 user: test
213 date: Thu Jan 01 00:00:00 1970 +0000
213 date: Thu Jan 01 00:00:00 1970 +0000
214 summary: Adding root node
214 summary: Adding root node
215
215
216 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
216 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
217 $ hg branches -a
217 $ hg branches -a
218 b 8:eebb944467c9
218 b 8:eebb944467c9
219 a branch name much longer than the default justification used by branches 7:10ff5895aa57
219 a branch name much longer than the default justification used by branches 7:10ff5895aa57
220 $ hg up -C b
220 $ hg up -C b
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
222 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
223
223
224 --- b branch should be inactive
224 --- b branch should be inactive
225
225
226 $ hg branches
226 $ hg branches
227 a branch name much longer than the default justification used by branches 7:10ff5895aa57
227 a branch name much longer than the default justification used by branches 7:10ff5895aa57
228 c 6:589736a22561 (inactive)
228 c 6:589736a22561 (inactive)
229 a 5:d8cbc61dbaa6 (inactive)
229 a 5:d8cbc61dbaa6 (inactive)
230 default 0:19709c5a4e75 (inactive)
230 default 0:19709c5a4e75 (inactive)
231 $ hg branches -c
231 $ hg branches -c
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
233 b 12:2da6583810df (closed)
233 b 12:e3d49c0575d8 (closed)
234 c 6:589736a22561 (inactive)
234 c 6:589736a22561 (inactive)
235 a 5:d8cbc61dbaa6 (inactive)
235 a 5:d8cbc61dbaa6 (inactive)
236 default 0:19709c5a4e75 (inactive)
236 default 0:19709c5a4e75 (inactive)
237 $ hg branches -a
237 $ hg branches -a
238 a branch name much longer than the default justification used by branches 7:10ff5895aa57
238 a branch name much longer than the default justification used by branches 7:10ff5895aa57
239 $ hg heads b
239 $ hg heads b
240 no open branch heads found on branches b
240 no open branch heads found on branches b
241 [1]
241 [1]
242 $ hg heads --closed b
242 $ hg heads --closed b
243 changeset: 12:2da6583810df
243 changeset: 12:e3d49c0575d8
244 branch: b
244 branch: b
245 tag: tip
245 tag: tip
246 parent: 8:eebb944467c9
246 parent: 8:eebb944467c9
247 user: test
247 user: test
248 date: Thu Jan 01 00:00:09 1970 +0000
248 date: Thu Jan 01 00:00:09 1970 +0000
249 summary: close this part branch too
249 summary: close this part branch too
250
250
251 changeset: 11:c84627f3c15d
251 changeset: 11:d3f163457ebf
252 branch: b
252 branch: b
253 user: test
253 user: test
254 date: Thu Jan 01 00:00:09 1970 +0000
254 date: Thu Jan 01 00:00:09 1970 +0000
255 summary: prune bad branch
255 summary: prune bad branch
256
256
257 $ echo 'xxx4' >> b
257 $ echo 'xxx4' >> b
258 $ hg commit -d '9 0' -m 'reopen branch with a change'
258 $ hg commit -d '9 0' -m 'reopen branch with a change'
259 reopening closed branch head 12
259 reopening closed branch head 12
260
260
261 --- branch b is back in action
261 --- branch b is back in action
262
262
263 $ hg branches -a
263 $ hg branches -a
264 b 13:6ac12926b8c3
264 b 13:e23b5505d1ad
265 a branch name much longer than the default justification used by branches 7:10ff5895aa57
265 a branch name much longer than the default justification used by branches 7:10ff5895aa57
266
266
267 ---- test heads listings
267 ---- test heads listings
268
268
269 $ hg heads
269 $ hg heads
270 changeset: 13:6ac12926b8c3
270 changeset: 13:e23b5505d1ad
271 branch: b
271 branch: b
272 tag: tip
272 tag: tip
273 user: test
273 user: test
274 date: Thu Jan 01 00:00:09 1970 +0000
274 date: Thu Jan 01 00:00:09 1970 +0000
275 summary: reopen branch with a change
275 summary: reopen branch with a change
276
276
277 changeset: 7:10ff5895aa57
277 changeset: 7:10ff5895aa57
278 branch: a branch name much longer than the default justification used by branches
278 branch: a branch name much longer than the default justification used by branches
279 user: test
279 user: test
280 date: Thu Jan 01 00:00:06 1970 +0000
280 date: Thu Jan 01 00:00:06 1970 +0000
281 summary: Adding d branch
281 summary: Adding d branch
282
282
283 changeset: 6:589736a22561
283 changeset: 6:589736a22561
284 branch: c
284 branch: c
285 user: test
285 user: test
286 date: Thu Jan 01 00:00:05 1970 +0000
286 date: Thu Jan 01 00:00:05 1970 +0000
287 summary: Adding c branch
287 summary: Adding c branch
288
288
289 changeset: 5:d8cbc61dbaa6
289 changeset: 5:d8cbc61dbaa6
290 branch: a
290 branch: a
291 parent: 2:881fe2b92ad0
291 parent: 2:881fe2b92ad0
292 user: test
292 user: test
293 date: Thu Jan 01 00:00:04 1970 +0000
293 date: Thu Jan 01 00:00:04 1970 +0000
294 summary: Adding b branch head 2
294 summary: Adding b branch head 2
295
295
296 changeset: 0:19709c5a4e75
296 changeset: 0:19709c5a4e75
297 user: test
297 user: test
298 date: Thu Jan 01 00:00:00 1970 +0000
298 date: Thu Jan 01 00:00:00 1970 +0000
299 summary: Adding root node
299 summary: Adding root node
300
300
301
301
302 branch default
302 branch default
303
303
304 $ hg heads default
304 $ hg heads default
305 changeset: 0:19709c5a4e75
305 changeset: 0:19709c5a4e75
306 user: test
306 user: test
307 date: Thu Jan 01 00:00:00 1970 +0000
307 date: Thu Jan 01 00:00:00 1970 +0000
308 summary: Adding root node
308 summary: Adding root node
309
309
310
310
311 branch a
311 branch a
312
312
313 $ hg heads a
313 $ hg heads a
314 changeset: 5:d8cbc61dbaa6
314 changeset: 5:d8cbc61dbaa6
315 branch: a
315 branch: a
316 parent: 2:881fe2b92ad0
316 parent: 2:881fe2b92ad0
317 user: test
317 user: test
318 date: Thu Jan 01 00:00:04 1970 +0000
318 date: Thu Jan 01 00:00:04 1970 +0000
319 summary: Adding b branch head 2
319 summary: Adding b branch head 2
320
320
321 $ hg heads --active a
321 $ hg heads --active a
322 no open branch heads found on branches a
322 no open branch heads found on branches a
323 [1]
323 [1]
324
324
325 branch b
325 branch b
326
326
327 $ hg heads b
327 $ hg heads b
328 changeset: 13:6ac12926b8c3
328 changeset: 13:e23b5505d1ad
329 branch: b
329 branch: b
330 tag: tip
330 tag: tip
331 user: test
331 user: test
332 date: Thu Jan 01 00:00:09 1970 +0000
332 date: Thu Jan 01 00:00:09 1970 +0000
333 summary: reopen branch with a change
333 summary: reopen branch with a change
334
334
335 $ hg heads --closed b
335 $ hg heads --closed b
336 changeset: 13:6ac12926b8c3
336 changeset: 13:e23b5505d1ad
337 branch: b
337 branch: b
338 tag: tip
338 tag: tip
339 user: test
339 user: test
340 date: Thu Jan 01 00:00:09 1970 +0000
340 date: Thu Jan 01 00:00:09 1970 +0000
341 summary: reopen branch with a change
341 summary: reopen branch with a change
342
342
343 changeset: 11:c84627f3c15d
343 changeset: 11:d3f163457ebf
344 branch: b
344 branch: b
345 user: test
345 user: test
346 date: Thu Jan 01 00:00:09 1970 +0000
346 date: Thu Jan 01 00:00:09 1970 +0000
347 summary: prune bad branch
347 summary: prune bad branch
348
348
349 default branch colors:
349 default branch colors:
350
350
351 $ echo "[extensions]" >> $HGRCPATH
351 $ echo "[extensions]" >> $HGRCPATH
352 $ echo "color =" >> $HGRCPATH
352 $ echo "color =" >> $HGRCPATH
353 $ echo "[color]" >> $HGRCPATH
353 $ echo "[color]" >> $HGRCPATH
354 $ echo "mode = ansi" >> $HGRCPATH
354 $ echo "mode = ansi" >> $HGRCPATH
355
355
356 $ hg up -C c
356 $ hg up -C c
357 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
357 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
358 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
358 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
359 $ hg up -C b
359 $ hg up -C b
360 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
360 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
361 $ hg branches --color=always
361 $ hg branches --color=always
362 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:6ac12926b8c3\x1b[0m (esc)
362 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
363 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
363 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
364 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
364 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
365 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
365 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
366
366
367 default closed branch color:
367 default closed branch color:
368
368
369 $ hg branches --color=always --closed
369 $ hg branches --color=always --closed
370 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:6ac12926b8c3\x1b[0m (esc)
370 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
371 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
371 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
372 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:717d2e6fabe1\x1b[0m (closed) (esc)
372 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
373 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
373 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
374 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
374 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
375
375
376 $ echo "[extensions]" >> $HGRCPATH
376 $ echo "[extensions]" >> $HGRCPATH
377 $ echo "color =" >> $HGRCPATH
377 $ echo "color =" >> $HGRCPATH
378 $ echo "[color]" >> $HGRCPATH
378 $ echo "[color]" >> $HGRCPATH
379 $ echo "branches.active = green" >> $HGRCPATH
379 $ echo "branches.active = green" >> $HGRCPATH
380 $ echo "branches.closed = blue" >> $HGRCPATH
380 $ echo "branches.closed = blue" >> $HGRCPATH
381 $ echo "branches.current = red" >> $HGRCPATH
381 $ echo "branches.current = red" >> $HGRCPATH
382 $ echo "branches.inactive = magenta" >> $HGRCPATH
382 $ echo "branches.inactive = magenta" >> $HGRCPATH
383 $ echo "log.changeset = cyan" >> $HGRCPATH
383 $ echo "log.changeset = cyan" >> $HGRCPATH
384
384
385 custom branch colors:
385 custom branch colors:
386
386
387 $ hg branches --color=always
387 $ hg branches --color=always
388 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:6ac12926b8c3\x1b[0m (esc)
388 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
389 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
389 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
390 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
390 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
391 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
391 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
392
392
393 custom closed branch color:
393 custom closed branch color:
394
394
395 $ hg branches --color=always --closed
395 $ hg branches --color=always --closed
396 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:6ac12926b8c3\x1b[0m (esc)
396 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
397 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
397 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
398 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:717d2e6fabe1\x1b[0m (closed) (esc)
398 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
399 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
399 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
400 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
400 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -1,1360 +1,1360
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo a > a
3 $ echo a > a
4 $ hg add a
4 $ hg add a
5 $ echo line 1 > b
5 $ echo line 1 > b
6 $ echo line 2 >> b
6 $ echo line 2 >> b
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
7 $ hg commit -l b -d '1000000 0' -u 'User Name <user@hostname>'
8
8
9 $ hg add b
9 $ hg add b
10 $ echo other 1 > c
10 $ echo other 1 > c
11 $ echo other 2 >> c
11 $ echo other 2 >> c
12 $ echo >> c
12 $ echo >> c
13 $ echo other 3 >> c
13 $ echo other 3 >> c
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
14 $ hg commit -l c -d '1100000 0' -u 'A. N. Other <other@place>'
15
15
16 $ hg add c
16 $ hg add c
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
17 $ hg commit -m 'no person' -d '1200000 0' -u 'other@place'
18 $ echo c >> c
18 $ echo c >> c
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
19 $ hg commit -m 'no user, no domain' -d '1300000 0' -u 'person'
20
20
21 $ echo foo > .hg/branch
21 $ echo foo > .hg/branch
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
22 $ hg commit -m 'new branch' -d '1400000 0' -u 'person'
23
23
24 $ hg co -q 3
24 $ hg co -q 3
25 $ echo other 4 >> d
25 $ echo other 4 >> d
26 $ hg add d
26 $ hg add d
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
27 $ hg commit -m 'new head' -d '1500000 0' -u 'person'
28
28
29 $ hg merge -q foo
29 $ hg merge -q foo
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
30 $ hg commit -m 'merge' -d '1500001 0' -u 'person'
31
31
32 Second branch starting at nullrev:
32 Second branch starting at nullrev:
33
33
34 $ hg update null
34 $ hg update null
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
36 $ echo second > second
36 $ echo second > second
37 $ hg add second
37 $ hg add second
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
38 $ hg commit -m second -d '1000000 0' -u 'User Name <user@hostname>'
39 created new head
39 created new head
40
40
41 $ echo third > third
41 $ echo third > third
42 $ hg add third
42 $ hg add third
43 $ hg mv second fourth
43 $ hg mv second fourth
44 $ hg commit -m third -d "2020-01-01 10:01"
44 $ hg commit -m third -d "2020-01-01 10:01"
45
45
46 Make sure user/global hgrc does not affect tests
46 Make sure user/global hgrc does not affect tests
47
47
48 $ echo '[ui]' > .hg/hgrc
48 $ echo '[ui]' > .hg/hgrc
49 $ echo 'logtemplate =' >> .hg/hgrc
49 $ echo 'logtemplate =' >> .hg/hgrc
50 $ echo 'style =' >> .hg/hgrc
50 $ echo 'style =' >> .hg/hgrc
51
51
52 Default style is like normal output:
52 Default style is like normal output:
53
53
54 $ hg log > log.out
54 $ hg log > log.out
55 $ hg log --style default > style.out
55 $ hg log --style default > style.out
56 $ cmp log.out style.out || diff -u log.out style.out
56 $ cmp log.out style.out || diff -u log.out style.out
57
57
58 $ hg log -v > log.out
58 $ hg log -v > log.out
59 $ hg log -v --style default > style.out
59 $ hg log -v --style default > style.out
60 $ cmp log.out style.out || diff -u log.out style.out
60 $ cmp log.out style.out || diff -u log.out style.out
61
61
62 $ hg log --debug > log.out
62 $ hg log --debug > log.out
63 $ hg log --debug --style default > style.out
63 $ hg log --debug --style default > style.out
64 $ cmp log.out style.out || diff -u log.out style.out
64 $ cmp log.out style.out || diff -u log.out style.out
65
65
66 Revision with no copies (used to print a traceback):
66 Revision with no copies (used to print a traceback):
67
67
68 $ hg tip -v --template '\n'
68 $ hg tip -v --template '\n'
69
69
70
70
71 Compact style works:
71 Compact style works:
72
72
73 $ hg log --style compact
73 $ hg log --style compact
74 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
74 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
75 third
75 third
76
76
77 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
77 7:-1 29114dbae42b 1970-01-12 13:46 +0000 user
78 second
78 second
79
79
80 6:5,4 c7b487c6c50e 1970-01-18 08:40 +0000 person
80 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
81 merge
81 merge
82
82
83 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
83 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
84 new head
84 new head
85
85
86 4 32a18f097fcc 1970-01-17 04:53 +0000 person
86 4 bbe44766e73d 1970-01-17 04:53 +0000 person
87 new branch
87 new branch
88
88
89 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
89 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
90 no user, no domain
90 no user, no domain
91
91
92 2 97054abb4ab8 1970-01-14 21:20 +0000 other
92 2 97054abb4ab8 1970-01-14 21:20 +0000 other
93 no person
93 no person
94
94
95 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
95 1 b608e9d1a3f0 1970-01-13 17:33 +0000 other
96 other 1
96 other 1
97
97
98 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
98 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 user
99 line 1
99 line 1
100
100
101
101
102 $ hg log -v --style compact
102 $ hg log -v --style compact
103 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
103 8[tip] 95c24699272e 2020-01-01 10:01 +0000 test
104 third
104 third
105
105
106 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
106 7:-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
107 second
107 second
108
108
109 6:5,4 c7b487c6c50e 1970-01-18 08:40 +0000 person
109 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
110 merge
110 merge
111
111
112 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
112 5:3 13207e5a10d9 1970-01-18 08:40 +0000 person
113 new head
113 new head
114
114
115 4 32a18f097fcc 1970-01-17 04:53 +0000 person
115 4 bbe44766e73d 1970-01-17 04:53 +0000 person
116 new branch
116 new branch
117
117
118 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
118 3 10e46f2dcbf4 1970-01-16 01:06 +0000 person
119 no user, no domain
119 no user, no domain
120
120
121 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
121 2 97054abb4ab8 1970-01-14 21:20 +0000 other@place
122 no person
122 no person
123
123
124 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
124 1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
125 other 1
125 other 1
126 other 2
126 other 2
127
127
128 other 3
128 other 3
129
129
130 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
130 0 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
131 line 1
131 line 1
132 line 2
132 line 2
133
133
134
134
135 $ hg log --debug --style compact
135 $ hg log --debug --style compact
136 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
136 8[tip]:7,-1 95c24699272e 2020-01-01 10:01 +0000 test
137 third
137 third
138
138
139 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
139 7:-1,-1 29114dbae42b 1970-01-12 13:46 +0000 User Name <user@hostname>
140 second
140 second
141
141
142 6:5,4 c7b487c6c50e 1970-01-18 08:40 +0000 person
142 6:5,4 d41e714fe50d 1970-01-18 08:40 +0000 person
143 merge
143 merge
144
144
145 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
145 5:3,-1 13207e5a10d9 1970-01-18 08:40 +0000 person
146 new head
146 new head
147
147
148 4:3,-1 32a18f097fcc 1970-01-17 04:53 +0000 person
148 4:3,-1 bbe44766e73d 1970-01-17 04:53 +0000 person
149 new branch
149 new branch
150
150
151 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
151 3:2,-1 10e46f2dcbf4 1970-01-16 01:06 +0000 person
152 no user, no domain
152 no user, no domain
153
153
154 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
154 2:1,-1 97054abb4ab8 1970-01-14 21:20 +0000 other@place
155 no person
155 no person
156
156
157 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
157 1:0,-1 b608e9d1a3f0 1970-01-13 17:33 +0000 A. N. Other <other@place>
158 other 1
158 other 1
159 other 2
159 other 2
160
160
161 other 3
161 other 3
162
162
163 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
163 0:-1,-1 1e4e1b8f71e0 1970-01-12 13:46 +0000 User Name <user@hostname>
164 line 1
164 line 1
165 line 2
165 line 2
166
166
167
167
168 Test xml styles:
168 Test xml styles:
169
169
170 $ hg log --style xml
170 $ hg log --style xml
171 <?xml version="1.0"?>
171 <?xml version="1.0"?>
172 <log>
172 <log>
173 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
173 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
174 <tag>tip</tag>
174 <tag>tip</tag>
175 <author email="test">test</author>
175 <author email="test">test</author>
176 <date>2020-01-01T10:01:00+00:00</date>
176 <date>2020-01-01T10:01:00+00:00</date>
177 <msg xml:space="preserve">third</msg>
177 <msg xml:space="preserve">third</msg>
178 </logentry>
178 </logentry>
179 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
179 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
180 <parent revision="-1" node="0000000000000000000000000000000000000000" />
180 <parent revision="-1" node="0000000000000000000000000000000000000000" />
181 <author email="user@hostname">User Name</author>
181 <author email="user@hostname">User Name</author>
182 <date>1970-01-12T13:46:40+00:00</date>
182 <date>1970-01-12T13:46:40+00:00</date>
183 <msg xml:space="preserve">second</msg>
183 <msg xml:space="preserve">second</msg>
184 </logentry>
184 </logentry>
185 <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
185 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
186 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
186 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
187 <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
187 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
188 <author email="person">person</author>
188 <author email="person">person</author>
189 <date>1970-01-18T08:40:01+00:00</date>
189 <date>1970-01-18T08:40:01+00:00</date>
190 <msg xml:space="preserve">merge</msg>
190 <msg xml:space="preserve">merge</msg>
191 </logentry>
191 </logentry>
192 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
192 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
193 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
193 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
194 <author email="person">person</author>
194 <author email="person">person</author>
195 <date>1970-01-18T08:40:00+00:00</date>
195 <date>1970-01-18T08:40:00+00:00</date>
196 <msg xml:space="preserve">new head</msg>
196 <msg xml:space="preserve">new head</msg>
197 </logentry>
197 </logentry>
198 <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
198 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
199 <branch>foo</branch>
199 <branch>foo</branch>
200 <author email="person">person</author>
200 <author email="person">person</author>
201 <date>1970-01-17T04:53:20+00:00</date>
201 <date>1970-01-17T04:53:20+00:00</date>
202 <msg xml:space="preserve">new branch</msg>
202 <msg xml:space="preserve">new branch</msg>
203 </logentry>
203 </logentry>
204 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
204 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
205 <author email="person">person</author>
205 <author email="person">person</author>
206 <date>1970-01-16T01:06:40+00:00</date>
206 <date>1970-01-16T01:06:40+00:00</date>
207 <msg xml:space="preserve">no user, no domain</msg>
207 <msg xml:space="preserve">no user, no domain</msg>
208 </logentry>
208 </logentry>
209 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
209 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
210 <author email="other@place">other</author>
210 <author email="other@place">other</author>
211 <date>1970-01-14T21:20:00+00:00</date>
211 <date>1970-01-14T21:20:00+00:00</date>
212 <msg xml:space="preserve">no person</msg>
212 <msg xml:space="preserve">no person</msg>
213 </logentry>
213 </logentry>
214 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
214 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
215 <author email="other@place">A. N. Other</author>
215 <author email="other@place">A. N. Other</author>
216 <date>1970-01-13T17:33:20+00:00</date>
216 <date>1970-01-13T17:33:20+00:00</date>
217 <msg xml:space="preserve">other 1
217 <msg xml:space="preserve">other 1
218 other 2
218 other 2
219
219
220 other 3</msg>
220 other 3</msg>
221 </logentry>
221 </logentry>
222 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
222 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
223 <author email="user@hostname">User Name</author>
223 <author email="user@hostname">User Name</author>
224 <date>1970-01-12T13:46:40+00:00</date>
224 <date>1970-01-12T13:46:40+00:00</date>
225 <msg xml:space="preserve">line 1
225 <msg xml:space="preserve">line 1
226 line 2</msg>
226 line 2</msg>
227 </logentry>
227 </logentry>
228 </log>
228 </log>
229
229
230 $ hg log -v --style xml
230 $ hg log -v --style xml
231 <?xml version="1.0"?>
231 <?xml version="1.0"?>
232 <log>
232 <log>
233 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
233 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
234 <tag>tip</tag>
234 <tag>tip</tag>
235 <author email="test">test</author>
235 <author email="test">test</author>
236 <date>2020-01-01T10:01:00+00:00</date>
236 <date>2020-01-01T10:01:00+00:00</date>
237 <msg xml:space="preserve">third</msg>
237 <msg xml:space="preserve">third</msg>
238 <paths>
238 <paths>
239 <path action="A">fourth</path>
239 <path action="A">fourth</path>
240 <path action="A">third</path>
240 <path action="A">third</path>
241 <path action="R">second</path>
241 <path action="R">second</path>
242 </paths>
242 </paths>
243 <copies>
243 <copies>
244 <copy source="second">fourth</copy>
244 <copy source="second">fourth</copy>
245 </copies>
245 </copies>
246 </logentry>
246 </logentry>
247 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
247 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
248 <parent revision="-1" node="0000000000000000000000000000000000000000" />
248 <parent revision="-1" node="0000000000000000000000000000000000000000" />
249 <author email="user@hostname">User Name</author>
249 <author email="user@hostname">User Name</author>
250 <date>1970-01-12T13:46:40+00:00</date>
250 <date>1970-01-12T13:46:40+00:00</date>
251 <msg xml:space="preserve">second</msg>
251 <msg xml:space="preserve">second</msg>
252 <paths>
252 <paths>
253 <path action="A">second</path>
253 <path action="A">second</path>
254 </paths>
254 </paths>
255 </logentry>
255 </logentry>
256 <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
256 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
257 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
257 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
258 <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
258 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
259 <author email="person">person</author>
259 <author email="person">person</author>
260 <date>1970-01-18T08:40:01+00:00</date>
260 <date>1970-01-18T08:40:01+00:00</date>
261 <msg xml:space="preserve">merge</msg>
261 <msg xml:space="preserve">merge</msg>
262 <paths>
262 <paths>
263 </paths>
263 </paths>
264 </logentry>
264 </logentry>
265 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
265 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
266 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
266 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
267 <author email="person">person</author>
267 <author email="person">person</author>
268 <date>1970-01-18T08:40:00+00:00</date>
268 <date>1970-01-18T08:40:00+00:00</date>
269 <msg xml:space="preserve">new head</msg>
269 <msg xml:space="preserve">new head</msg>
270 <paths>
270 <paths>
271 <path action="A">d</path>
271 <path action="A">d</path>
272 </paths>
272 </paths>
273 </logentry>
273 </logentry>
274 <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
274 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
275 <branch>foo</branch>
275 <branch>foo</branch>
276 <author email="person">person</author>
276 <author email="person">person</author>
277 <date>1970-01-17T04:53:20+00:00</date>
277 <date>1970-01-17T04:53:20+00:00</date>
278 <msg xml:space="preserve">new branch</msg>
278 <msg xml:space="preserve">new branch</msg>
279 <paths>
279 <paths>
280 </paths>
280 </paths>
281 </logentry>
281 </logentry>
282 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
282 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
283 <author email="person">person</author>
283 <author email="person">person</author>
284 <date>1970-01-16T01:06:40+00:00</date>
284 <date>1970-01-16T01:06:40+00:00</date>
285 <msg xml:space="preserve">no user, no domain</msg>
285 <msg xml:space="preserve">no user, no domain</msg>
286 <paths>
286 <paths>
287 <path action="M">c</path>
287 <path action="M">c</path>
288 </paths>
288 </paths>
289 </logentry>
289 </logentry>
290 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
290 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
291 <author email="other@place">other</author>
291 <author email="other@place">other</author>
292 <date>1970-01-14T21:20:00+00:00</date>
292 <date>1970-01-14T21:20:00+00:00</date>
293 <msg xml:space="preserve">no person</msg>
293 <msg xml:space="preserve">no person</msg>
294 <paths>
294 <paths>
295 <path action="A">c</path>
295 <path action="A">c</path>
296 </paths>
296 </paths>
297 </logentry>
297 </logentry>
298 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
298 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
299 <author email="other@place">A. N. Other</author>
299 <author email="other@place">A. N. Other</author>
300 <date>1970-01-13T17:33:20+00:00</date>
300 <date>1970-01-13T17:33:20+00:00</date>
301 <msg xml:space="preserve">other 1
301 <msg xml:space="preserve">other 1
302 other 2
302 other 2
303
303
304 other 3</msg>
304 other 3</msg>
305 <paths>
305 <paths>
306 <path action="A">b</path>
306 <path action="A">b</path>
307 </paths>
307 </paths>
308 </logentry>
308 </logentry>
309 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
309 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
310 <author email="user@hostname">User Name</author>
310 <author email="user@hostname">User Name</author>
311 <date>1970-01-12T13:46:40+00:00</date>
311 <date>1970-01-12T13:46:40+00:00</date>
312 <msg xml:space="preserve">line 1
312 <msg xml:space="preserve">line 1
313 line 2</msg>
313 line 2</msg>
314 <paths>
314 <paths>
315 <path action="A">a</path>
315 <path action="A">a</path>
316 </paths>
316 </paths>
317 </logentry>
317 </logentry>
318 </log>
318 </log>
319
319
320 $ hg log --debug --style xml
320 $ hg log --debug --style xml
321 <?xml version="1.0"?>
321 <?xml version="1.0"?>
322 <log>
322 <log>
323 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
323 <logentry revision="8" node="95c24699272ef57d062b8bccc32c878bf841784a">
324 <tag>tip</tag>
324 <tag>tip</tag>
325 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
325 <parent revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453" />
326 <parent revision="-1" node="0000000000000000000000000000000000000000" />
326 <parent revision="-1" node="0000000000000000000000000000000000000000" />
327 <author email="test">test</author>
327 <author email="test">test</author>
328 <date>2020-01-01T10:01:00+00:00</date>
328 <date>2020-01-01T10:01:00+00:00</date>
329 <msg xml:space="preserve">third</msg>
329 <msg xml:space="preserve">third</msg>
330 <paths>
330 <paths>
331 <path action="A">fourth</path>
331 <path action="A">fourth</path>
332 <path action="A">third</path>
332 <path action="A">third</path>
333 <path action="R">second</path>
333 <path action="R">second</path>
334 </paths>
334 </paths>
335 <copies>
335 <copies>
336 <copy source="second">fourth</copy>
336 <copy source="second">fourth</copy>
337 </copies>
337 </copies>
338 <extra key="branch">default</extra>
338 <extra key="branch">default</extra>
339 </logentry>
339 </logentry>
340 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
340 <logentry revision="7" node="29114dbae42b9f078cf2714dbe3a86bba8ec7453">
341 <parent revision="-1" node="0000000000000000000000000000000000000000" />
341 <parent revision="-1" node="0000000000000000000000000000000000000000" />
342 <parent revision="-1" node="0000000000000000000000000000000000000000" />
342 <parent revision="-1" node="0000000000000000000000000000000000000000" />
343 <author email="user@hostname">User Name</author>
343 <author email="user@hostname">User Name</author>
344 <date>1970-01-12T13:46:40+00:00</date>
344 <date>1970-01-12T13:46:40+00:00</date>
345 <msg xml:space="preserve">second</msg>
345 <msg xml:space="preserve">second</msg>
346 <paths>
346 <paths>
347 <path action="A">second</path>
347 <path action="A">second</path>
348 </paths>
348 </paths>
349 <extra key="branch">default</extra>
349 <extra key="branch">default</extra>
350 </logentry>
350 </logentry>
351 <logentry revision="6" node="c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f">
351 <logentry revision="6" node="d41e714fe50d9e4a5f11b4d595d543481b5f980b">
352 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
352 <parent revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f" />
353 <parent revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4" />
353 <parent revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74" />
354 <author email="person">person</author>
354 <author email="person">person</author>
355 <date>1970-01-18T08:40:01+00:00</date>
355 <date>1970-01-18T08:40:01+00:00</date>
356 <msg xml:space="preserve">merge</msg>
356 <msg xml:space="preserve">merge</msg>
357 <paths>
357 <paths>
358 </paths>
358 </paths>
359 <extra key="branch">default</extra>
359 <extra key="branch">default</extra>
360 </logentry>
360 </logentry>
361 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
361 <logentry revision="5" node="13207e5a10d9fd28ec424934298e176197f2c67f">
362 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
362 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
363 <parent revision="-1" node="0000000000000000000000000000000000000000" />
364 <author email="person">person</author>
364 <author email="person">person</author>
365 <date>1970-01-18T08:40:00+00:00</date>
365 <date>1970-01-18T08:40:00+00:00</date>
366 <msg xml:space="preserve">new head</msg>
366 <msg xml:space="preserve">new head</msg>
367 <paths>
367 <paths>
368 <path action="A">d</path>
368 <path action="A">d</path>
369 </paths>
369 </paths>
370 <extra key="branch">default</extra>
370 <extra key="branch">default</extra>
371 </logentry>
371 </logentry>
372 <logentry revision="4" node="32a18f097fcccf76ef282f62f8a85b3adf8d13c4">
372 <logentry revision="4" node="bbe44766e73d5f11ed2177f1838de10c53ef3e74">
373 <branch>foo</branch>
373 <branch>foo</branch>
374 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
374 <parent revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47" />
375 <parent revision="-1" node="0000000000000000000000000000000000000000" />
375 <parent revision="-1" node="0000000000000000000000000000000000000000" />
376 <author email="person">person</author>
376 <author email="person">person</author>
377 <date>1970-01-17T04:53:20+00:00</date>
377 <date>1970-01-17T04:53:20+00:00</date>
378 <msg xml:space="preserve">new branch</msg>
378 <msg xml:space="preserve">new branch</msg>
379 <paths>
379 <paths>
380 </paths>
380 </paths>
381 <extra key="branch">foo</extra>
381 <extra key="branch">foo</extra>
382 </logentry>
382 </logentry>
383 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
383 <logentry revision="3" node="10e46f2dcbf4823578cf180f33ecf0b957964c47">
384 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
384 <parent revision="2" node="97054abb4ab824450e9164180baf491ae0078465" />
385 <parent revision="-1" node="0000000000000000000000000000000000000000" />
385 <parent revision="-1" node="0000000000000000000000000000000000000000" />
386 <author email="person">person</author>
386 <author email="person">person</author>
387 <date>1970-01-16T01:06:40+00:00</date>
387 <date>1970-01-16T01:06:40+00:00</date>
388 <msg xml:space="preserve">no user, no domain</msg>
388 <msg xml:space="preserve">no user, no domain</msg>
389 <paths>
389 <paths>
390 <path action="M">c</path>
390 <path action="M">c</path>
391 </paths>
391 </paths>
392 <extra key="branch">default</extra>
392 <extra key="branch">default</extra>
393 </logentry>
393 </logentry>
394 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
394 <logentry revision="2" node="97054abb4ab824450e9164180baf491ae0078465">
395 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
395 <parent revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965" />
396 <parent revision="-1" node="0000000000000000000000000000000000000000" />
396 <parent revision="-1" node="0000000000000000000000000000000000000000" />
397 <author email="other@place">other</author>
397 <author email="other@place">other</author>
398 <date>1970-01-14T21:20:00+00:00</date>
398 <date>1970-01-14T21:20:00+00:00</date>
399 <msg xml:space="preserve">no person</msg>
399 <msg xml:space="preserve">no person</msg>
400 <paths>
400 <paths>
401 <path action="A">c</path>
401 <path action="A">c</path>
402 </paths>
402 </paths>
403 <extra key="branch">default</extra>
403 <extra key="branch">default</extra>
404 </logentry>
404 </logentry>
405 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
405 <logentry revision="1" node="b608e9d1a3f0273ccf70fb85fd6866b3482bf965">
406 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
406 <parent revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f" />
407 <parent revision="-1" node="0000000000000000000000000000000000000000" />
407 <parent revision="-1" node="0000000000000000000000000000000000000000" />
408 <author email="other@place">A. N. Other</author>
408 <author email="other@place">A. N. Other</author>
409 <date>1970-01-13T17:33:20+00:00</date>
409 <date>1970-01-13T17:33:20+00:00</date>
410 <msg xml:space="preserve">other 1
410 <msg xml:space="preserve">other 1
411 other 2
411 other 2
412
412
413 other 3</msg>
413 other 3</msg>
414 <paths>
414 <paths>
415 <path action="A">b</path>
415 <path action="A">b</path>
416 </paths>
416 </paths>
417 <extra key="branch">default</extra>
417 <extra key="branch">default</extra>
418 </logentry>
418 </logentry>
419 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
419 <logentry revision="0" node="1e4e1b8f71e05681d422154f5421e385fec3454f">
420 <parent revision="-1" node="0000000000000000000000000000000000000000" />
420 <parent revision="-1" node="0000000000000000000000000000000000000000" />
421 <parent revision="-1" node="0000000000000000000000000000000000000000" />
421 <parent revision="-1" node="0000000000000000000000000000000000000000" />
422 <author email="user@hostname">User Name</author>
422 <author email="user@hostname">User Name</author>
423 <date>1970-01-12T13:46:40+00:00</date>
423 <date>1970-01-12T13:46:40+00:00</date>
424 <msg xml:space="preserve">line 1
424 <msg xml:space="preserve">line 1
425 line 2</msg>
425 line 2</msg>
426 <paths>
426 <paths>
427 <path action="A">a</path>
427 <path action="A">a</path>
428 </paths>
428 </paths>
429 <extra key="branch">default</extra>
429 <extra key="branch">default</extra>
430 </logentry>
430 </logentry>
431 </log>
431 </log>
432
432
433
433
434 Error if style not readable:
434 Error if style not readable:
435
435
436 $ touch q
436 $ touch q
437 $ chmod 0 q
437 $ chmod 0 q
438 $ hg log --style ./q
438 $ hg log --style ./q
439 abort: Permission denied: ./q
439 abort: Permission denied: ./q
440 [255]
440 [255]
441
441
442 Error if no style:
442 Error if no style:
443
443
444 $ hg log --style notexist
444 $ hg log --style notexist
445 abort: style not found: notexist
445 abort: style not found: notexist
446 [255]
446 [255]
447
447
448 Error if style missing key:
448 Error if style missing key:
449
449
450 $ echo 'q = q' > t
450 $ echo 'q = q' > t
451 $ hg log --style ./t
451 $ hg log --style ./t
452 abort: "changeset" not in template map
452 abort: "changeset" not in template map
453 [255]
453 [255]
454
454
455 Error if include fails:
455 Error if include fails:
456
456
457 $ echo 'changeset = q' >> t
457 $ echo 'changeset = q' >> t
458 $ hg log --style ./t
458 $ hg log --style ./t
459 abort: template file ./q: Permission denied
459 abort: template file ./q: Permission denied
460 [255]
460 [255]
461
461
462 Include works:
462 Include works:
463
463
464 $ rm q
464 $ rm q
465 $ echo '{rev}' > q
465 $ echo '{rev}' > q
466 $ hg log --style ./t
466 $ hg log --style ./t
467 8
467 8
468 7
468 7
469 6
469 6
470 5
470 5
471 4
471 4
472 3
472 3
473 2
473 2
474 1
474 1
475 0
475 0
476
476
477 ui.style works:
477 ui.style works:
478
478
479 $ echo '[ui]' > .hg/hgrc
479 $ echo '[ui]' > .hg/hgrc
480 $ echo 'style = t' >> .hg/hgrc
480 $ echo 'style = t' >> .hg/hgrc
481 $ hg log
481 $ hg log
482 8
482 8
483 7
483 7
484 6
484 6
485 5
485 5
486 4
486 4
487 3
487 3
488 2
488 2
489 1
489 1
490 0
490 0
491
491
492
492
493 Issue338:
493 Issue338:
494
494
495 $ hg log --style=changelog > changelog
495 $ hg log --style=changelog > changelog
496
496
497 $ cat changelog
497 $ cat changelog
498 2020-01-01 test <test>
498 2020-01-01 test <test>
499
499
500 * fourth, second, third:
500 * fourth, second, third:
501 third
501 third
502 [95c24699272e] [tip]
502 [95c24699272e] [tip]
503
503
504 1970-01-12 User Name <user@hostname>
504 1970-01-12 User Name <user@hostname>
505
505
506 * second:
506 * second:
507 second
507 second
508 [29114dbae42b]
508 [29114dbae42b]
509
509
510 1970-01-18 person <person>
510 1970-01-18 person <person>
511
511
512 * merge
512 * merge
513 [c7b487c6c50e]
513 [d41e714fe50d]
514
514
515 * d:
515 * d:
516 new head
516 new head
517 [13207e5a10d9]
517 [13207e5a10d9]
518
518
519 1970-01-17 person <person>
519 1970-01-17 person <person>
520
520
521 * new branch
521 * new branch
522 [32a18f097fcc] <foo>
522 [bbe44766e73d] <foo>
523
523
524 1970-01-16 person <person>
524 1970-01-16 person <person>
525
525
526 * c:
526 * c:
527 no user, no domain
527 no user, no domain
528 [10e46f2dcbf4]
528 [10e46f2dcbf4]
529
529
530 1970-01-14 other <other@place>
530 1970-01-14 other <other@place>
531
531
532 * c:
532 * c:
533 no person
533 no person
534 [97054abb4ab8]
534 [97054abb4ab8]
535
535
536 1970-01-13 A. N. Other <other@place>
536 1970-01-13 A. N. Other <other@place>
537
537
538 * b:
538 * b:
539 other 1 other 2
539 other 1 other 2
540
540
541 other 3
541 other 3
542 [b608e9d1a3f0]
542 [b608e9d1a3f0]
543
543
544 1970-01-12 User Name <user@hostname>
544 1970-01-12 User Name <user@hostname>
545
545
546 * a:
546 * a:
547 line 1 line 2
547 line 1 line 2
548 [1e4e1b8f71e0]
548 [1e4e1b8f71e0]
549
549
550
550
551 Issue2130: xml output for 'hg heads' is malformed
551 Issue2130: xml output for 'hg heads' is malformed
552
552
553 $ hg heads --style changelog
553 $ hg heads --style changelog
554 2020-01-01 test <test>
554 2020-01-01 test <test>
555
555
556 * fourth, second, third:
556 * fourth, second, third:
557 third
557 third
558 [95c24699272e] [tip]
558 [95c24699272e] [tip]
559
559
560 1970-01-18 person <person>
560 1970-01-18 person <person>
561
561
562 * merge
562 * merge
563 [c7b487c6c50e]
563 [d41e714fe50d]
564
564
565 1970-01-17 person <person>
565 1970-01-17 person <person>
566
566
567 * new branch
567 * new branch
568 [32a18f097fcc] <foo>
568 [bbe44766e73d] <foo>
569
569
570
570
571 Keys work:
571 Keys work:
572
572
573 $ for key in author branch branches date desc file_adds file_dels file_mods \
573 $ for key in author branch branches date desc file_adds file_dels file_mods \
574 > file_copies file_copies_switch files \
574 > file_copies file_copies_switch files \
575 > manifest node parents rev tags diffstat extras; do
575 > manifest node parents rev tags diffstat extras; do
576 > for mode in '' --verbose --debug; do
576 > for mode in '' --verbose --debug; do
577 > hg log $mode --template "$key$mode: {$key}\n"
577 > hg log $mode --template "$key$mode: {$key}\n"
578 > done
578 > done
579 > done
579 > done
580 author: test
580 author: test
581 author: User Name <user@hostname>
581 author: User Name <user@hostname>
582 author: person
582 author: person
583 author: person
583 author: person
584 author: person
584 author: person
585 author: person
585 author: person
586 author: other@place
586 author: other@place
587 author: A. N. Other <other@place>
587 author: A. N. Other <other@place>
588 author: User Name <user@hostname>
588 author: User Name <user@hostname>
589 author--verbose: test
589 author--verbose: test
590 author--verbose: User Name <user@hostname>
590 author--verbose: User Name <user@hostname>
591 author--verbose: person
591 author--verbose: person
592 author--verbose: person
592 author--verbose: person
593 author--verbose: person
593 author--verbose: person
594 author--verbose: person
594 author--verbose: person
595 author--verbose: other@place
595 author--verbose: other@place
596 author--verbose: A. N. Other <other@place>
596 author--verbose: A. N. Other <other@place>
597 author--verbose: User Name <user@hostname>
597 author--verbose: User Name <user@hostname>
598 author--debug: test
598 author--debug: test
599 author--debug: User Name <user@hostname>
599 author--debug: User Name <user@hostname>
600 author--debug: person
600 author--debug: person
601 author--debug: person
601 author--debug: person
602 author--debug: person
602 author--debug: person
603 author--debug: person
603 author--debug: person
604 author--debug: other@place
604 author--debug: other@place
605 author--debug: A. N. Other <other@place>
605 author--debug: A. N. Other <other@place>
606 author--debug: User Name <user@hostname>
606 author--debug: User Name <user@hostname>
607 branch: default
607 branch: default
608 branch: default
608 branch: default
609 branch: default
609 branch: default
610 branch: default
610 branch: default
611 branch: foo
611 branch: foo
612 branch: default
612 branch: default
613 branch: default
613 branch: default
614 branch: default
614 branch: default
615 branch: default
615 branch: default
616 branch--verbose: default
616 branch--verbose: default
617 branch--verbose: default
617 branch--verbose: default
618 branch--verbose: default
618 branch--verbose: default
619 branch--verbose: default
619 branch--verbose: default
620 branch--verbose: foo
620 branch--verbose: foo
621 branch--verbose: default
621 branch--verbose: default
622 branch--verbose: default
622 branch--verbose: default
623 branch--verbose: default
623 branch--verbose: default
624 branch--verbose: default
624 branch--verbose: default
625 branch--debug: default
625 branch--debug: default
626 branch--debug: default
626 branch--debug: default
627 branch--debug: default
627 branch--debug: default
628 branch--debug: default
628 branch--debug: default
629 branch--debug: foo
629 branch--debug: foo
630 branch--debug: default
630 branch--debug: default
631 branch--debug: default
631 branch--debug: default
632 branch--debug: default
632 branch--debug: default
633 branch--debug: default
633 branch--debug: default
634 branches:
634 branches:
635 branches:
635 branches:
636 branches:
636 branches:
637 branches:
637 branches:
638 branches: foo
638 branches: foo
639 branches:
639 branches:
640 branches:
640 branches:
641 branches:
641 branches:
642 branches:
642 branches:
643 branches--verbose:
643 branches--verbose:
644 branches--verbose:
644 branches--verbose:
645 branches--verbose:
645 branches--verbose:
646 branches--verbose:
646 branches--verbose:
647 branches--verbose: foo
647 branches--verbose: foo
648 branches--verbose:
648 branches--verbose:
649 branches--verbose:
649 branches--verbose:
650 branches--verbose:
650 branches--verbose:
651 branches--verbose:
651 branches--verbose:
652 branches--debug:
652 branches--debug:
653 branches--debug:
653 branches--debug:
654 branches--debug:
654 branches--debug:
655 branches--debug:
655 branches--debug:
656 branches--debug: foo
656 branches--debug: foo
657 branches--debug:
657 branches--debug:
658 branches--debug:
658 branches--debug:
659 branches--debug:
659 branches--debug:
660 branches--debug:
660 branches--debug:
661 date: 1577872860.00
661 date: 1577872860.00
662 date: 1000000.00
662 date: 1000000.00
663 date: 1500001.00
663 date: 1500001.00
664 date: 1500000.00
664 date: 1500000.00
665 date: 1400000.00
665 date: 1400000.00
666 date: 1300000.00
666 date: 1300000.00
667 date: 1200000.00
667 date: 1200000.00
668 date: 1100000.00
668 date: 1100000.00
669 date: 1000000.00
669 date: 1000000.00
670 date--verbose: 1577872860.00
670 date--verbose: 1577872860.00
671 date--verbose: 1000000.00
671 date--verbose: 1000000.00
672 date--verbose: 1500001.00
672 date--verbose: 1500001.00
673 date--verbose: 1500000.00
673 date--verbose: 1500000.00
674 date--verbose: 1400000.00
674 date--verbose: 1400000.00
675 date--verbose: 1300000.00
675 date--verbose: 1300000.00
676 date--verbose: 1200000.00
676 date--verbose: 1200000.00
677 date--verbose: 1100000.00
677 date--verbose: 1100000.00
678 date--verbose: 1000000.00
678 date--verbose: 1000000.00
679 date--debug: 1577872860.00
679 date--debug: 1577872860.00
680 date--debug: 1000000.00
680 date--debug: 1000000.00
681 date--debug: 1500001.00
681 date--debug: 1500001.00
682 date--debug: 1500000.00
682 date--debug: 1500000.00
683 date--debug: 1400000.00
683 date--debug: 1400000.00
684 date--debug: 1300000.00
684 date--debug: 1300000.00
685 date--debug: 1200000.00
685 date--debug: 1200000.00
686 date--debug: 1100000.00
686 date--debug: 1100000.00
687 date--debug: 1000000.00
687 date--debug: 1000000.00
688 desc: third
688 desc: third
689 desc: second
689 desc: second
690 desc: merge
690 desc: merge
691 desc: new head
691 desc: new head
692 desc: new branch
692 desc: new branch
693 desc: no user, no domain
693 desc: no user, no domain
694 desc: no person
694 desc: no person
695 desc: other 1
695 desc: other 1
696 other 2
696 other 2
697
697
698 other 3
698 other 3
699 desc: line 1
699 desc: line 1
700 line 2
700 line 2
701 desc--verbose: third
701 desc--verbose: third
702 desc--verbose: second
702 desc--verbose: second
703 desc--verbose: merge
703 desc--verbose: merge
704 desc--verbose: new head
704 desc--verbose: new head
705 desc--verbose: new branch
705 desc--verbose: new branch
706 desc--verbose: no user, no domain
706 desc--verbose: no user, no domain
707 desc--verbose: no person
707 desc--verbose: no person
708 desc--verbose: other 1
708 desc--verbose: other 1
709 other 2
709 other 2
710
710
711 other 3
711 other 3
712 desc--verbose: line 1
712 desc--verbose: line 1
713 line 2
713 line 2
714 desc--debug: third
714 desc--debug: third
715 desc--debug: second
715 desc--debug: second
716 desc--debug: merge
716 desc--debug: merge
717 desc--debug: new head
717 desc--debug: new head
718 desc--debug: new branch
718 desc--debug: new branch
719 desc--debug: no user, no domain
719 desc--debug: no user, no domain
720 desc--debug: no person
720 desc--debug: no person
721 desc--debug: other 1
721 desc--debug: other 1
722 other 2
722 other 2
723
723
724 other 3
724 other 3
725 desc--debug: line 1
725 desc--debug: line 1
726 line 2
726 line 2
727 file_adds: fourth third
727 file_adds: fourth third
728 file_adds: second
728 file_adds: second
729 file_adds:
729 file_adds:
730 file_adds: d
730 file_adds: d
731 file_adds:
731 file_adds:
732 file_adds:
732 file_adds:
733 file_adds: c
733 file_adds: c
734 file_adds: b
734 file_adds: b
735 file_adds: a
735 file_adds: a
736 file_adds--verbose: fourth third
736 file_adds--verbose: fourth third
737 file_adds--verbose: second
737 file_adds--verbose: second
738 file_adds--verbose:
738 file_adds--verbose:
739 file_adds--verbose: d
739 file_adds--verbose: d
740 file_adds--verbose:
740 file_adds--verbose:
741 file_adds--verbose:
741 file_adds--verbose:
742 file_adds--verbose: c
742 file_adds--verbose: c
743 file_adds--verbose: b
743 file_adds--verbose: b
744 file_adds--verbose: a
744 file_adds--verbose: a
745 file_adds--debug: fourth third
745 file_adds--debug: fourth third
746 file_adds--debug: second
746 file_adds--debug: second
747 file_adds--debug:
747 file_adds--debug:
748 file_adds--debug: d
748 file_adds--debug: d
749 file_adds--debug:
749 file_adds--debug:
750 file_adds--debug:
750 file_adds--debug:
751 file_adds--debug: c
751 file_adds--debug: c
752 file_adds--debug: b
752 file_adds--debug: b
753 file_adds--debug: a
753 file_adds--debug: a
754 file_dels: second
754 file_dels: second
755 file_dels:
755 file_dels:
756 file_dels:
756 file_dels:
757 file_dels:
757 file_dels:
758 file_dels:
758 file_dels:
759 file_dels:
759 file_dels:
760 file_dels:
760 file_dels:
761 file_dels:
761 file_dels:
762 file_dels:
762 file_dels:
763 file_dels--verbose: second
763 file_dels--verbose: second
764 file_dels--verbose:
764 file_dels--verbose:
765 file_dels--verbose:
765 file_dels--verbose:
766 file_dels--verbose:
766 file_dels--verbose:
767 file_dels--verbose:
767 file_dels--verbose:
768 file_dels--verbose:
768 file_dels--verbose:
769 file_dels--verbose:
769 file_dels--verbose:
770 file_dels--verbose:
770 file_dels--verbose:
771 file_dels--verbose:
771 file_dels--verbose:
772 file_dels--debug: second
772 file_dels--debug: second
773 file_dels--debug:
773 file_dels--debug:
774 file_dels--debug:
774 file_dels--debug:
775 file_dels--debug:
775 file_dels--debug:
776 file_dels--debug:
776 file_dels--debug:
777 file_dels--debug:
777 file_dels--debug:
778 file_dels--debug:
778 file_dels--debug:
779 file_dels--debug:
779 file_dels--debug:
780 file_dels--debug:
780 file_dels--debug:
781 file_mods:
781 file_mods:
782 file_mods:
782 file_mods:
783 file_mods:
783 file_mods:
784 file_mods:
784 file_mods:
785 file_mods:
785 file_mods:
786 file_mods: c
786 file_mods: c
787 file_mods:
787 file_mods:
788 file_mods:
788 file_mods:
789 file_mods:
789 file_mods:
790 file_mods--verbose:
790 file_mods--verbose:
791 file_mods--verbose:
791 file_mods--verbose:
792 file_mods--verbose:
792 file_mods--verbose:
793 file_mods--verbose:
793 file_mods--verbose:
794 file_mods--verbose:
794 file_mods--verbose:
795 file_mods--verbose: c
795 file_mods--verbose: c
796 file_mods--verbose:
796 file_mods--verbose:
797 file_mods--verbose:
797 file_mods--verbose:
798 file_mods--verbose:
798 file_mods--verbose:
799 file_mods--debug:
799 file_mods--debug:
800 file_mods--debug:
800 file_mods--debug:
801 file_mods--debug:
801 file_mods--debug:
802 file_mods--debug:
802 file_mods--debug:
803 file_mods--debug:
803 file_mods--debug:
804 file_mods--debug: c
804 file_mods--debug: c
805 file_mods--debug:
805 file_mods--debug:
806 file_mods--debug:
806 file_mods--debug:
807 file_mods--debug:
807 file_mods--debug:
808 file_copies: fourth (second)
808 file_copies: fourth (second)
809 file_copies:
809 file_copies:
810 file_copies:
810 file_copies:
811 file_copies:
811 file_copies:
812 file_copies:
812 file_copies:
813 file_copies:
813 file_copies:
814 file_copies:
814 file_copies:
815 file_copies:
815 file_copies:
816 file_copies:
816 file_copies:
817 file_copies--verbose: fourth (second)
817 file_copies--verbose: fourth (second)
818 file_copies--verbose:
818 file_copies--verbose:
819 file_copies--verbose:
819 file_copies--verbose:
820 file_copies--verbose:
820 file_copies--verbose:
821 file_copies--verbose:
821 file_copies--verbose:
822 file_copies--verbose:
822 file_copies--verbose:
823 file_copies--verbose:
823 file_copies--verbose:
824 file_copies--verbose:
824 file_copies--verbose:
825 file_copies--verbose:
825 file_copies--verbose:
826 file_copies--debug: fourth (second)
826 file_copies--debug: fourth (second)
827 file_copies--debug:
827 file_copies--debug:
828 file_copies--debug:
828 file_copies--debug:
829 file_copies--debug:
829 file_copies--debug:
830 file_copies--debug:
830 file_copies--debug:
831 file_copies--debug:
831 file_copies--debug:
832 file_copies--debug:
832 file_copies--debug:
833 file_copies--debug:
833 file_copies--debug:
834 file_copies--debug:
834 file_copies--debug:
835 file_copies_switch:
835 file_copies_switch:
836 file_copies_switch:
836 file_copies_switch:
837 file_copies_switch:
837 file_copies_switch:
838 file_copies_switch:
838 file_copies_switch:
839 file_copies_switch:
839 file_copies_switch:
840 file_copies_switch:
840 file_copies_switch:
841 file_copies_switch:
841 file_copies_switch:
842 file_copies_switch:
842 file_copies_switch:
843 file_copies_switch:
843 file_copies_switch:
844 file_copies_switch--verbose:
844 file_copies_switch--verbose:
845 file_copies_switch--verbose:
845 file_copies_switch--verbose:
846 file_copies_switch--verbose:
846 file_copies_switch--verbose:
847 file_copies_switch--verbose:
847 file_copies_switch--verbose:
848 file_copies_switch--verbose:
848 file_copies_switch--verbose:
849 file_copies_switch--verbose:
849 file_copies_switch--verbose:
850 file_copies_switch--verbose:
850 file_copies_switch--verbose:
851 file_copies_switch--verbose:
851 file_copies_switch--verbose:
852 file_copies_switch--verbose:
852 file_copies_switch--verbose:
853 file_copies_switch--debug:
853 file_copies_switch--debug:
854 file_copies_switch--debug:
854 file_copies_switch--debug:
855 file_copies_switch--debug:
855 file_copies_switch--debug:
856 file_copies_switch--debug:
856 file_copies_switch--debug:
857 file_copies_switch--debug:
857 file_copies_switch--debug:
858 file_copies_switch--debug:
858 file_copies_switch--debug:
859 file_copies_switch--debug:
859 file_copies_switch--debug:
860 file_copies_switch--debug:
860 file_copies_switch--debug:
861 file_copies_switch--debug:
861 file_copies_switch--debug:
862 files: fourth second third
862 files: fourth second third
863 files: second
863 files: second
864 files:
864 files:
865 files: d
865 files: d
866 files:
866 files:
867 files: c
867 files: c
868 files: c
868 files: c
869 files: b
869 files: b
870 files: a
870 files: a
871 files--verbose: fourth second third
871 files--verbose: fourth second third
872 files--verbose: second
872 files--verbose: second
873 files--verbose:
873 files--verbose:
874 files--verbose: d
874 files--verbose: d
875 files--verbose:
875 files--verbose:
876 files--verbose: c
876 files--verbose: c
877 files--verbose: c
877 files--verbose: c
878 files--verbose: b
878 files--verbose: b
879 files--verbose: a
879 files--verbose: a
880 files--debug: fourth second third
880 files--debug: fourth second third
881 files--debug: second
881 files--debug: second
882 files--debug:
882 files--debug:
883 files--debug: d
883 files--debug: d
884 files--debug:
884 files--debug:
885 files--debug: c
885 files--debug: c
886 files--debug: c
886 files--debug: c
887 files--debug: b
887 files--debug: b
888 files--debug: a
888 files--debug: a
889 manifest: 8:94961b75a2da
889 manifest: 6:94961b75a2da
890 manifest: 7:f2dbc354b94e
890 manifest: 5:f2dbc354b94e
891 manifest: 6:91015e9dbdd7
891 manifest: 4:4dc3def4f9b4
892 manifest: 5:4dc3def4f9b4
892 manifest: 4:4dc3def4f9b4
893 manifest: 4:90ae8dda64e1
893 manifest: 3:cb5a1327723b
894 manifest: 3:cb5a1327723b
894 manifest: 3:cb5a1327723b
895 manifest: 2:6e0e82995c35
895 manifest: 2:6e0e82995c35
896 manifest: 1:4e8d705b1e53
896 manifest: 1:4e8d705b1e53
897 manifest: 0:a0c8bcbbb45c
897 manifest: 0:a0c8bcbbb45c
898 manifest--verbose: 8:94961b75a2da
898 manifest--verbose: 6:94961b75a2da
899 manifest--verbose: 7:f2dbc354b94e
899 manifest--verbose: 5:f2dbc354b94e
900 manifest--verbose: 6:91015e9dbdd7
900 manifest--verbose: 4:4dc3def4f9b4
901 manifest--verbose: 5:4dc3def4f9b4
901 manifest--verbose: 4:4dc3def4f9b4
902 manifest--verbose: 4:90ae8dda64e1
902 manifest--verbose: 3:cb5a1327723b
903 manifest--verbose: 3:cb5a1327723b
903 manifest--verbose: 3:cb5a1327723b
904 manifest--verbose: 2:6e0e82995c35
904 manifest--verbose: 2:6e0e82995c35
905 manifest--verbose: 1:4e8d705b1e53
905 manifest--verbose: 1:4e8d705b1e53
906 manifest--verbose: 0:a0c8bcbbb45c
906 manifest--verbose: 0:a0c8bcbbb45c
907 manifest--debug: 8:94961b75a2da554b4df6fb599e5bfc7d48de0c64
907 manifest--debug: 6:94961b75a2da554b4df6fb599e5bfc7d48de0c64
908 manifest--debug: 7:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
908 manifest--debug: 5:f2dbc354b94e5ec0b4f10680ee0cee816101d0bf
909 manifest--debug: 6:91015e9dbdd76a6791085d12b0a0ec7fcd22ffbf
909 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
910 manifest--debug: 5:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
910 manifest--debug: 4:4dc3def4f9b4c6e8de820f6ee74737f91e96a216
911 manifest--debug: 4:90ae8dda64e1a876c792bccb9af66284f6018363
911 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
912 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
912 manifest--debug: 3:cb5a1327723bada42f117e4c55a303246eaf9ccc
913 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
913 manifest--debug: 2:6e0e82995c35d0d57a52aca8da4e56139e06b4b1
914 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
914 manifest--debug: 1:4e8d705b1e53e3f9375e0e60dc7b525d8211fe55
915 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
915 manifest--debug: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
916 node: 95c24699272ef57d062b8bccc32c878bf841784a
916 node: 95c24699272ef57d062b8bccc32c878bf841784a
917 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
917 node: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
918 node: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
918 node: d41e714fe50d9e4a5f11b4d595d543481b5f980b
919 node: 13207e5a10d9fd28ec424934298e176197f2c67f
919 node: 13207e5a10d9fd28ec424934298e176197f2c67f
920 node: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
920 node: bbe44766e73d5f11ed2177f1838de10c53ef3e74
921 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
921 node: 10e46f2dcbf4823578cf180f33ecf0b957964c47
922 node: 97054abb4ab824450e9164180baf491ae0078465
922 node: 97054abb4ab824450e9164180baf491ae0078465
923 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
923 node: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
924 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
924 node: 1e4e1b8f71e05681d422154f5421e385fec3454f
925 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
925 node--verbose: 95c24699272ef57d062b8bccc32c878bf841784a
926 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
926 node--verbose: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
927 node--verbose: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
927 node--verbose: d41e714fe50d9e4a5f11b4d595d543481b5f980b
928 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
928 node--verbose: 13207e5a10d9fd28ec424934298e176197f2c67f
929 node--verbose: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
929 node--verbose: bbe44766e73d5f11ed2177f1838de10c53ef3e74
930 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
930 node--verbose: 10e46f2dcbf4823578cf180f33ecf0b957964c47
931 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
931 node--verbose: 97054abb4ab824450e9164180baf491ae0078465
932 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
932 node--verbose: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
933 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
933 node--verbose: 1e4e1b8f71e05681d422154f5421e385fec3454f
934 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
934 node--debug: 95c24699272ef57d062b8bccc32c878bf841784a
935 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
935 node--debug: 29114dbae42b9f078cf2714dbe3a86bba8ec7453
936 node--debug: c7b487c6c50ef1cf464cafdc4f4f5e615fc5999f
936 node--debug: d41e714fe50d9e4a5f11b4d595d543481b5f980b
937 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
937 node--debug: 13207e5a10d9fd28ec424934298e176197f2c67f
938 node--debug: 32a18f097fcccf76ef282f62f8a85b3adf8d13c4
938 node--debug: bbe44766e73d5f11ed2177f1838de10c53ef3e74
939 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
939 node--debug: 10e46f2dcbf4823578cf180f33ecf0b957964c47
940 node--debug: 97054abb4ab824450e9164180baf491ae0078465
940 node--debug: 97054abb4ab824450e9164180baf491ae0078465
941 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
941 node--debug: b608e9d1a3f0273ccf70fb85fd6866b3482bf965
942 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
942 node--debug: 1e4e1b8f71e05681d422154f5421e385fec3454f
943 parents:
943 parents:
944 parents: -1:000000000000
944 parents: -1:000000000000
945 parents: 5:13207e5a10d9 4:32a18f097fcc
945 parents: 5:13207e5a10d9 4:bbe44766e73d
946 parents: 3:10e46f2dcbf4
946 parents: 3:10e46f2dcbf4
947 parents:
947 parents:
948 parents:
948 parents:
949 parents:
949 parents:
950 parents:
950 parents:
951 parents:
951 parents:
952 parents--verbose:
952 parents--verbose:
953 parents--verbose: -1:000000000000
953 parents--verbose: -1:000000000000
954 parents--verbose: 5:13207e5a10d9 4:32a18f097fcc
954 parents--verbose: 5:13207e5a10d9 4:bbe44766e73d
955 parents--verbose: 3:10e46f2dcbf4
955 parents--verbose: 3:10e46f2dcbf4
956 parents--verbose:
956 parents--verbose:
957 parents--verbose:
957 parents--verbose:
958 parents--verbose:
958 parents--verbose:
959 parents--verbose:
959 parents--verbose:
960 parents--verbose:
960 parents--verbose:
961 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
961 parents--debug: 7:29114dbae42b9f078cf2714dbe3a86bba8ec7453 -1:0000000000000000000000000000000000000000
962 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
962 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
963 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:32a18f097fcccf76ef282f62f8a85b3adf8d13c4
963 parents--debug: 5:13207e5a10d9fd28ec424934298e176197f2c67f 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
964 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
964 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
965 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
965 parents--debug: 3:10e46f2dcbf4823578cf180f33ecf0b957964c47 -1:0000000000000000000000000000000000000000
966 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
966 parents--debug: 2:97054abb4ab824450e9164180baf491ae0078465 -1:0000000000000000000000000000000000000000
967 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
967 parents--debug: 1:b608e9d1a3f0273ccf70fb85fd6866b3482bf965 -1:0000000000000000000000000000000000000000
968 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
968 parents--debug: 0:1e4e1b8f71e05681d422154f5421e385fec3454f -1:0000000000000000000000000000000000000000
969 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
969 parents--debug: -1:0000000000000000000000000000000000000000 -1:0000000000000000000000000000000000000000
970 rev: 8
970 rev: 8
971 rev: 7
971 rev: 7
972 rev: 6
972 rev: 6
973 rev: 5
973 rev: 5
974 rev: 4
974 rev: 4
975 rev: 3
975 rev: 3
976 rev: 2
976 rev: 2
977 rev: 1
977 rev: 1
978 rev: 0
978 rev: 0
979 rev--verbose: 8
979 rev--verbose: 8
980 rev--verbose: 7
980 rev--verbose: 7
981 rev--verbose: 6
981 rev--verbose: 6
982 rev--verbose: 5
982 rev--verbose: 5
983 rev--verbose: 4
983 rev--verbose: 4
984 rev--verbose: 3
984 rev--verbose: 3
985 rev--verbose: 2
985 rev--verbose: 2
986 rev--verbose: 1
986 rev--verbose: 1
987 rev--verbose: 0
987 rev--verbose: 0
988 rev--debug: 8
988 rev--debug: 8
989 rev--debug: 7
989 rev--debug: 7
990 rev--debug: 6
990 rev--debug: 6
991 rev--debug: 5
991 rev--debug: 5
992 rev--debug: 4
992 rev--debug: 4
993 rev--debug: 3
993 rev--debug: 3
994 rev--debug: 2
994 rev--debug: 2
995 rev--debug: 1
995 rev--debug: 1
996 rev--debug: 0
996 rev--debug: 0
997 tags: tip
997 tags: tip
998 tags:
998 tags:
999 tags:
999 tags:
1000 tags:
1000 tags:
1001 tags:
1001 tags:
1002 tags:
1002 tags:
1003 tags:
1003 tags:
1004 tags:
1004 tags:
1005 tags:
1005 tags:
1006 tags--verbose: tip
1006 tags--verbose: tip
1007 tags--verbose:
1007 tags--verbose:
1008 tags--verbose:
1008 tags--verbose:
1009 tags--verbose:
1009 tags--verbose:
1010 tags--verbose:
1010 tags--verbose:
1011 tags--verbose:
1011 tags--verbose:
1012 tags--verbose:
1012 tags--verbose:
1013 tags--verbose:
1013 tags--verbose:
1014 tags--verbose:
1014 tags--verbose:
1015 tags--debug: tip
1015 tags--debug: tip
1016 tags--debug:
1016 tags--debug:
1017 tags--debug:
1017 tags--debug:
1018 tags--debug:
1018 tags--debug:
1019 tags--debug:
1019 tags--debug:
1020 tags--debug:
1020 tags--debug:
1021 tags--debug:
1021 tags--debug:
1022 tags--debug:
1022 tags--debug:
1023 tags--debug:
1023 tags--debug:
1024 diffstat: 3: +2/-1
1024 diffstat: 3: +2/-1
1025 diffstat: 1: +1/-0
1025 diffstat: 1: +1/-0
1026 diffstat: 0: +0/-0
1026 diffstat: 0: +0/-0
1027 diffstat: 1: +1/-0
1027 diffstat: 1: +1/-0
1028 diffstat: 0: +0/-0
1028 diffstat: 0: +0/-0
1029 diffstat: 1: +1/-0
1029 diffstat: 1: +1/-0
1030 diffstat: 1: +4/-0
1030 diffstat: 1: +4/-0
1031 diffstat: 1: +2/-0
1031 diffstat: 1: +2/-0
1032 diffstat: 1: +1/-0
1032 diffstat: 1: +1/-0
1033 diffstat--verbose: 3: +2/-1
1033 diffstat--verbose: 3: +2/-1
1034 diffstat--verbose: 1: +1/-0
1034 diffstat--verbose: 1: +1/-0
1035 diffstat--verbose: 0: +0/-0
1035 diffstat--verbose: 0: +0/-0
1036 diffstat--verbose: 1: +1/-0
1036 diffstat--verbose: 1: +1/-0
1037 diffstat--verbose: 0: +0/-0
1037 diffstat--verbose: 0: +0/-0
1038 diffstat--verbose: 1: +1/-0
1038 diffstat--verbose: 1: +1/-0
1039 diffstat--verbose: 1: +4/-0
1039 diffstat--verbose: 1: +4/-0
1040 diffstat--verbose: 1: +2/-0
1040 diffstat--verbose: 1: +2/-0
1041 diffstat--verbose: 1: +1/-0
1041 diffstat--verbose: 1: +1/-0
1042 diffstat--debug: 3: +2/-1
1042 diffstat--debug: 3: +2/-1
1043 diffstat--debug: 1: +1/-0
1043 diffstat--debug: 1: +1/-0
1044 diffstat--debug: 0: +0/-0
1044 diffstat--debug: 0: +0/-0
1045 diffstat--debug: 1: +1/-0
1045 diffstat--debug: 1: +1/-0
1046 diffstat--debug: 0: +0/-0
1046 diffstat--debug: 0: +0/-0
1047 diffstat--debug: 1: +1/-0
1047 diffstat--debug: 1: +1/-0
1048 diffstat--debug: 1: +4/-0
1048 diffstat--debug: 1: +4/-0
1049 diffstat--debug: 1: +2/-0
1049 diffstat--debug: 1: +2/-0
1050 diffstat--debug: 1: +1/-0
1050 diffstat--debug: 1: +1/-0
1051 extras: branch=default
1051 extras: branch=default
1052 extras: branch=default
1052 extras: branch=default
1053 extras: branch=default
1053 extras: branch=default
1054 extras: branch=default
1054 extras: branch=default
1055 extras: branch=foo
1055 extras: branch=foo
1056 extras: branch=default
1056 extras: branch=default
1057 extras: branch=default
1057 extras: branch=default
1058 extras: branch=default
1058 extras: branch=default
1059 extras: branch=default
1059 extras: branch=default
1060 extras--verbose: branch=default
1060 extras--verbose: branch=default
1061 extras--verbose: branch=default
1061 extras--verbose: branch=default
1062 extras--verbose: branch=default
1062 extras--verbose: branch=default
1063 extras--verbose: branch=default
1063 extras--verbose: branch=default
1064 extras--verbose: branch=foo
1064 extras--verbose: branch=foo
1065 extras--verbose: branch=default
1065 extras--verbose: branch=default
1066 extras--verbose: branch=default
1066 extras--verbose: branch=default
1067 extras--verbose: branch=default
1067 extras--verbose: branch=default
1068 extras--verbose: branch=default
1068 extras--verbose: branch=default
1069 extras--debug: branch=default
1069 extras--debug: branch=default
1070 extras--debug: branch=default
1070 extras--debug: branch=default
1071 extras--debug: branch=default
1071 extras--debug: branch=default
1072 extras--debug: branch=default
1072 extras--debug: branch=default
1073 extras--debug: branch=foo
1073 extras--debug: branch=foo
1074 extras--debug: branch=default
1074 extras--debug: branch=default
1075 extras--debug: branch=default
1075 extras--debug: branch=default
1076 extras--debug: branch=default
1076 extras--debug: branch=default
1077 extras--debug: branch=default
1077 extras--debug: branch=default
1078
1078
1079
1079
1080 Filters work:
1080 Filters work:
1081
1081
1082 $ hg log --template '{author|domain}\n'
1082 $ hg log --template '{author|domain}\n'
1083
1083
1084 hostname
1084 hostname
1085
1085
1086
1086
1087
1087
1088
1088
1089 place
1089 place
1090 place
1090 place
1091 hostname
1091 hostname
1092
1092
1093 $ hg log --template '{author|person}\n'
1093 $ hg log --template '{author|person}\n'
1094 test
1094 test
1095 User Name
1095 User Name
1096 person
1096 person
1097 person
1097 person
1098 person
1098 person
1099 person
1099 person
1100 other
1100 other
1101 A. N. Other
1101 A. N. Other
1102 User Name
1102 User Name
1103
1103
1104 $ hg log --template '{author|user}\n'
1104 $ hg log --template '{author|user}\n'
1105 test
1105 test
1106 user
1106 user
1107 person
1107 person
1108 person
1108 person
1109 person
1109 person
1110 person
1110 person
1111 other
1111 other
1112 other
1112 other
1113 user
1113 user
1114
1114
1115 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1115 $ hg log --template '{date|age}\n' > /dev/null || exit 1
1116
1116
1117 $ hg log -l1 --template '{date|age}\n'
1117 $ hg log -l1 --template '{date|age}\n'
1118 8 years from now
1118 8 years from now
1119 $ hg log --template '{date|date}\n'
1119 $ hg log --template '{date|date}\n'
1120 Wed Jan 01 10:01:00 2020 +0000
1120 Wed Jan 01 10:01:00 2020 +0000
1121 Mon Jan 12 13:46:40 1970 +0000
1121 Mon Jan 12 13:46:40 1970 +0000
1122 Sun Jan 18 08:40:01 1970 +0000
1122 Sun Jan 18 08:40:01 1970 +0000
1123 Sun Jan 18 08:40:00 1970 +0000
1123 Sun Jan 18 08:40:00 1970 +0000
1124 Sat Jan 17 04:53:20 1970 +0000
1124 Sat Jan 17 04:53:20 1970 +0000
1125 Fri Jan 16 01:06:40 1970 +0000
1125 Fri Jan 16 01:06:40 1970 +0000
1126 Wed Jan 14 21:20:00 1970 +0000
1126 Wed Jan 14 21:20:00 1970 +0000
1127 Tue Jan 13 17:33:20 1970 +0000
1127 Tue Jan 13 17:33:20 1970 +0000
1128 Mon Jan 12 13:46:40 1970 +0000
1128 Mon Jan 12 13:46:40 1970 +0000
1129
1129
1130 $ hg log --template '{date|isodate}\n'
1130 $ hg log --template '{date|isodate}\n'
1131 2020-01-01 10:01 +0000
1131 2020-01-01 10:01 +0000
1132 1970-01-12 13:46 +0000
1132 1970-01-12 13:46 +0000
1133 1970-01-18 08:40 +0000
1133 1970-01-18 08:40 +0000
1134 1970-01-18 08:40 +0000
1134 1970-01-18 08:40 +0000
1135 1970-01-17 04:53 +0000
1135 1970-01-17 04:53 +0000
1136 1970-01-16 01:06 +0000
1136 1970-01-16 01:06 +0000
1137 1970-01-14 21:20 +0000
1137 1970-01-14 21:20 +0000
1138 1970-01-13 17:33 +0000
1138 1970-01-13 17:33 +0000
1139 1970-01-12 13:46 +0000
1139 1970-01-12 13:46 +0000
1140
1140
1141 $ hg log --template '{date|isodatesec}\n'
1141 $ hg log --template '{date|isodatesec}\n'
1142 2020-01-01 10:01:00 +0000
1142 2020-01-01 10:01:00 +0000
1143 1970-01-12 13:46:40 +0000
1143 1970-01-12 13:46:40 +0000
1144 1970-01-18 08:40:01 +0000
1144 1970-01-18 08:40:01 +0000
1145 1970-01-18 08:40:00 +0000
1145 1970-01-18 08:40:00 +0000
1146 1970-01-17 04:53:20 +0000
1146 1970-01-17 04:53:20 +0000
1147 1970-01-16 01:06:40 +0000
1147 1970-01-16 01:06:40 +0000
1148 1970-01-14 21:20:00 +0000
1148 1970-01-14 21:20:00 +0000
1149 1970-01-13 17:33:20 +0000
1149 1970-01-13 17:33:20 +0000
1150 1970-01-12 13:46:40 +0000
1150 1970-01-12 13:46:40 +0000
1151
1151
1152 $ hg log --template '{date|rfc822date}\n'
1152 $ hg log --template '{date|rfc822date}\n'
1153 Wed, 01 Jan 2020 10:01:00 +0000
1153 Wed, 01 Jan 2020 10:01:00 +0000
1154 Mon, 12 Jan 1970 13:46:40 +0000
1154 Mon, 12 Jan 1970 13:46:40 +0000
1155 Sun, 18 Jan 1970 08:40:01 +0000
1155 Sun, 18 Jan 1970 08:40:01 +0000
1156 Sun, 18 Jan 1970 08:40:00 +0000
1156 Sun, 18 Jan 1970 08:40:00 +0000
1157 Sat, 17 Jan 1970 04:53:20 +0000
1157 Sat, 17 Jan 1970 04:53:20 +0000
1158 Fri, 16 Jan 1970 01:06:40 +0000
1158 Fri, 16 Jan 1970 01:06:40 +0000
1159 Wed, 14 Jan 1970 21:20:00 +0000
1159 Wed, 14 Jan 1970 21:20:00 +0000
1160 Tue, 13 Jan 1970 17:33:20 +0000
1160 Tue, 13 Jan 1970 17:33:20 +0000
1161 Mon, 12 Jan 1970 13:46:40 +0000
1161 Mon, 12 Jan 1970 13:46:40 +0000
1162
1162
1163 $ hg log --template '{desc|firstline}\n'
1163 $ hg log --template '{desc|firstline}\n'
1164 third
1164 third
1165 second
1165 second
1166 merge
1166 merge
1167 new head
1167 new head
1168 new branch
1168 new branch
1169 no user, no domain
1169 no user, no domain
1170 no person
1170 no person
1171 other 1
1171 other 1
1172 line 1
1172 line 1
1173
1173
1174 $ hg log --template '{node|short}\n'
1174 $ hg log --template '{node|short}\n'
1175 95c24699272e
1175 95c24699272e
1176 29114dbae42b
1176 29114dbae42b
1177 c7b487c6c50e
1177 d41e714fe50d
1178 13207e5a10d9
1178 13207e5a10d9
1179 32a18f097fcc
1179 bbe44766e73d
1180 10e46f2dcbf4
1180 10e46f2dcbf4
1181 97054abb4ab8
1181 97054abb4ab8
1182 b608e9d1a3f0
1182 b608e9d1a3f0
1183 1e4e1b8f71e0
1183 1e4e1b8f71e0
1184
1184
1185 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1185 $ hg log --template '<changeset author="{author|xmlescape}"/>\n'
1186 <changeset author="test"/>
1186 <changeset author="test"/>
1187 <changeset author="User Name &lt;user@hostname&gt;"/>
1187 <changeset author="User Name &lt;user@hostname&gt;"/>
1188 <changeset author="person"/>
1188 <changeset author="person"/>
1189 <changeset author="person"/>
1189 <changeset author="person"/>
1190 <changeset author="person"/>
1190 <changeset author="person"/>
1191 <changeset author="person"/>
1191 <changeset author="person"/>
1192 <changeset author="other@place"/>
1192 <changeset author="other@place"/>
1193 <changeset author="A. N. Other &lt;other@place&gt;"/>
1193 <changeset author="A. N. Other &lt;other@place&gt;"/>
1194 <changeset author="User Name &lt;user@hostname&gt;"/>
1194 <changeset author="User Name &lt;user@hostname&gt;"/>
1195
1195
1196 $ hg log --template '{rev}: {children}\n'
1196 $ hg log --template '{rev}: {children}\n'
1197 8:
1197 8:
1198 7: 8:95c24699272e
1198 7: 8:95c24699272e
1199 6:
1199 6:
1200 5: 6:c7b487c6c50e
1200 5: 6:d41e714fe50d
1201 4: 6:c7b487c6c50e
1201 4: 6:d41e714fe50d
1202 3: 4:32a18f097fcc 5:13207e5a10d9
1202 3: 4:bbe44766e73d 5:13207e5a10d9
1203 2: 3:10e46f2dcbf4
1203 2: 3:10e46f2dcbf4
1204 1: 2:97054abb4ab8
1204 1: 2:97054abb4ab8
1205 0: 1:b608e9d1a3f0
1205 0: 1:b608e9d1a3f0
1206
1206
1207 Formatnode filter works:
1207 Formatnode filter works:
1208
1208
1209 $ hg -q log -r 0 --template '{node|formatnode}\n'
1209 $ hg -q log -r 0 --template '{node|formatnode}\n'
1210 1e4e1b8f71e0
1210 1e4e1b8f71e0
1211
1211
1212 $ hg log -r 0 --template '{node|formatnode}\n'
1212 $ hg log -r 0 --template '{node|formatnode}\n'
1213 1e4e1b8f71e0
1213 1e4e1b8f71e0
1214
1214
1215 $ hg -v log -r 0 --template '{node|formatnode}\n'
1215 $ hg -v log -r 0 --template '{node|formatnode}\n'
1216 1e4e1b8f71e0
1216 1e4e1b8f71e0
1217
1217
1218 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1218 $ hg --debug log -r 0 --template '{node|formatnode}\n'
1219 1e4e1b8f71e05681d422154f5421e385fec3454f
1219 1e4e1b8f71e05681d422154f5421e385fec3454f
1220
1220
1221 Error on syntax:
1221 Error on syntax:
1222
1222
1223 $ echo 'x = "f' >> t
1223 $ echo 'x = "f' >> t
1224 $ hg log
1224 $ hg log
1225 abort: t:3: unmatched quotes
1225 abort: t:3: unmatched quotes
1226 [255]
1226 [255]
1227
1227
1228 $ cd ..
1228 $ cd ..
1229
1229
1230
1230
1231 latesttag:
1231 latesttag:
1232
1232
1233 $ hg init latesttag
1233 $ hg init latesttag
1234 $ cd latesttag
1234 $ cd latesttag
1235
1235
1236 $ echo a > file
1236 $ echo a > file
1237 $ hg ci -Am a -d '0 0'
1237 $ hg ci -Am a -d '0 0'
1238 adding file
1238 adding file
1239
1239
1240 $ echo b >> file
1240 $ echo b >> file
1241 $ hg ci -m b -d '1 0'
1241 $ hg ci -m b -d '1 0'
1242
1242
1243 $ echo c >> head1
1243 $ echo c >> head1
1244 $ hg ci -Am h1c -d '2 0'
1244 $ hg ci -Am h1c -d '2 0'
1245 adding head1
1245 adding head1
1246
1246
1247 $ hg update -q 1
1247 $ hg update -q 1
1248 $ echo d >> head2
1248 $ echo d >> head2
1249 $ hg ci -Am h2d -d '3 0'
1249 $ hg ci -Am h2d -d '3 0'
1250 adding head2
1250 adding head2
1251 created new head
1251 created new head
1252
1252
1253 $ echo e >> head2
1253 $ echo e >> head2
1254 $ hg ci -m h2e -d '4 0'
1254 $ hg ci -m h2e -d '4 0'
1255
1255
1256 $ hg merge -q
1256 $ hg merge -q
1257 $ hg ci -m merge -d '5 0'
1257 $ hg ci -m merge -d '5 0'
1258
1258
1259 No tag set:
1259 No tag set:
1260
1260
1261 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1261 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1262 5: null+5
1262 5: null+5
1263 4: null+4
1263 4: null+4
1264 3: null+3
1264 3: null+3
1265 2: null+3
1265 2: null+3
1266 1: null+2
1266 1: null+2
1267 0: null+1
1267 0: null+1
1268
1268
1269 One common tag: longuest path wins:
1269 One common tag: longuest path wins:
1270
1270
1271 $ hg tag -r 1 -m t1 -d '6 0' t1
1271 $ hg tag -r 1 -m t1 -d '6 0' t1
1272 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1272 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1273 6: t1+4
1273 6: t1+4
1274 5: t1+3
1274 5: t1+3
1275 4: t1+2
1275 4: t1+2
1276 3: t1+1
1276 3: t1+1
1277 2: t1+1
1277 2: t1+1
1278 1: t1+0
1278 1: t1+0
1279 0: null+1
1279 0: null+1
1280
1280
1281 One ancestor tag: more recent wins:
1281 One ancestor tag: more recent wins:
1282
1282
1283 $ hg tag -r 2 -m t2 -d '7 0' t2
1283 $ hg tag -r 2 -m t2 -d '7 0' t2
1284 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1284 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1285 7: t2+3
1285 7: t2+3
1286 6: t2+2
1286 6: t2+2
1287 5: t2+1
1287 5: t2+1
1288 4: t1+2
1288 4: t1+2
1289 3: t1+1
1289 3: t1+1
1290 2: t2+0
1290 2: t2+0
1291 1: t1+0
1291 1: t1+0
1292 0: null+1
1292 0: null+1
1293
1293
1294 Two branch tags: more recent wins:
1294 Two branch tags: more recent wins:
1295
1295
1296 $ hg tag -r 3 -m t3 -d '8 0' t3
1296 $ hg tag -r 3 -m t3 -d '8 0' t3
1297 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1297 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1298 8: t3+5
1298 8: t3+5
1299 7: t3+4
1299 7: t3+4
1300 6: t3+3
1300 6: t3+3
1301 5: t3+2
1301 5: t3+2
1302 4: t3+1
1302 4: t3+1
1303 3: t3+0
1303 3: t3+0
1304 2: t2+0
1304 2: t2+0
1305 1: t1+0
1305 1: t1+0
1306 0: null+1
1306 0: null+1
1307
1307
1308 Merged tag overrides:
1308 Merged tag overrides:
1309
1309
1310 $ hg tag -r 5 -m t5 -d '9 0' t5
1310 $ hg tag -r 5 -m t5 -d '9 0' t5
1311 $ hg tag -r 3 -m at3 -d '10 0' at3
1311 $ hg tag -r 3 -m at3 -d '10 0' at3
1312 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1312 $ hg log --template '{rev}: {latesttag}+{latesttagdistance}\n'
1313 10: t5+5
1313 10: t5+5
1314 9: t5+4
1314 9: t5+4
1315 8: t5+3
1315 8: t5+3
1316 7: t5+2
1316 7: t5+2
1317 6: t5+1
1317 6: t5+1
1318 5: t5+0
1318 5: t5+0
1319 4: at3:t3+1
1319 4: at3:t3+1
1320 3: at3:t3+0
1320 3: at3:t3+0
1321 2: t2+0
1321 2: t2+0
1322 1: t1+0
1322 1: t1+0
1323 0: null+1
1323 0: null+1
1324
1324
1325 $ cd ..
1325 $ cd ..
1326
1326
1327
1327
1328 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1328 Style path expansion: issue1948 - ui.style option doesn't work on OSX
1329 if it is a relative path
1329 if it is a relative path
1330
1330
1331 $ mkdir -p home/styles
1331 $ mkdir -p home/styles
1332
1332
1333 $ cat > home/styles/teststyle <<EOF
1333 $ cat > home/styles/teststyle <<EOF
1334 > changeset = 'test {rev}:{node|short}\n'
1334 > changeset = 'test {rev}:{node|short}\n'
1335 > EOF
1335 > EOF
1336
1336
1337 $ HOME=`pwd`/home; export HOME
1337 $ HOME=`pwd`/home; export HOME
1338
1338
1339 $ cat > latesttag/.hg/hgrc <<EOF
1339 $ cat > latesttag/.hg/hgrc <<EOF
1340 > [ui]
1340 > [ui]
1341 > style = ~/styles/teststyle
1341 > style = ~/styles/teststyle
1342 > EOF
1342 > EOF
1343
1343
1344 $ hg -R latesttag tip
1344 $ hg -R latesttag tip
1345 test 10:dee8f28249af
1345 test 10:dee8f28249af
1346
1346
1347 Test recursive showlist template (issue1989):
1347 Test recursive showlist template (issue1989):
1348
1348
1349 $ cat > style1989 <<EOF
1349 $ cat > style1989 <<EOF
1350 > changeset = '{file_mods}{manifest}{extras}'
1350 > changeset = '{file_mods}{manifest}{extras}'
1351 > file_mod = 'M|{author|person}\n'
1351 > file_mod = 'M|{author|person}\n'
1352 > manifest = '{rev},{author}\n'
1352 > manifest = '{rev},{author}\n'
1353 > extra = '{key}: {author}\n'
1353 > extra = '{key}: {author}\n'
1354 > EOF
1354 > EOF
1355
1355
1356 $ hg -R latesttag log -r tip --style=style1989
1356 $ hg -R latesttag log -r tip --style=style1989
1357 M|test
1357 M|test
1358 10,test
1358 10,test
1359 branch: test
1359 branch: test
1360
1360
@@ -1,101 +1,101
1
1
2 $ "$TESTDIR/hghave" svn svn-bindings || exit 80
2 $ "$TESTDIR/hghave" svn svn-bindings || exit 80
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > convert =
6 > convert =
7 > graphlog =
7 > graphlog =
8 > EOF
8 > EOF
9
9
10 $ svnadmin create svn-repo
10 $ svnadmin create svn-repo
11 $ svnadmin load -q svn-repo < "$TESTDIR/svn/branches.svndump"
11 $ svnadmin load -q svn-repo < "$TESTDIR/svn/branches.svndump"
12
12
13 Convert trunk and branches
13 Convert trunk and branches
14
14
15 $ cat > branchmap <<EOF
15 $ cat > branchmap <<EOF
16 > old3 newbranch
16 > old3 newbranch
17 > EOF
17 > EOF
18 $ hg convert --branchmap=branchmap --datesort -r 10 svn-repo A-hg
18 $ hg convert --branchmap=branchmap --datesort -r 10 svn-repo A-hg
19 initializing destination A-hg repository
19 initializing destination A-hg repository
20 scanning source...
20 scanning source...
21 sorting...
21 sorting...
22 converting...
22 converting...
23 10 init projA
23 10 init projA
24 9 hello
24 9 hello
25 8 branch trunk, remove c and dir
25 8 branch trunk, remove c and dir
26 7 change a
26 7 change a
27 6 change b
27 6 change b
28 5 move and update c
28 5 move and update c
29 4 move and update c
29 4 move and update c
30 3 change b again
30 3 change b again
31 2 move to old2
31 2 move to old2
32 1 move back to old
32 1 move back to old
33 0 last change to a
33 0 last change to a
34
34
35 Test template keywords
35 Test template keywords
36
36
37 $ hg -R A-hg log --template '{rev} {svnuuid}{svnpath}@{svnrev}\n'
37 $ hg -R A-hg log --template '{rev} {svnuuid}{svnpath}@{svnrev}\n'
38 10 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@10
38 10 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@10
39 9 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@9
39 9 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@9
40 8 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old2@8
40 8 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old2@8
41 7 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@7
41 7 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@7
42 6 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@6
42 6 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@6
43 5 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@6
43 5 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@6
44 4 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@5
44 4 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@5
45 3 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@4
45 3 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@4
46 2 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@3
46 2 644ede6c-2b81-4367-9dc8-d786514f2cde/branches/old@3
47 1 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@2
47 1 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@2
48 0 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@1
48 0 644ede6c-2b81-4367-9dc8-d786514f2cde/trunk@1
49
49
50 Convert again
50 Convert again
51
51
52 $ hg convert --branchmap=branchmap --datesort svn-repo A-hg
52 $ hg convert --branchmap=branchmap --datesort svn-repo A-hg
53 scanning source...
53 scanning source...
54 sorting...
54 sorting...
55 converting...
55 converting...
56 0 branch trunk@1 into old3
56 0 branch trunk@1 into old3
57
57
58 $ cd A-hg
58 $ cd A-hg
59 $ hg glog --template 'branch={branches} {rev} {desc|firstline} files: {files}\n'
59 $ hg glog --template 'branch={branches} {rev} {desc|firstline} files: {files}\n'
60 o branch=newbranch 11 branch trunk@1 into old3 files:
60 o branch=newbranch 11 branch trunk@1 into old3 files:
61 |
61 |
62 | o branch= 10 last change to a files: a
62 | o branch= 10 last change to a files: a
63 | |
63 | |
64 | | o branch=old 9 move back to old files:
64 | | o branch=old 9 move back to old files:
65 | | |
65 | | |
66 | | o branch=old2 8 move to old2 files:
66 | | o branch=old2 8 move to old2 files:
67 | | |
67 | | |
68 | | o branch=old 7 change b again files: b
68 | | o branch=old 7 change b again files: b
69 | | |
69 | | |
70 | o | branch= 6 move and update c files: b
70 | o | branch= 6 move and update c files: b
71 | | |
71 | | |
72 | | o branch=old 5 move and update c files: c
72 | | o branch=old 5 move and update c files: c
73 | | |
73 | | |
74 | | o branch=old 4 change b files: b
74 | | o branch=old 4 change b files: b
75 | | |
75 | | |
76 | o | branch= 3 change a files: a
76 | o | branch= 3 change a files: a
77 | | |
77 | | |
78 | | o branch=old 2 branch trunk, remove c and dir files: c
78 | | o branch=old 2 branch trunk, remove c and dir files: c
79 | |/
79 | |/
80 | o branch= 1 hello files: a b c dir/e
80 | o branch= 1 hello files: a b c dir/e
81 |/
81 |/
82 o branch= 0 init projA files:
82 o branch= 0 init projA files:
83
83
84
84
85 $ hg branches
85 $ hg branches
86 newbranch 11:08fca3ff8634
86 newbranch 11:a6d7cc050ad1
87 default 10:098988aa63ba
87 default 10:6e2b33404495
88 old 9:b308f345079b
88 old 9:93c4b0f99529
89 old2 8:49f2336c7b8b (inactive)
89 old2 8:b52884d7bead (inactive)
90 $ hg tags -q
90 $ hg tags -q
91 tip
91 tip
92 $ cd ..
92 $ cd ..
93
93
94 Test hg failing to call itself
94 Test hg failing to call itself
95
95
96 $ HG=foobar hg convert svn-repo B-hg
96 $ HG=foobar hg convert svn-repo B-hg
97 * (glob)
97 * (glob)
98 initializing destination B-hg repository
98 initializing destination B-hg repository
99 abort: Mercurial failed to run itself, check hg executable is in PATH
99 abort: Mercurial failed to run itself, check hg executable is in PATH
100 [255]
100 [255]
101
101
@@ -1,135 +1,135
1
1
2 $ "$TESTDIR/hghave" svn svn-bindings || exit 80
2 $ "$TESTDIR/hghave" svn svn-bindings || exit 80
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > convert =
6 > convert =
7 > graphlog =
7 > graphlog =
8 > EOF
8 > EOF
9
9
10 $ svnadmin create svn-repo
10 $ svnadmin create svn-repo
11 $ svnadmin load -q svn-repo < "$TESTDIR/svn/encoding.svndump"
11 $ svnadmin load -q svn-repo < "$TESTDIR/svn/encoding.svndump"
12
12
13 Convert while testing all possible outputs
13 Convert while testing all possible outputs
14
14
15 $ hg --debug convert svn-repo A-hg
15 $ hg --debug convert svn-repo A-hg
16 initializing destination A-hg repository
16 initializing destination A-hg repository
17 reparent to file://*/svn-repo (glob)
17 reparent to file://*/svn-repo (glob)
18 run hg sink pre-conversion action
18 run hg sink pre-conversion action
19 scanning source...
19 scanning source...
20 found trunk at 'trunk'
20 found trunk at 'trunk'
21 found tags at 'tags'
21 found tags at 'tags'
22 found branches at 'branches'
22 found branches at 'branches'
23 found branch branch\xc3\xa9 at 5 (esc)
23 found branch branch\xc3\xa9 at 5 (esc)
24 found branch branch\xc3\xa9e at 6 (esc)
24 found branch branch\xc3\xa9e at 6 (esc)
25 scanning: 1 revisions
25 scanning: 1 revisions
26 reparent to file://*/svn-repo/trunk (glob)
26 reparent to file://*/svn-repo/trunk (glob)
27 fetching revision log for "/trunk" from 4 to 0
27 fetching revision log for "/trunk" from 4 to 0
28 parsing revision 4 (2 changes)
28 parsing revision 4 (2 changes)
29 parsing revision 3 (4 changes)
29 parsing revision 3 (4 changes)
30 parsing revision 2 (3 changes)
30 parsing revision 2 (3 changes)
31 parsing revision 1 (3 changes)
31 parsing revision 1 (3 changes)
32 no copyfrom path, don't know what to do.
32 no copyfrom path, don't know what to do.
33 '/branches' is not under '/trunk', ignoring
33 '/branches' is not under '/trunk', ignoring
34 '/tags' is not under '/trunk', ignoring
34 '/tags' is not under '/trunk', ignoring
35 scanning: 2 revisions
35 scanning: 2 revisions
36 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
36 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
37 fetching revision log for "/branches/branch\xc3\xa9" from 5 to 0 (esc)
37 fetching revision log for "/branches/branch\xc3\xa9" from 5 to 0 (esc)
38 parsing revision 5 (1 changes)
38 parsing revision 5 (1 changes)
39 reparent to file://*/svn-repo (glob)
39 reparent to file://*/svn-repo (glob)
40 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
40 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
41 found parent of branch /branches/branch\xc3\xa9 at 4: /trunk (esc)
41 found parent of branch /branches/branch\xc3\xa9 at 4: /trunk (esc)
42 scanning: 3 revisions
42 scanning: 3 revisions
43 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
43 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
44 fetching revision log for "/branches/branch\xc3\xa9e" from 6 to 0 (esc)
44 fetching revision log for "/branches/branch\xc3\xa9e" from 6 to 0 (esc)
45 parsing revision 6 (1 changes)
45 parsing revision 6 (1 changes)
46 reparent to file://*/svn-repo (glob)
46 reparent to file://*/svn-repo (glob)
47 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
47 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
48 found parent of branch /branches/branch\xc3\xa9e at 5: /branches/branch\xc3\xa9 (esc)
48 found parent of branch /branches/branch\xc3\xa9e at 5: /branches/branch\xc3\xa9 (esc)
49 scanning: 4 revisions
49 scanning: 4 revisions
50 scanning: 5 revisions
50 scanning: 5 revisions
51 scanning: 6 revisions
51 scanning: 6 revisions
52 sorting...
52 sorting...
53 converting...
53 converting...
54 5 init projA
54 5 init projA
55 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@1
55 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@1
56 converting: 0/6 revisions (0.00%)
56 converting: 0/6 revisions (0.00%)
57 4 hello
57 4 hello
58 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@2
58 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@2
59 converting: 1/6 revisions (16.67%)
59 converting: 1/6 revisions (16.67%)
60 reparent to file://*/svn-repo/trunk (glob)
60 reparent to file://*/svn-repo/trunk (glob)
61 scanning paths: /trunk/\xc3\xa0 0/3 (0.00%) (esc)
61 scanning paths: /trunk/\xc3\xa0 0/3 (0.00%) (esc)
62 scanning paths: /trunk/\xc3\xa0/e\xcc\x81 1/3 (33.33%) (esc)
62 scanning paths: /trunk/\xc3\xa0/e\xcc\x81 1/3 (33.33%) (esc)
63 scanning paths: /trunk/\xc3\xa9 2/3 (66.67%) (esc)
63 scanning paths: /trunk/\xc3\xa9 2/3 (66.67%) (esc)
64 \xc3\xa0/e\xcc\x81 (esc)
64 \xc3\xa0/e\xcc\x81 (esc)
65 getting files: \xc3\xa0/e\xcc\x81 1/2 (50.00%) (esc)
65 getting files: \xc3\xa0/e\xcc\x81 1/2 (50.00%) (esc)
66 \xc3\xa9 (esc)
66 \xc3\xa9 (esc)
67 getting files: \xc3\xa9 2/2 (100.00%) (esc)
67 getting files: \xc3\xa9 2/2 (100.00%) (esc)
68 3 copy files
68 3 copy files
69 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@3
69 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@3
70 converting: 2/6 revisions (33.33%)
70 converting: 2/6 revisions (33.33%)
71 scanning paths: /trunk/\xc3\xa0 0/4 (0.00%) (esc)
71 scanning paths: /trunk/\xc3\xa0 0/4 (0.00%) (esc)
72 gone from -1
72 gone from -1
73 reparent to file://*/svn-repo (glob)
73 reparent to file://*/svn-repo (glob)
74 reparent to file://*/svn-repo/trunk (glob)
74 reparent to file://*/svn-repo/trunk (glob)
75 scanning paths: /trunk/\xc3\xa8 1/4 (25.00%) (esc)
75 scanning paths: /trunk/\xc3\xa8 1/4 (25.00%) (esc)
76 copied to \xc3\xa8 from \xc3\xa9@2 (esc)
76 copied to \xc3\xa8 from \xc3\xa9@2 (esc)
77 scanning paths: /trunk/\xc3\xa9 2/4 (50.00%) (esc)
77 scanning paths: /trunk/\xc3\xa9 2/4 (50.00%) (esc)
78 gone from -1
78 gone from -1
79 reparent to file://*/svn-repo (glob)
79 reparent to file://*/svn-repo (glob)
80 reparent to file://*/svn-repo/trunk (glob)
80 reparent to file://*/svn-repo/trunk (glob)
81 scanning paths: /trunk/\xc3\xb9 3/4 (75.00%) (esc)
81 scanning paths: /trunk/\xc3\xb9 3/4 (75.00%) (esc)
82 mark /trunk/\xc3\xb9 came from \xc3\xa0:2 (esc)
82 mark /trunk/\xc3\xb9 came from \xc3\xa0:2 (esc)
83 \xc3\xa0/e\xcc\x81 (esc)
83 \xc3\xa0/e\xcc\x81 (esc)
84 getting files: \xc3\xa0/e\xcc\x81 1/4 (25.00%) (esc)
84 getting files: \xc3\xa0/e\xcc\x81 1/4 (25.00%) (esc)
85 \xc3\xa8 (esc)
85 \xc3\xa8 (esc)
86 getting files: \xc3\xa8 2/4 (50.00%) (esc)
86 getting files: \xc3\xa8 2/4 (50.00%) (esc)
87 \xc3\xa8: copy \xc3\xa9:6b67ccefd5ce6de77e7ead4f5292843a0255329f (esc)
87 \xc3\xa8: copy \xc3\xa9:6b67ccefd5ce6de77e7ead4f5292843a0255329f (esc)
88 \xc3\xa9 (esc)
88 \xc3\xa9 (esc)
89 getting files: \xc3\xa9 3/4 (75.00%) (esc)
89 getting files: \xc3\xa9 3/4 (75.00%) (esc)
90 \xc3\xb9/e\xcc\x81 (esc)
90 \xc3\xb9/e\xcc\x81 (esc)
91 getting files: \xc3\xb9/e\xcc\x81 4/4 (100.00%) (esc)
91 getting files: \xc3\xb9/e\xcc\x81 4/4 (100.00%) (esc)
92 \xc3\xb9/e\xcc\x81: copy \xc3\xa0/e\xcc\x81:a9092a3d84a37b9993b5c73576f6de29b7ea50f6 (esc)
92 \xc3\xb9/e\xcc\x81: copy \xc3\xa0/e\xcc\x81:a9092a3d84a37b9993b5c73576f6de29b7ea50f6 (esc)
93 2 remove files
93 2 remove files
94 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@4
94 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/trunk@4
95 converting: 3/6 revisions (50.00%)
95 converting: 3/6 revisions (50.00%)
96 scanning paths: /trunk/\xc3\xa8 0/2 (0.00%) (esc)
96 scanning paths: /trunk/\xc3\xa8 0/2 (0.00%) (esc)
97 gone from -1
97 gone from -1
98 reparent to file://*/svn-repo (glob)
98 reparent to file://*/svn-repo (glob)
99 reparent to file://*/svn-repo/trunk (glob)
99 reparent to file://*/svn-repo/trunk (glob)
100 scanning paths: /trunk/\xc3\xb9 1/2 (50.00%) (esc)
100 scanning paths: /trunk/\xc3\xb9 1/2 (50.00%) (esc)
101 gone from -1
101 gone from -1
102 reparent to file://*/svn-repo (glob)
102 reparent to file://*/svn-repo (glob)
103 reparent to file://*/svn-repo/trunk (glob)
103 reparent to file://*/svn-repo/trunk (glob)
104 \xc3\xa8 (esc)
104 \xc3\xa8 (esc)
105 getting files: \xc3\xa8 1/2 (50.00%) (esc)
105 getting files: \xc3\xa8 1/2 (50.00%) (esc)
106 \xc3\xb9/e\xcc\x81 (esc)
106 \xc3\xb9/e\xcc\x81 (esc)
107 getting files: \xc3\xb9/e\xcc\x81 2/2 (100.00%) (esc)
107 getting files: \xc3\xb9/e\xcc\x81 2/2 (100.00%) (esc)
108 1 branch to branch?
108 1 branch to branch?
109 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/branches/branch?@5
109 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/branches/branch?@5
110 converting: 4/6 revisions (66.67%)
110 converting: 4/6 revisions (66.67%)
111 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
111 reparent to file://*/svn-repo/branches/branch%C3%A9 (glob)
112 scanning paths: /branches/branch\xc3\xa9 0/1 (0.00%) (esc)
112 scanning paths: /branches/branch\xc3\xa9 0/1 (0.00%) (esc)
113 0 branch to branch?e
113 0 branch to branch?e
114 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/branches/branch?e@6
114 source: svn:afeb9c47-92ff-4c0c-9f72-e1f6eb8ac9af/branches/branch?e@6
115 converting: 5/6 revisions (83.33%)
115 converting: 5/6 revisions (83.33%)
116 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
116 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
117 scanning paths: /branches/branch\xc3\xa9e 0/1 (0.00%) (esc)
117 scanning paths: /branches/branch\xc3\xa9e 0/1 (0.00%) (esc)
118 reparent to file://*/svn-repo (glob)
118 reparent to file://*/svn-repo (glob)
119 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
119 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
120 reparent to file://*/svn-repo (glob)
120 reparent to file://*/svn-repo (glob)
121 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
121 reparent to file://*/svn-repo/branches/branch%C3%A9e (glob)
122 updating tags
122 updating tags
123 .hgtags
123 .hgtags
124 run hg sink post-conversion action
124 run hg sink post-conversion action
125 $ cd A-hg
125 $ cd A-hg
126 $ hg up
126 $ hg up
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
128
128
129 Check tags are in UTF-8
129 Check tags are in UTF-8
130
130
131 $ cat .hgtags
131 $ cat .hgtags
132 221c3fdaf24df5f14c0a64c597581e2eacfb47bb branch\xc3\xa9e (esc)
132 e94e4422020e715add80525e8f0f46c9968689f1 branch\xc3\xa9e (esc)
133 7a40952c2db29cf00d9e31df3749e98d8a4bdcbf branch\xc3\xa9 (esc)
133 f7e66f98380ed1e53a797c5c7a7a2616a7ab377d branch\xc3\xa9 (esc)
134
134
135 $ cd ..
135 $ cd ..
@@ -1,127 +1,127
1 # A B
1 # A B
2 #
2 #
3 # 3 4 3
3 # 3 4 3
4 # |\/| |\
4 # |\/| |\
5 # |/\| | \
5 # |/\| | \
6 # 1 2 1 2
6 # 1 2 1 2
7 # \ / \ /
7 # \ / \ /
8 # 0 0
8 # 0 0
9 #
9 #
10 # if the result of the merge of 1 and 2
10 # if the result of the merge of 1 and 2
11 # is the same in 3 and 4, no new manifest
11 # is the same in 3 and 4, no new manifest
12 # will be created and the manifest group
12 # will be created and the manifest group
13 # will be empty during the pull
13 # will be empty during the pull
14 #
14 #
15 # (plus we test a failure where outgoing
15 # (plus we test a failure where outgoing
16 # wrongly reported the number of csets)
16 # wrongly reported the number of csets)
17
17
18 $ hg init a
18 $ hg init a
19 $ cd a
19 $ cd a
20 $ touch init
20 $ touch init
21 $ hg ci -A -m 0
21 $ hg ci -A -m 0
22 adding init
22 adding init
23 $ touch x y
23 $ touch x y
24 $ hg ci -A -m 1
24 $ hg ci -A -m 1
25 adding x
25 adding x
26 adding y
26 adding y
27
27
28 $ hg update 0
28 $ hg update 0
29 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
29 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
30 $ touch x y
30 $ touch x y
31 $ hg ci -A -m 2
31 $ hg ci -A -m 2
32 adding x
32 adding x
33 adding y
33 adding y
34 created new head
34 created new head
35
35
36 $ hg merge 1
36 $ hg merge 1
37 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
38 (branch merge, don't forget to commit)
39 $ hg ci -A -m m1
39 $ hg ci -A -m m1
40
40
41 $ hg update -C 1
41 $ hg update -C 1
42 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ hg merge 2
43 $ hg merge 2
44 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 (branch merge, don't forget to commit)
45 (branch merge, don't forget to commit)
46 $ hg ci -A -m m2
46 $ hg ci -A -m m2
47 created new head
47 created new head
48
48
49 $ cd ..
49 $ cd ..
50
50
51 $ hg clone -r 3 a b
51 $ hg clone -r 3 a b
52 adding changesets
52 adding changesets
53 adding manifests
53 adding manifests
54 adding file changes
54 adding file changes
55 added 4 changesets with 3 changes to 3 files
55 added 4 changesets with 3 changes to 3 files
56 updating to branch default
56 updating to branch default
57 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
58
58
59 $ hg clone -r 4 a c
59 $ hg clone -r 4 a c
60 adding changesets
60 adding changesets
61 adding manifests
61 adding manifests
62 adding file changes
62 adding file changes
63 added 4 changesets with 3 changes to 3 files
63 added 4 changesets with 3 changes to 3 files
64 updating to branch default
64 updating to branch default
65 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
65 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
66
66
67 $ hg -R a outgoing b
67 $ hg -R a outgoing b
68 comparing with b
68 comparing with b
69 searching for changes
69 searching for changes
70 changeset: 4:119caaef4ed1
70 changeset: 4:1ec3c74fc0e0
71 tag: tip
71 tag: tip
72 parent: 1:79f9e10cd04e
72 parent: 1:79f9e10cd04e
73 parent: 2:8e1bb01c1a24
73 parent: 2:8e1bb01c1a24
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: m2
76 summary: m2
77
77
78 $ hg -R a outgoing c
78 $ hg -R a outgoing c
79 comparing with c
79 comparing with c
80 searching for changes
80 searching for changes
81 changeset: 3:cbb48b367d1b
81 changeset: 3:d15a0c284984
82 parent: 2:8e1bb01c1a24
82 parent: 2:8e1bb01c1a24
83 parent: 1:79f9e10cd04e
83 parent: 1:79f9e10cd04e
84 user: test
84 user: test
85 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
86 summary: m1
86 summary: m1
87
87
88 $ hg -R b outgoing c
88 $ hg -R b outgoing c
89 comparing with c
89 comparing with c
90 searching for changes
90 searching for changes
91 changeset: 3:cbb48b367d1b
91 changeset: 3:d15a0c284984
92 tag: tip
92 tag: tip
93 parent: 2:8e1bb01c1a24
93 parent: 2:8e1bb01c1a24
94 parent: 1:79f9e10cd04e
94 parent: 1:79f9e10cd04e
95 user: test
95 user: test
96 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
97 summary: m1
97 summary: m1
98
98
99 $ hg -R c outgoing b
99 $ hg -R c outgoing b
100 comparing with b
100 comparing with b
101 searching for changes
101 searching for changes
102 changeset: 3:119caaef4ed1
102 changeset: 3:1ec3c74fc0e0
103 tag: tip
103 tag: tip
104 parent: 1:79f9e10cd04e
104 parent: 1:79f9e10cd04e
105 parent: 2:8e1bb01c1a24
105 parent: 2:8e1bb01c1a24
106 user: test
106 user: test
107 date: Thu Jan 01 00:00:00 1970 +0000
107 date: Thu Jan 01 00:00:00 1970 +0000
108 summary: m2
108 summary: m2
109
109
110
110
111 $ hg -R b pull a
111 $ hg -R b pull a
112 pulling from a
112 pulling from a
113 searching for changes
113 searching for changes
114 adding changesets
114 adding changesets
115 adding manifests
115 adding manifests
116 adding file changes
116 adding file changes
117 added 1 changesets with 0 changes to 0 files (+1 heads)
117 added 1 changesets with 0 changes to 0 files (+1 heads)
118 (run 'hg heads' to see heads, 'hg merge' to merge)
118 (run 'hg heads' to see heads, 'hg merge' to merge)
119
119
120 $ hg -R c pull a
120 $ hg -R c pull a
121 pulling from a
121 pulling from a
122 searching for changes
122 searching for changes
123 adding changesets
123 adding changesets
124 adding manifests
124 adding manifests
125 adding file changes
125 adding file changes
126 added 1 changesets with 0 changes to 0 files (+1 heads)
126 added 1 changesets with 0 changes to 0 files (+1 heads)
127 (run 'hg heads' to see heads, 'hg merge' to merge)
127 (run 'hg heads' to see heads, 'hg merge' to merge)
@@ -1,249 +1,249
1 Test character encoding
1 Test character encoding
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 we need a repo with some legacy latin-1 changesets
6 we need a repo with some legacy latin-1 changesets
7
7
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
9 adding changesets
9 adding changesets
10 adding manifests
10 adding manifests
11 adding file changes
11 adding file changes
12 added 2 changesets with 2 changes to 1 files
12 added 2 changesets with 2 changes to 1 files
13 (run 'hg update' to get a working copy)
13 (run 'hg update' to get a working copy)
14 $ hg co
14 $ hg co
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ python << EOF
16 $ python << EOF
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
20 > EOF
20 > EOF
21
21
22 should fail with encoding error
22 should fail with encoding error
23
23
24 $ echo "plain old ascii" > a
24 $ echo "plain old ascii" > a
25 $ hg st
25 $ hg st
26 M a
26 M a
27 ? latin-1
27 ? latin-1
28 ? latin-1-tag
28 ? latin-1-tag
29 ? utf-8
29 ? utf-8
30 $ HGENCODING=ascii hg ci -l latin-1
30 $ HGENCODING=ascii hg ci -l latin-1
31 transaction abort!
31 transaction abort!
32 rollback completed
32 rollback completed
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
34 [255]
34 [255]
35
35
36 these should work
36 these should work
37
37
38 $ echo "latin-1" > a
38 $ echo "latin-1" > a
39 $ HGENCODING=latin-1 hg ci -l latin-1
39 $ HGENCODING=latin-1 hg ci -l latin-1
40 $ echo "utf-8" > a
40 $ echo "utf-8" > a
41 $ HGENCODING=utf-8 hg ci -l utf-8
41 $ HGENCODING=utf-8 hg ci -l utf-8
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
44 marked working directory as branch \xe9 (esc)
44 marked working directory as branch \xe9 (esc)
45 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
45 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
46 $ rm .hg/branch
46 $ rm .hg/branch
47
47
48 hg log (ascii)
48 hg log (ascii)
49
49
50 $ hg --encoding ascii log
50 $ hg --encoding ascii log
51 changeset: 5:093c6077d1c8
51 changeset: 5:a52c0692f24a
52 branch: ?
52 branch: ?
53 tag: tip
53 tag: tip
54 user: test
54 user: test
55 date: Thu Jan 01 00:00:00 1970 +0000
55 date: Thu Jan 01 00:00:00 1970 +0000
56 summary: latin1 branch
56 summary: latin1 branch
57
57
58 changeset: 4:94db611b4196
58 changeset: 4:94db611b4196
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Added tag ? for changeset ca661e7520de
61 summary: Added tag ? for changeset ca661e7520de
62
62
63 changeset: 3:ca661e7520de
63 changeset: 3:ca661e7520de
64 tag: ?
64 tag: ?
65 user: test
65 user: test
66 date: Thu Jan 01 00:00:00 1970 +0000
66 date: Thu Jan 01 00:00:00 1970 +0000
67 summary: utf-8 e' encoded: ?
67 summary: utf-8 e' encoded: ?
68
68
69 changeset: 2:650c6f3d55dd
69 changeset: 2:650c6f3d55dd
70 user: test
70 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
71 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: latin-1 e' encoded: ?
72 summary: latin-1 e' encoded: ?
73
73
74 changeset: 1:0e5b7e3f9c4a
74 changeset: 1:0e5b7e3f9c4a
75 user: test
75 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
76 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
77 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
78
78
79 changeset: 0:1e78a93102a3
79 changeset: 0:1e78a93102a3
80 user: test
80 user: test
81 date: Mon Jan 12 13:46:40 1970 +0000
81 date: Mon Jan 12 13:46:40 1970 +0000
82 summary: latin-1 e': ? = u'\xe9'
82 summary: latin-1 e': ? = u'\xe9'
83
83
84
84
85 hg log (latin-1)
85 hg log (latin-1)
86
86
87 $ hg --encoding latin-1 log
87 $ hg --encoding latin-1 log
88 changeset: 5:093c6077d1c8
88 changeset: 5:a52c0692f24a
89 branch: \xe9 (esc)
89 branch: \xe9 (esc)
90 tag: tip
90 tag: tip
91 user: test
91 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
92 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: latin1 branch
93 summary: latin1 branch
94
94
95 changeset: 4:94db611b4196
95 changeset: 4:94db611b4196
96 user: test
96 user: test
97 date: Thu Jan 01 00:00:00 1970 +0000
97 date: Thu Jan 01 00:00:00 1970 +0000
98 summary: Added tag \xe9 for changeset ca661e7520de (esc)
98 summary: Added tag \xe9 for changeset ca661e7520de (esc)
99
99
100 changeset: 3:ca661e7520de
100 changeset: 3:ca661e7520de
101 tag: \xe9 (esc)
101 tag: \xe9 (esc)
102 user: test
102 user: test
103 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
104 summary: utf-8 e' encoded: \xe9 (esc)
104 summary: utf-8 e' encoded: \xe9 (esc)
105
105
106 changeset: 2:650c6f3d55dd
106 changeset: 2:650c6f3d55dd
107 user: test
107 user: test
108 date: Thu Jan 01 00:00:00 1970 +0000
108 date: Thu Jan 01 00:00:00 1970 +0000
109 summary: latin-1 e' encoded: \xe9 (esc)
109 summary: latin-1 e' encoded: \xe9 (esc)
110
110
111 changeset: 1:0e5b7e3f9c4a
111 changeset: 1:0e5b7e3f9c4a
112 user: test
112 user: test
113 date: Mon Jan 12 13:46:40 1970 +0000
113 date: Mon Jan 12 13:46:40 1970 +0000
114 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
114 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
115
115
116 changeset: 0:1e78a93102a3
116 changeset: 0:1e78a93102a3
117 user: test
117 user: test
118 date: Mon Jan 12 13:46:40 1970 +0000
118 date: Mon Jan 12 13:46:40 1970 +0000
119 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
119 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
120
120
121
121
122 hg log (utf-8)
122 hg log (utf-8)
123
123
124 $ hg --encoding utf-8 log
124 $ hg --encoding utf-8 log
125 changeset: 5:093c6077d1c8
125 changeset: 5:a52c0692f24a
126 branch: \xc3\xa9 (esc)
126 branch: \xc3\xa9 (esc)
127 tag: tip
127 tag: tip
128 user: test
128 user: test
129 date: Thu Jan 01 00:00:00 1970 +0000
129 date: Thu Jan 01 00:00:00 1970 +0000
130 summary: latin1 branch
130 summary: latin1 branch
131
131
132 changeset: 4:94db611b4196
132 changeset: 4:94db611b4196
133 user: test
133 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
135 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
135 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
136
136
137 changeset: 3:ca661e7520de
137 changeset: 3:ca661e7520de
138 tag: \xc3\xa9 (esc)
138 tag: \xc3\xa9 (esc)
139 user: test
139 user: test
140 date: Thu Jan 01 00:00:00 1970 +0000
140 date: Thu Jan 01 00:00:00 1970 +0000
141 summary: utf-8 e' encoded: \xc3\xa9 (esc)
141 summary: utf-8 e' encoded: \xc3\xa9 (esc)
142
142
143 changeset: 2:650c6f3d55dd
143 changeset: 2:650c6f3d55dd
144 user: test
144 user: test
145 date: Thu Jan 01 00:00:00 1970 +0000
145 date: Thu Jan 01 00:00:00 1970 +0000
146 summary: latin-1 e' encoded: \xc3\xa9 (esc)
146 summary: latin-1 e' encoded: \xc3\xa9 (esc)
147
147
148 changeset: 1:0e5b7e3f9c4a
148 changeset: 1:0e5b7e3f9c4a
149 user: test
149 user: test
150 date: Mon Jan 12 13:46:40 1970 +0000
150 date: Mon Jan 12 13:46:40 1970 +0000
151 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
151 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
152
152
153 changeset: 0:1e78a93102a3
153 changeset: 0:1e78a93102a3
154 user: test
154 user: test
155 date: Mon Jan 12 13:46:40 1970 +0000
155 date: Mon Jan 12 13:46:40 1970 +0000
156 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
156 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
157
157
158
158
159 hg tags (ascii)
159 hg tags (ascii)
160
160
161 $ HGENCODING=ascii hg tags
161 $ HGENCODING=ascii hg tags
162 tip 5:093c6077d1c8
162 tip 5:a52c0692f24a
163 ? 3:ca661e7520de
163 ? 3:ca661e7520de
164
164
165 hg tags (latin-1)
165 hg tags (latin-1)
166
166
167 $ HGENCODING=latin-1 hg tags
167 $ HGENCODING=latin-1 hg tags
168 tip 5:093c6077d1c8
168 tip 5:a52c0692f24a
169 \xe9 3:ca661e7520de (esc)
169 \xe9 3:ca661e7520de (esc)
170
170
171 hg tags (utf-8)
171 hg tags (utf-8)
172
172
173 $ HGENCODING=utf-8 hg tags
173 $ HGENCODING=utf-8 hg tags
174 tip 5:093c6077d1c8
174 tip 5:a52c0692f24a
175 \xc3\xa9 3:ca661e7520de (esc)
175 \xc3\xa9 3:ca661e7520de (esc)
176
176
177 hg branches (ascii)
177 hg branches (ascii)
178
178
179 $ HGENCODING=ascii hg branches
179 $ HGENCODING=ascii hg branches
180 ? 5:093c6077d1c8
180 ? 5:a52c0692f24a
181 default 4:94db611b4196 (inactive)
181 default 4:94db611b4196 (inactive)
182
182
183 hg branches (latin-1)
183 hg branches (latin-1)
184
184
185 $ HGENCODING=latin-1 hg branches
185 $ HGENCODING=latin-1 hg branches
186 \xe9 5:093c6077d1c8 (esc)
186 \xe9 5:a52c0692f24a (esc)
187 default 4:94db611b4196 (inactive)
187 default 4:94db611b4196 (inactive)
188
188
189 hg branches (utf-8)
189 hg branches (utf-8)
190
190
191 $ HGENCODING=utf-8 hg branches
191 $ HGENCODING=utf-8 hg branches
192 \xc3\xa9 5:093c6077d1c8 (esc)
192 \xc3\xa9 5:a52c0692f24a (esc)
193 default 4:94db611b4196 (inactive)
193 default 4:94db611b4196 (inactive)
194 $ echo '[ui]' >> .hg/hgrc
194 $ echo '[ui]' >> .hg/hgrc
195 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
195 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
196
196
197 hg log (utf-8)
197 hg log (utf-8)
198
198
199 $ HGENCODING=utf-8 hg log
199 $ HGENCODING=utf-8 hg log
200 changeset: 5:093c6077d1c8
200 changeset: 5:a52c0692f24a
201 branch: \xc3\xa9 (esc)
201 branch: \xc3\xa9 (esc)
202 tag: tip
202 tag: tip
203 user: test
203 user: test
204 date: Thu Jan 01 00:00:00 1970 +0000
204 date: Thu Jan 01 00:00:00 1970 +0000
205 summary: latin1 branch
205 summary: latin1 branch
206
206
207 changeset: 4:94db611b4196
207 changeset: 4:94db611b4196
208 user: test
208 user: test
209 date: Thu Jan 01 00:00:00 1970 +0000
209 date: Thu Jan 01 00:00:00 1970 +0000
210 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
210 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
211
211
212 changeset: 3:ca661e7520de
212 changeset: 3:ca661e7520de
213 tag: \xc3\xa9 (esc)
213 tag: \xc3\xa9 (esc)
214 user: test
214 user: test
215 date: Thu Jan 01 00:00:00 1970 +0000
215 date: Thu Jan 01 00:00:00 1970 +0000
216 summary: utf-8 e' encoded: \xc3\xa9 (esc)
216 summary: utf-8 e' encoded: \xc3\xa9 (esc)
217
217
218 changeset: 2:650c6f3d55dd
218 changeset: 2:650c6f3d55dd
219 user: test
219 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
220 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: latin-1 e' encoded: \xc3\xa9 (esc)
221 summary: latin-1 e' encoded: \xc3\xa9 (esc)
222
222
223 changeset: 1:0e5b7e3f9c4a
223 changeset: 1:0e5b7e3f9c4a
224 user: test
224 user: test
225 date: Mon Jan 12 13:46:40 1970 +0000
225 date: Mon Jan 12 13:46:40 1970 +0000
226 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
226 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
227
227
228 changeset: 0:1e78a93102a3
228 changeset: 0:1e78a93102a3
229 user: test
229 user: test
230 date: Mon Jan 12 13:46:40 1970 +0000
230 date: Mon Jan 12 13:46:40 1970 +0000
231 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
231 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
232
232
233
233
234 hg log (dolphin)
234 hg log (dolphin)
235
235
236 $ HGENCODING=dolphin hg log
236 $ HGENCODING=dolphin hg log
237 abort: unknown encoding: dolphin, please check your locale settings
237 abort: unknown encoding: dolphin, please check your locale settings
238 [255]
238 [255]
239 $ HGENCODING=ascii hg branch `cat latin-1-tag`
239 $ HGENCODING=ascii hg branch `cat latin-1-tag`
240 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
240 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
241 [255]
241 [255]
242 $ cp latin-1-tag .hg/branch
242 $ cp latin-1-tag .hg/branch
243 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
243 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
244
244
245 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
245 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
246
246
247 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
247 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
248 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
248 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
249
249
@@ -1,95 +1,95
1 http://mercurial.selenic.com/bts/issue1306
1 http://mercurial.selenic.com/bts/issue1306
2
2
3 Initialize remote repo with branches:
3 Initialize remote repo with branches:
4
4
5 $ hg init remote
5 $ hg init remote
6 $ cd remote
6 $ cd remote
7
7
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Ama
9 $ hg ci -Ama
10 adding a
10 adding a
11
11
12 $ hg branch br
12 $ hg branch br
13 marked working directory as branch br
13 marked working directory as branch br
14 $ hg ci -Amb
14 $ hg ci -Amb
15
15
16 $ echo c > c
16 $ echo c > c
17 $ hg ci -Amc
17 $ hg ci -Amc
18 adding c
18 adding c
19
19
20 $ hg log
20 $ hg log
21 changeset: 2:1630aed6ed2b
21 changeset: 2:ae3d9c30ec50
22 branch: br
22 branch: br
23 tag: tip
23 tag: tip
24 user: test
24 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
25 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: c
26 summary: c
27
27
28 changeset: 1:234f53e6c5ff
28 changeset: 1:3f7f930ca414
29 branch: br
29 branch: br
30 user: test
30 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
31 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: b
32 summary: b
33
33
34 changeset: 0:cb9a9f314b8b
34 changeset: 0:cb9a9f314b8b
35 user: test
35 user: test
36 date: Thu Jan 01 00:00:00 1970 +0000
36 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: a
37 summary: a
38
38
39
39
40 $ cd ..
40 $ cd ..
41
41
42 Try cloning -r branch:
42 Try cloning -r branch:
43
43
44 $ hg clone -rbr remote local1
44 $ hg clone -rbr remote local1
45 adding changesets
45 adding changesets
46 adding manifests
46 adding manifests
47 adding file changes
47 adding file changes
48 added 3 changesets with 2 changes to 2 files
48 added 3 changesets with 2 changes to 2 files
49 updating to branch br
49 updating to branch br
50 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
51
51
52 $ hg -R local1 parents
52 $ hg -R local1 parents
53 changeset: 2:1630aed6ed2b
53 changeset: 2:ae3d9c30ec50
54 branch: br
54 branch: br
55 tag: tip
55 tag: tip
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
57 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: c
58 summary: c
59
59
60
60
61 Try cloning -rother clone#branch:
61 Try cloning -rother clone#branch:
62
62
63 $ hg clone -r0 remote#br local2
63 $ hg clone -r0 remote#br local2
64 adding changesets
64 adding changesets
65 adding manifests
65 adding manifests
66 adding file changes
66 adding file changes
67 added 3 changesets with 2 changes to 2 files
67 added 3 changesets with 2 changes to 2 files
68 updating to branch default
68 updating to branch default
69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70
70
71 $ hg -R local2 parents
71 $ hg -R local2 parents
72 changeset: 0:cb9a9f314b8b
72 changeset: 0:cb9a9f314b8b
73 user: test
73 user: test
74 date: Thu Jan 01 00:00:00 1970 +0000
74 date: Thu Jan 01 00:00:00 1970 +0000
75 summary: a
75 summary: a
76
76
77
77
78 Try cloning -r1 clone#branch:
78 Try cloning -r1 clone#branch:
79
79
80 $ hg clone -r1 remote#br local3
80 $ hg clone -r1 remote#br local3
81 adding changesets
81 adding changesets
82 adding manifests
82 adding manifests
83 adding file changes
83 adding file changes
84 added 3 changesets with 2 changes to 2 files
84 added 3 changesets with 2 changes to 2 files
85 updating to branch br
85 updating to branch br
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87
87
88 $ hg -R local3 parents
88 $ hg -R local3 parents
89 changeset: 1:234f53e6c5ff
89 changeset: 1:3f7f930ca414
90 branch: br
90 branch: br
91 user: test
91 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
92 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: b
93 summary: b
94
94
95
95
@@ -1,1074 +1,1074
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [extensions]
2 > [extensions]
3 > keyword =
3 > keyword =
4 > mq =
4 > mq =
5 > notify =
5 > notify =
6 > record =
6 > record =
7 > transplant =
7 > transplant =
8 > [ui]
8 > [ui]
9 > interactive = true
9 > interactive = true
10 > EOF
10 > EOF
11
11
12 Run kwdemo before [keyword] files are set up
12 Run kwdemo before [keyword] files are set up
13 as it would succeed without uisetup otherwise
13 as it would succeed without uisetup otherwise
14
14
15 $ hg --quiet kwdemo
15 $ hg --quiet kwdemo
16 [extensions]
16 [extensions]
17 keyword =
17 keyword =
18 [keyword]
18 [keyword]
19 demo.txt =
19 demo.txt =
20 [keywordset]
20 [keywordset]
21 svn = False
21 svn = False
22 [keywordmaps]
22 [keywordmaps]
23 Author = {author|user}
23 Author = {author|user}
24 Date = {date|utcdate}
24 Date = {date|utcdate}
25 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
25 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
26 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
26 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
27 RCSFile = {file|basename},v
27 RCSFile = {file|basename},v
28 RCSfile = {file|basename},v
28 RCSfile = {file|basename},v
29 Revision = {node|short}
29 Revision = {node|short}
30 Source = {root}/{file},v
30 Source = {root}/{file},v
31 $Author: test $
31 $Author: test $
32 $Date: ????/??/?? ??:??:?? $ (glob)
32 $Date: ????/??/?? ??:??:?? $ (glob)
33 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
33 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
34 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
34 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
35 $RCSFile: demo.txt,v $
35 $RCSFile: demo.txt,v $
36 $RCSfile: demo.txt,v $
36 $RCSfile: demo.txt,v $
37 $Revision: ???????????? $ (glob)
37 $Revision: ???????????? $ (glob)
38 $Source: */demo.txt,v $ (glob)
38 $Source: */demo.txt,v $ (glob)
39
39
40 $ hg --quiet kwdemo "Branch = {branches}"
40 $ hg --quiet kwdemo "Branch = {branches}"
41 [extensions]
41 [extensions]
42 keyword =
42 keyword =
43 [keyword]
43 [keyword]
44 demo.txt =
44 demo.txt =
45 [keywordset]
45 [keywordset]
46 svn = False
46 svn = False
47 [keywordmaps]
47 [keywordmaps]
48 Branch = {branches}
48 Branch = {branches}
49 $Branch: demobranch $
49 $Branch: demobranch $
50
50
51 $ cat <<EOF >> $HGRCPATH
51 $ cat <<EOF >> $HGRCPATH
52 > [keyword]
52 > [keyword]
53 > ** =
53 > ** =
54 > b = ignore
54 > b = ignore
55 > i = ignore
55 > i = ignore
56 > [hooks]
56 > [hooks]
57 > EOF
57 > EOF
58 $ cp $HGRCPATH $HGRCPATH.nohooks
58 $ cp $HGRCPATH $HGRCPATH.nohooks
59 > cat <<EOF >> $HGRCPATH
59 > cat <<EOF >> $HGRCPATH
60 > commit=
60 > commit=
61 > commit.test=cp a hooktest
61 > commit.test=cp a hooktest
62 > EOF
62 > EOF
63
63
64 $ hg init Test-bndl
64 $ hg init Test-bndl
65 $ cd Test-bndl
65 $ cd Test-bndl
66
66
67 kwshrink should exit silently in empty/invalid repo
67 kwshrink should exit silently in empty/invalid repo
68
68
69 $ hg kwshrink
69 $ hg kwshrink
70
70
71 Symlinks cannot be created on Windows.
71 Symlinks cannot be created on Windows.
72 A bundle to test this was made with:
72 A bundle to test this was made with:
73 hg init t
73 hg init t
74 cd t
74 cd t
75 echo a > a
75 echo a > a
76 ln -s a sym
76 ln -s a sym
77 hg add sym
77 hg add sym
78 hg ci -m addsym -u mercurial
78 hg ci -m addsym -u mercurial
79 hg bundle --base null ../test-keyword.hg
79 hg bundle --base null ../test-keyword.hg
80
80
81 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
81 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
82 pulling from *test-keyword.hg (glob)
82 pulling from *test-keyword.hg (glob)
83 requesting all changes
83 requesting all changes
84 adding changesets
84 adding changesets
85 adding manifests
85 adding manifests
86 adding file changes
86 adding file changes
87 added 1 changesets with 1 changes to 1 files
87 added 1 changesets with 1 changes to 1 files
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89
89
90 $ echo 'expand $Id$' > a
90 $ echo 'expand $Id$' > a
91 $ echo 'do not process $Id:' >> a
91 $ echo 'do not process $Id:' >> a
92 $ echo 'xxx $' >> a
92 $ echo 'xxx $' >> a
93 $ echo 'ignore $Id$' > b
93 $ echo 'ignore $Id$' > b
94
94
95 Output files as they were created
95 Output files as they were created
96
96
97 $ cat a b
97 $ cat a b
98 expand $Id$
98 expand $Id$
99 do not process $Id:
99 do not process $Id:
100 xxx $
100 xxx $
101 ignore $Id$
101 ignore $Id$
102
102
103 no kwfiles
103 no kwfiles
104
104
105 $ hg kwfiles
105 $ hg kwfiles
106
106
107 untracked candidates
107 untracked candidates
108
108
109 $ hg -v kwfiles --unknown
109 $ hg -v kwfiles --unknown
110 k a
110 k a
111
111
112 Add files and check status
112 Add files and check status
113
113
114 $ hg addremove
114 $ hg addremove
115 adding a
115 adding a
116 adding b
116 adding b
117 $ hg status
117 $ hg status
118 A a
118 A a
119 A b
119 A b
120
120
121
121
122 Default keyword expansion including commit hook
122 Default keyword expansion including commit hook
123 Interrupted commit should not change state or run commit hook
123 Interrupted commit should not change state or run commit hook
124
124
125 $ hg --debug commit
125 $ hg --debug commit
126 abort: empty commit message
126 abort: empty commit message
127 [255]
127 [255]
128 $ hg status
128 $ hg status
129 A a
129 A a
130 A b
130 A b
131
131
132 Commit with several checks
132 Commit with several checks
133
133
134 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
134 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
135 a
135 a
136 b
136 b
137 overwriting a expanding keywords
137 overwriting a expanding keywords
138 running hook commit.test: cp a hooktest
138 running hook commit.test: cp a hooktest
139 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
139 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
140 $ hg status
140 $ hg status
141 ? hooktest
141 ? hooktest
142 $ hg debugrebuildstate
142 $ hg debugrebuildstate
143 $ hg --quiet identify
143 $ hg --quiet identify
144 ef63ca68695b
144 ef63ca68695b
145
145
146 cat files in working directory with keywords expanded
146 cat files in working directory with keywords expanded
147
147
148 $ cat a b
148 $ cat a b
149 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
149 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
150 do not process $Id:
150 do not process $Id:
151 xxx $
151 xxx $
152 ignore $Id$
152 ignore $Id$
153
153
154 hg cat files and symlink, no expansion
154 hg cat files and symlink, no expansion
155
155
156 $ hg cat sym a b && echo
156 $ hg cat sym a b && echo
157 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
157 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
158 do not process $Id:
158 do not process $Id:
159 xxx $
159 xxx $
160 ignore $Id$
160 ignore $Id$
161 a
161 a
162
162
163 Test hook execution
163 Test hook execution
164
164
165 $ diff a hooktest
165 $ diff a hooktest
166
166
167 $ cp $HGRCPATH.nohooks $HGRCPATH
167 $ cp $HGRCPATH.nohooks $HGRCPATH
168 $ rm hooktest
168 $ rm hooktest
169
169
170 bundle
170 bundle
171
171
172 $ hg bundle --base null ../kw.hg
172 $ hg bundle --base null ../kw.hg
173 2 changesets found
173 2 changesets found
174 $ cd ..
174 $ cd ..
175 $ hg init Test
175 $ hg init Test
176 $ cd Test
176 $ cd Test
177
177
178 Notify on pull to check whether keywords stay as is in email
178 Notify on pull to check whether keywords stay as is in email
179 ie. if patch.diff wrapper acts as it should
179 ie. if patch.diff wrapper acts as it should
180
180
181 $ cat <<EOF >> $HGRCPATH
181 $ cat <<EOF >> $HGRCPATH
182 > [hooks]
182 > [hooks]
183 > incoming.notify = python:hgext.notify.hook
183 > incoming.notify = python:hgext.notify.hook
184 > [notify]
184 > [notify]
185 > sources = pull
185 > sources = pull
186 > diffstat = False
186 > diffstat = False
187 > maxsubject = 15
187 > maxsubject = 15
188 > [reposubs]
188 > [reposubs]
189 > * = Test
189 > * = Test
190 > EOF
190 > EOF
191
191
192 Pull from bundle and trigger notify
192 Pull from bundle and trigger notify
193
193
194 $ hg pull -u ../kw.hg
194 $ hg pull -u ../kw.hg
195 pulling from ../kw.hg
195 pulling from ../kw.hg
196 requesting all changes
196 requesting all changes
197 adding changesets
197 adding changesets
198 adding manifests
198 adding manifests
199 adding file changes
199 adding file changes
200 added 2 changesets with 3 changes to 3 files
200 added 2 changesets with 3 changes to 3 files
201 Content-Type: text/plain; charset="us-ascii"
201 Content-Type: text/plain; charset="us-ascii"
202 MIME-Version: 1.0
202 MIME-Version: 1.0
203 Content-Transfer-Encoding: 7bit
203 Content-Transfer-Encoding: 7bit
204 Date: * (glob)
204 Date: * (glob)
205 Subject: changeset in...
205 Subject: changeset in...
206 From: mercurial
206 From: mercurial
207 X-Hg-Notification: changeset a2392c293916
207 X-Hg-Notification: changeset a2392c293916
208 Message-Id: <hg.a2392c293916*> (glob)
208 Message-Id: <hg.a2392c293916*> (glob)
209 To: Test
209 To: Test
210
210
211 changeset a2392c293916 in $TESTTMP/Test
211 changeset a2392c293916 in $TESTTMP/Test
212 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
212 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
213 description:
213 description:
214 addsym
214 addsym
215
215
216 diffs (6 lines):
216 diffs (6 lines):
217
217
218 diff -r 000000000000 -r a2392c293916 sym
218 diff -r 000000000000 -r a2392c293916 sym
219 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
219 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
220 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
220 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
221 @@ -0,0 +1,1 @@
221 @@ -0,0 +1,1 @@
222 +a
222 +a
223 \ No newline at end of file
223 \ No newline at end of file
224 Content-Type: text/plain; charset="us-ascii"
224 Content-Type: text/plain; charset="us-ascii"
225 MIME-Version: 1.0
225 MIME-Version: 1.0
226 Content-Transfer-Encoding: 7bit
226 Content-Transfer-Encoding: 7bit
227 Date:* (glob)
227 Date:* (glob)
228 Subject: changeset in...
228 Subject: changeset in...
229 From: User Name <user@example.com>
229 From: User Name <user@example.com>
230 X-Hg-Notification: changeset ef63ca68695b
230 X-Hg-Notification: changeset ef63ca68695b
231 Message-Id: <hg.ef63ca68695b*> (glob)
231 Message-Id: <hg.ef63ca68695b*> (glob)
232 To: Test
232 To: Test
233
233
234 changeset ef63ca68695b in $TESTTMP/Test
234 changeset ef63ca68695b in $TESTTMP/Test
235 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
235 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
236 description:
236 description:
237 absym
237 absym
238
238
239 diffs (12 lines):
239 diffs (12 lines):
240
240
241 diff -r a2392c293916 -r ef63ca68695b a
241 diff -r a2392c293916 -r ef63ca68695b a
242 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
242 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243 +++ b/a Thu Jan 01 00:00:00 1970 +0000
243 +++ b/a Thu Jan 01 00:00:00 1970 +0000
244 @@ -0,0 +1,3 @@
244 @@ -0,0 +1,3 @@
245 +expand $Id$
245 +expand $Id$
246 +do not process $Id:
246 +do not process $Id:
247 +xxx $
247 +xxx $
248 diff -r a2392c293916 -r ef63ca68695b b
248 diff -r a2392c293916 -r ef63ca68695b b
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:00 1970 +0000
251 @@ -0,0 +1,1 @@
251 @@ -0,0 +1,1 @@
252 +ignore $Id$
252 +ignore $Id$
253 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
253 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
254
254
255 $ cp $HGRCPATH.nohooks $HGRCPATH
255 $ cp $HGRCPATH.nohooks $HGRCPATH
256
256
257 Touch files and check with status
257 Touch files and check with status
258
258
259 $ touch a b
259 $ touch a b
260 $ hg status
260 $ hg status
261
261
262 Update and expand
262 Update and expand
263
263
264 $ rm sym a b
264 $ rm sym a b
265 $ hg update -C
265 $ hg update -C
266 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 $ cat a b
267 $ cat a b
268 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
268 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
269 do not process $Id:
269 do not process $Id:
270 xxx $
270 xxx $
271 ignore $Id$
271 ignore $Id$
272
272
273 Check whether expansion is filewise
273 Check whether expansion is filewise
274
274
275 $ echo '$Id$' > c
275 $ echo '$Id$' > c
276 $ echo 'tests for different changenodes' >> c
276 $ echo 'tests for different changenodes' >> c
277
277
278 commit file c
278 commit file c
279
279
280 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
280 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
281 adding c
281 adding c
282
282
283 force expansion
283 force expansion
284
284
285 $ hg -v kwexpand
285 $ hg -v kwexpand
286 overwriting a expanding keywords
286 overwriting a expanding keywords
287 overwriting c expanding keywords
287 overwriting c expanding keywords
288
288
289 compare changenodes in a and c
289 compare changenodes in a and c
290
290
291 $ cat a c
291 $ cat a c
292 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
292 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
293 do not process $Id:
293 do not process $Id:
294 xxx $
294 xxx $
295 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
295 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
296 tests for different changenodes
296 tests for different changenodes
297
297
298 record
298 record
299
299
300 $ echo '$Id$' > r
300 $ echo '$Id$' > r
301 $ hg add r
301 $ hg add r
302
302
303 record chunk
303 record chunk
304
304
305 $ python -c \
305 $ python -c \
306 > 'l=open("a").readlines();l.insert(1,"foo\n");l.append("bar\n");open("a","w").writelines(l);'
306 > 'l=open("a").readlines();l.insert(1,"foo\n");l.append("bar\n");open("a","w").writelines(l);'
307 $ hg record -d '1 10' -m rectest a<<EOF
307 $ hg record -d '1 10' -m rectest a<<EOF
308 > y
308 > y
309 > y
309 > y
310 > n
310 > n
311 > EOF
311 > EOF
312 diff --git a/a b/a
312 diff --git a/a b/a
313 2 hunks, 2 lines changed
313 2 hunks, 2 lines changed
314 examine changes to 'a'? [Ynsfdaq?]
314 examine changes to 'a'? [Ynsfdaq?]
315 @@ -1,3 +1,4 @@
315 @@ -1,3 +1,4 @@
316 expand $Id$
316 expand $Id$
317 +foo
317 +foo
318 do not process $Id:
318 do not process $Id:
319 xxx $
319 xxx $
320 record change 1/2 to 'a'? [Ynsfdaq?]
320 record change 1/2 to 'a'? [Ynsfdaq?]
321 @@ -2,2 +3,3 @@
321 @@ -2,2 +3,3 @@
322 do not process $Id:
322 do not process $Id:
323 xxx $
323 xxx $
324 +bar
324 +bar
325 record change 2/2 to 'a'? [Ynsfdaq?]
325 record change 2/2 to 'a'? [Ynsfdaq?]
326
326
327 $ hg identify
327 $ hg identify
328 d17e03c92c97+ tip
328 d17e03c92c97+ tip
329 $ hg status
329 $ hg status
330 M a
330 M a
331 A r
331 A r
332
332
333 Cat modified file a
333 Cat modified file a
334
334
335 $ cat a
335 $ cat a
336 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
336 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
337 foo
337 foo
338 do not process $Id:
338 do not process $Id:
339 xxx $
339 xxx $
340 bar
340 bar
341
341
342 Diff remaining chunk
342 Diff remaining chunk
343
343
344 $ hg diff a
344 $ hg diff a
345 diff -r d17e03c92c97 a
345 diff -r d17e03c92c97 a
346 --- a/a Wed Dec 31 23:59:51 1969 -0000
346 --- a/a Wed Dec 31 23:59:51 1969 -0000
347 +++ b/a * (glob)
347 +++ b/a * (glob)
348 @@ -2,3 +2,4 @@
348 @@ -2,3 +2,4 @@
349 foo
349 foo
350 do not process $Id:
350 do not process $Id:
351 xxx $
351 xxx $
352 +bar
352 +bar
353
353
354 $ hg rollback
354 $ hg rollback
355 repository tip rolled back to revision 2 (undo commit)
355 repository tip rolled back to revision 2 (undo commit)
356 working directory now based on revision 2
356 working directory now based on revision 2
357
357
358 Record all chunks in file a
358 Record all chunks in file a
359
359
360 $ echo foo > msg
360 $ echo foo > msg
361
361
362 - do not use "hg record -m" here!
362 - do not use "hg record -m" here!
363
363
364 $ hg record -l msg -d '1 11' a<<EOF
364 $ hg record -l msg -d '1 11' a<<EOF
365 > y
365 > y
366 > y
366 > y
367 > y
367 > y
368 > EOF
368 > EOF
369 diff --git a/a b/a
369 diff --git a/a b/a
370 2 hunks, 2 lines changed
370 2 hunks, 2 lines changed
371 examine changes to 'a'? [Ynsfdaq?]
371 examine changes to 'a'? [Ynsfdaq?]
372 @@ -1,3 +1,4 @@
372 @@ -1,3 +1,4 @@
373 expand $Id$
373 expand $Id$
374 +foo
374 +foo
375 do not process $Id:
375 do not process $Id:
376 xxx $
376 xxx $
377 record change 1/2 to 'a'? [Ynsfdaq?]
377 record change 1/2 to 'a'? [Ynsfdaq?]
378 @@ -2,2 +3,3 @@
378 @@ -2,2 +3,3 @@
379 do not process $Id:
379 do not process $Id:
380 xxx $
380 xxx $
381 +bar
381 +bar
382 record change 2/2 to 'a'? [Ynsfdaq?]
382 record change 2/2 to 'a'? [Ynsfdaq?]
383
383
384 File a should be clean
384 File a should be clean
385
385
386 $ hg status -A a
386 $ hg status -A a
387 C a
387 C a
388
388
389 rollback and revert expansion
389 rollback and revert expansion
390
390
391 $ cat a
391 $ cat a
392 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
392 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
393 foo
393 foo
394 do not process $Id:
394 do not process $Id:
395 xxx $
395 xxx $
396 bar
396 bar
397 $ hg --verbose rollback
397 $ hg --verbose rollback
398 repository tip rolled back to revision 2 (undo commit)
398 repository tip rolled back to revision 2 (undo commit)
399 working directory now based on revision 2
399 working directory now based on revision 2
400 overwriting a expanding keywords
400 overwriting a expanding keywords
401 $ hg status a
401 $ hg status a
402 M a
402 M a
403 $ cat a
403 $ cat a
404 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
404 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
405 foo
405 foo
406 do not process $Id:
406 do not process $Id:
407 xxx $
407 xxx $
408 bar
408 bar
409 $ echo '$Id$' > y
409 $ echo '$Id$' > y
410 $ echo '$Id$' > z
410 $ echo '$Id$' > z
411 $ hg add y
411 $ hg add y
412 $ hg commit -Am "rollback only" z
412 $ hg commit -Am "rollback only" z
413 $ cat z
413 $ cat z
414 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
414 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
415 $ hg --verbose rollback
415 $ hg --verbose rollback
416 repository tip rolled back to revision 2 (undo commit)
416 repository tip rolled back to revision 2 (undo commit)
417 working directory now based on revision 2
417 working directory now based on revision 2
418 overwriting z shrinking keywords
418 overwriting z shrinking keywords
419
419
420 Only z should be overwritten
420 Only z should be overwritten
421
421
422 $ hg status a y z
422 $ hg status a y z
423 M a
423 M a
424 A y
424 A y
425 A z
425 A z
426 $ cat z
426 $ cat z
427 $Id$
427 $Id$
428 $ hg forget y z
428 $ hg forget y z
429 $ rm y z
429 $ rm y z
430
430
431 record added file alone
431 record added file alone
432
432
433 $ hg -v record -l msg -d '1 12' r<<EOF
433 $ hg -v record -l msg -d '1 12' r<<EOF
434 > y
434 > y
435 > EOF
435 > EOF
436 diff --git a/r b/r
436 diff --git a/r b/r
437 new file mode 100644
437 new file mode 100644
438 examine changes to 'r'? [Ynsfdaq?]
438 examine changes to 'r'? [Ynsfdaq?]
439 r
439 r
440 committed changeset 3:899491280810
440 committed changeset 3:899491280810
441 overwriting r expanding keywords
441 overwriting r expanding keywords
442 $ hg --verbose rollback
442 $ hg --verbose rollback
443 repository tip rolled back to revision 2 (undo commit)
443 repository tip rolled back to revision 2 (undo commit)
444 working directory now based on revision 2
444 working directory now based on revision 2
445 overwriting r shrinking keywords
445 overwriting r shrinking keywords
446 $ hg forget r
446 $ hg forget r
447 $ rm msg r
447 $ rm msg r
448 $ hg update -C
448 $ hg update -C
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
450
450
451 record added keyword ignored file
451 record added keyword ignored file
452
452
453 $ echo '$Id$' > i
453 $ echo '$Id$' > i
454 $ hg add i
454 $ hg add i
455 $ hg --verbose record -d '1 13' -m recignored<<EOF
455 $ hg --verbose record -d '1 13' -m recignored<<EOF
456 > y
456 > y
457 > EOF
457 > EOF
458 diff --git a/i b/i
458 diff --git a/i b/i
459 new file mode 100644
459 new file mode 100644
460 examine changes to 'i'? [Ynsfdaq?]
460 examine changes to 'i'? [Ynsfdaq?]
461 i
461 i
462 committed changeset 3:5f40fe93bbdc
462 committed changeset 3:5f40fe93bbdc
463 $ cat i
463 $ cat i
464 $Id$
464 $Id$
465 $ hg -q rollback
465 $ hg -q rollback
466 $ hg forget i
466 $ hg forget i
467 $ rm i
467 $ rm i
468
468
469 Test patch queue repo
469 Test patch queue repo
470
470
471 $ hg init --mq
471 $ hg init --mq
472 $ hg qimport -r tip -n mqtest.diff
472 $ hg qimport -r tip -n mqtest.diff
473 $ hg commit --mq -m mqtest
473 $ hg commit --mq -m mqtest
474
474
475 Keywords should not be expanded in patch
475 Keywords should not be expanded in patch
476
476
477 $ cat .hg/patches/mqtest.diff
477 $ cat .hg/patches/mqtest.diff
478 # HG changeset patch
478 # HG changeset patch
479 # User User Name <user@example.com>
479 # User User Name <user@example.com>
480 # Date 1 0
480 # Date 1 0
481 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
481 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
482 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
482 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
483 cndiff
483 cndiff
484
484
485 diff -r ef63ca68695b -r 40a904bbbe4c c
485 diff -r ef63ca68695b -r 40a904bbbe4c c
486 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
486 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
487 +++ b/c Thu Jan 01 00:00:01 1970 +0000
487 +++ b/c Thu Jan 01 00:00:01 1970 +0000
488 @@ -0,0 +1,2 @@
488 @@ -0,0 +1,2 @@
489 +$Id$
489 +$Id$
490 +tests for different changenodes
490 +tests for different changenodes
491
491
492 $ hg qpop
492 $ hg qpop
493 popping mqtest.diff
493 popping mqtest.diff
494 patch queue now empty
494 patch queue now empty
495
495
496 qgoto, implying qpush, should expand
496 qgoto, implying qpush, should expand
497
497
498 $ hg qgoto mqtest.diff
498 $ hg qgoto mqtest.diff
499 applying mqtest.diff
499 applying mqtest.diff
500 now at: mqtest.diff
500 now at: mqtest.diff
501 $ cat c
501 $ cat c
502 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
502 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
503 tests for different changenodes
503 tests for different changenodes
504 $ hg cat c
504 $ hg cat c
505 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
505 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
506 tests for different changenodes
506 tests for different changenodes
507
507
508 Keywords should not be expanded in filelog
508 Keywords should not be expanded in filelog
509
509
510 $ hg --config 'extensions.keyword=!' cat c
510 $ hg --config 'extensions.keyword=!' cat c
511 $Id$
511 $Id$
512 tests for different changenodes
512 tests for different changenodes
513
513
514 qpop and move on
514 qpop and move on
515
515
516 $ hg qpop
516 $ hg qpop
517 popping mqtest.diff
517 popping mqtest.diff
518 patch queue now empty
518 patch queue now empty
519
519
520 Copy and show added kwfiles
520 Copy and show added kwfiles
521
521
522 $ hg cp a c
522 $ hg cp a c
523 $ hg kwfiles
523 $ hg kwfiles
524 a
524 a
525 c
525 c
526
526
527 Commit and show expansion in original and copy
527 Commit and show expansion in original and copy
528
528
529 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
529 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
530 c
530 c
531 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
531 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
532 overwriting c expanding keywords
532 overwriting c expanding keywords
533 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
533 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
534 $ cat a c
534 $ cat a c
535 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
535 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
536 do not process $Id:
536 do not process $Id:
537 xxx $
537 xxx $
538 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
538 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
539 do not process $Id:
539 do not process $Id:
540 xxx $
540 xxx $
541
541
542 Touch copied c and check its status
542 Touch copied c and check its status
543
543
544 $ touch c
544 $ touch c
545 $ hg status
545 $ hg status
546
546
547 Copy kwfile to keyword ignored file unexpanding keywords
547 Copy kwfile to keyword ignored file unexpanding keywords
548
548
549 $ hg --verbose copy a i
549 $ hg --verbose copy a i
550 copying a to i
550 copying a to i
551 overwriting i shrinking keywords
551 overwriting i shrinking keywords
552 $ head -n 1 i
552 $ head -n 1 i
553 expand $Id$
553 expand $Id$
554 $ hg forget i
554 $ hg forget i
555 $ rm i
555 $ rm i
556
556
557 Copy ignored file to ignored file: no overwriting
557 Copy ignored file to ignored file: no overwriting
558
558
559 $ hg --verbose copy b i
559 $ hg --verbose copy b i
560 copying b to i
560 copying b to i
561 $ hg forget i
561 $ hg forget i
562 $ rm i
562 $ rm i
563
563
564 cp symlink file; hg cp -A symlink file (part1)
564 cp symlink file; hg cp -A symlink file (part1)
565 - copied symlink points to kwfile: overwrite
565 - copied symlink points to kwfile: overwrite
566
566
567 $ cp sym i
567 $ cp sym i
568 $ ls -l i
568 $ ls -l i
569 -rw-r--r--* (glob)
569 -rw-r--r--* (glob)
570 $ head -1 i
570 $ head -1 i
571 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
571 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
572 $ hg copy --after --verbose sym i
572 $ hg copy --after --verbose sym i
573 copying sym to i
573 copying sym to i
574 overwriting i shrinking keywords
574 overwriting i shrinking keywords
575 $ head -1 i
575 $ head -1 i
576 expand $Id$
576 expand $Id$
577 $ hg forget i
577 $ hg forget i
578 $ rm i
578 $ rm i
579
579
580 Test different options of hg kwfiles
580 Test different options of hg kwfiles
581
581
582 $ hg kwfiles
582 $ hg kwfiles
583 a
583 a
584 c
584 c
585 $ hg -v kwfiles --ignore
585 $ hg -v kwfiles --ignore
586 I b
586 I b
587 I sym
587 I sym
588 $ hg kwfiles --all
588 $ hg kwfiles --all
589 K a
589 K a
590 K c
590 K c
591 I b
591 I b
592 I sym
592 I sym
593
593
594 Diff specific revision
594 Diff specific revision
595
595
596 $ hg diff --rev 1
596 $ hg diff --rev 1
597 diff -r ef63ca68695b c
597 diff -r ef63ca68695b c
598 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
598 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
599 +++ b/c * (glob)
599 +++ b/c * (glob)
600 @@ -0,0 +1,3 @@
600 @@ -0,0 +1,3 @@
601 +expand $Id$
601 +expand $Id$
602 +do not process $Id:
602 +do not process $Id:
603 +xxx $
603 +xxx $
604
604
605 Status after rollback:
605 Status after rollback:
606
606
607 $ hg rollback
607 $ hg rollback
608 repository tip rolled back to revision 1 (undo commit)
608 repository tip rolled back to revision 1 (undo commit)
609 working directory now based on revision 1
609 working directory now based on revision 1
610 $ hg status
610 $ hg status
611 A c
611 A c
612 $ hg update --clean
612 $ hg update --clean
613 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
613 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
614
614
615 cp symlink file; hg cp -A symlink file (part2)
615 cp symlink file; hg cp -A symlink file (part2)
616 - copied symlink points to kw ignored file: do not overwrite
616 - copied symlink points to kw ignored file: do not overwrite
617
617
618 $ cat a > i
618 $ cat a > i
619 $ ln -s i symignored
619 $ ln -s i symignored
620 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
620 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
621 $ cp symignored x
621 $ cp symignored x
622 $ hg copy --after --verbose symignored x
622 $ hg copy --after --verbose symignored x
623 copying symignored to x
623 copying symignored to x
624 $ head -n 1 x
624 $ head -n 1 x
625 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
625 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
626 $ hg forget x
626 $ hg forget x
627 $ rm x
627 $ rm x
628
628
629 $ hg rollback
629 $ hg rollback
630 repository tip rolled back to revision 1 (undo commit)
630 repository tip rolled back to revision 1 (undo commit)
631 working directory now based on revision 1
631 working directory now based on revision 1
632 $ hg update --clean
632 $ hg update --clean
633 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
633 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
634 $ rm i symignored
634 $ rm i symignored
635
635
636 Custom keywordmaps as argument to kwdemo
636 Custom keywordmaps as argument to kwdemo
637
637
638 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
638 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
639 [extensions]
639 [extensions]
640 keyword =
640 keyword =
641 [keyword]
641 [keyword]
642 ** =
642 ** =
643 b = ignore
643 b = ignore
644 demo.txt =
644 demo.txt =
645 i = ignore
645 i = ignore
646 [keywordset]
646 [keywordset]
647 svn = False
647 svn = False
648 [keywordmaps]
648 [keywordmaps]
649 Xinfo = {author}: {desc}
649 Xinfo = {author}: {desc}
650 $Xinfo: test: hg keyword configuration and expansion example $
650 $Xinfo: test: hg keyword configuration and expansion example $
651
651
652 Configure custom keywordmaps
652 Configure custom keywordmaps
653
653
654 $ cat <<EOF >>$HGRCPATH
654 $ cat <<EOF >>$HGRCPATH
655 > [keywordmaps]
655 > [keywordmaps]
656 > Id = {file} {node|short} {date|rfc822date} {author|user}
656 > Id = {file} {node|short} {date|rfc822date} {author|user}
657 > Xinfo = {author}: {desc}
657 > Xinfo = {author}: {desc}
658 > EOF
658 > EOF
659
659
660 Cat and hg cat files before custom expansion
660 Cat and hg cat files before custom expansion
661
661
662 $ cat a b
662 $ cat a b
663 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
663 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
664 do not process $Id:
664 do not process $Id:
665 xxx $
665 xxx $
666 ignore $Id$
666 ignore $Id$
667 $ hg cat sym a b && echo
667 $ hg cat sym a b && echo
668 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
668 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
669 do not process $Id:
669 do not process $Id:
670 xxx $
670 xxx $
671 ignore $Id$
671 ignore $Id$
672 a
672 a
673
673
674 Write custom keyword and prepare multiline commit message
674 Write custom keyword and prepare multiline commit message
675
675
676 $ echo '$Xinfo$' >> a
676 $ echo '$Xinfo$' >> a
677 $ cat <<EOF >> log
677 $ cat <<EOF >> log
678 > firstline
678 > firstline
679 > secondline
679 > secondline
680 > EOF
680 > EOF
681
681
682 Interrupted commit should not change state
682 Interrupted commit should not change state
683
683
684 $ hg commit
684 $ hg commit
685 abort: empty commit message
685 abort: empty commit message
686 [255]
686 [255]
687 $ hg status
687 $ hg status
688 M a
688 M a
689 ? c
689 ? c
690 ? log
690 ? log
691
691
692 Commit with multiline message and custom expansion
692 Commit with multiline message and custom expansion
693
693
694 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
694 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
695 a
695 a
696 overwriting a expanding keywords
696 overwriting a expanding keywords
697 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
697 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
698 $ rm log
698 $ rm log
699
699
700 Stat, verify and show custom expansion (firstline)
700 Stat, verify and show custom expansion (firstline)
701
701
702 $ hg status
702 $ hg status
703 ? c
703 ? c
704 $ hg verify
704 $ hg verify
705 checking changesets
705 checking changesets
706 checking manifests
706 checking manifests
707 crosschecking files in changesets and manifests
707 crosschecking files in changesets and manifests
708 checking files
708 checking files
709 3 files, 3 changesets, 4 total revisions
709 3 files, 3 changesets, 4 total revisions
710 $ cat a b
710 $ cat a b
711 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
711 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
712 do not process $Id:
712 do not process $Id:
713 xxx $
713 xxx $
714 $Xinfo: User Name <user@example.com>: firstline $
714 $Xinfo: User Name <user@example.com>: firstline $
715 ignore $Id$
715 ignore $Id$
716 $ hg cat sym a b && echo
716 $ hg cat sym a b && echo
717 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
717 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
718 do not process $Id:
718 do not process $Id:
719 xxx $
719 xxx $
720 $Xinfo: User Name <user@example.com>: firstline $
720 $Xinfo: User Name <user@example.com>: firstline $
721 ignore $Id$
721 ignore $Id$
722 a
722 a
723
723
724 annotate
724 annotate
725
725
726 $ hg annotate a
726 $ hg annotate a
727 1: expand $Id$
727 1: expand $Id$
728 1: do not process $Id:
728 1: do not process $Id:
729 1: xxx $
729 1: xxx $
730 2: $Xinfo$
730 2: $Xinfo$
731
731
732 remove with status checks
732 remove with status checks
733
733
734 $ hg debugrebuildstate
734 $ hg debugrebuildstate
735 $ hg remove a
735 $ hg remove a
736 $ hg --debug commit -m rma
736 $ hg --debug commit -m rma
737 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
737 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
738 $ hg status
738 $ hg status
739 ? c
739 ? c
740
740
741 Rollback, revert, and check expansion
741 Rollback, revert, and check expansion
742
742
743 $ hg rollback
743 $ hg rollback
744 repository tip rolled back to revision 2 (undo commit)
744 repository tip rolled back to revision 2 (undo commit)
745 working directory now based on revision 2
745 working directory now based on revision 2
746 $ hg status
746 $ hg status
747 R a
747 R a
748 ? c
748 ? c
749 $ hg revert --no-backup --rev tip a
749 $ hg revert --no-backup --rev tip a
750 $ cat a
750 $ cat a
751 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
751 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
752 do not process $Id:
752 do not process $Id:
753 xxx $
753 xxx $
754 $Xinfo: User Name <user@example.com>: firstline $
754 $Xinfo: User Name <user@example.com>: firstline $
755
755
756 Clone to test global and local configurations
756 Clone to test global and local configurations
757
757
758 $ cd ..
758 $ cd ..
759
759
760 Expansion in destinaton with global configuration
760 Expansion in destinaton with global configuration
761
761
762 $ hg --quiet clone Test globalconf
762 $ hg --quiet clone Test globalconf
763 $ cat globalconf/a
763 $ cat globalconf/a
764 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
764 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
765 do not process $Id:
765 do not process $Id:
766 xxx $
766 xxx $
767 $Xinfo: User Name <user@example.com>: firstline $
767 $Xinfo: User Name <user@example.com>: firstline $
768
768
769 No expansion in destination with local configuration in origin only
769 No expansion in destination with local configuration in origin only
770
770
771 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
771 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
772 $ cat localconf/a
772 $ cat localconf/a
773 expand $Id$
773 expand $Id$
774 do not process $Id:
774 do not process $Id:
775 xxx $
775 xxx $
776 $Xinfo$
776 $Xinfo$
777
777
778 Clone to test incoming
778 Clone to test incoming
779
779
780 $ hg clone -r1 Test Test-a
780 $ hg clone -r1 Test Test-a
781 adding changesets
781 adding changesets
782 adding manifests
782 adding manifests
783 adding file changes
783 adding file changes
784 added 2 changesets with 3 changes to 3 files
784 added 2 changesets with 3 changes to 3 files
785 updating to branch default
785 updating to branch default
786 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
786 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 $ cd Test-a
787 $ cd Test-a
788 $ cat <<EOF >> .hg/hgrc
788 $ cat <<EOF >> .hg/hgrc
789 > [paths]
789 > [paths]
790 > default = ../Test
790 > default = ../Test
791 > EOF
791 > EOF
792 $ hg incoming
792 $ hg incoming
793 comparing with $TESTTMP/Test
793 comparing with $TESTTMP/Test
794 searching for changes
794 searching for changes
795 changeset: 2:bb948857c743
795 changeset: 2:bb948857c743
796 tag: tip
796 tag: tip
797 user: User Name <user@example.com>
797 user: User Name <user@example.com>
798 date: Thu Jan 01 00:00:02 1970 +0000
798 date: Thu Jan 01 00:00:02 1970 +0000
799 summary: firstline
799 summary: firstline
800
800
801 Imported patch should not be rejected
801 Imported patch should not be rejected
802
802
803 $ python -c \
803 $ python -c \
804 > 'import re; s=re.sub("(Id.*)","\\1 rejecttest",open("a").read()); open("a","wb").write(s);'
804 > 'import re; s=re.sub("(Id.*)","\\1 rejecttest",open("a").read()); open("a","wb").write(s);'
805 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
805 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
806 a
806 a
807 overwriting a expanding keywords
807 overwriting a expanding keywords
808 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
808 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
809 $ hg export -o ../rejecttest.diff tip
809 $ hg export -o ../rejecttest.diff tip
810 $ cd ../Test
810 $ cd ../Test
811 $ hg import ../rejecttest.diff
811 $ hg import ../rejecttest.diff
812 applying ../rejecttest.diff
812 applying ../rejecttest.diff
813 $ cat a b
813 $ cat a b
814 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
814 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
815 do not process $Id: rejecttest
815 do not process $Id: rejecttest
816 xxx $
816 xxx $
817 $Xinfo: User Name <user@example.com>: rejects? $
817 $Xinfo: User Name <user@example.com>: rejects? $
818 ignore $Id$
818 ignore $Id$
819
819
820 $ hg rollback
820 $ hg rollback
821 repository tip rolled back to revision 2 (undo commit)
821 repository tip rolled back to revision 2 (undo commit)
822 working directory now based on revision 2
822 working directory now based on revision 2
823 $ hg update --clean
823 $ hg update --clean
824 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
825
825
826 kwexpand/kwshrink on selected files
826 kwexpand/kwshrink on selected files
827
827
828 $ mkdir x
828 $ mkdir x
829 $ hg copy a x/a
829 $ hg copy a x/a
830 $ hg --verbose kwshrink a
830 $ hg --verbose kwshrink a
831 overwriting a shrinking keywords
831 overwriting a shrinking keywords
832 $ hg status a
832 $ hg status a
833 $ hg --verbose kwexpand a
833 $ hg --verbose kwexpand a
834 overwriting a expanding keywords
834 overwriting a expanding keywords
835 $ hg status a
835 $ hg status a
836
836
837 kwexpand x/a should abort
837 kwexpand x/a should abort
838
838
839 $ hg --verbose kwexpand x/a
839 $ hg --verbose kwexpand x/a
840 abort: outstanding uncommitted changes
840 abort: outstanding uncommitted changes
841 [255]
841 [255]
842 $ cd x
842 $ cd x
843 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
843 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
844 x/a
844 x/a
845 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
845 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
846 overwriting x/a expanding keywords
846 overwriting x/a expanding keywords
847 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
847 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
848 $ cat a
848 $ cat a
849 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
849 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
850 do not process $Id:
850 do not process $Id:
851 xxx $
851 xxx $
852 $Xinfo: User Name <user@example.com>: xa $
852 $Xinfo: User Name <user@example.com>: xa $
853
853
854 kwshrink a inside directory x
854 kwshrink a inside directory x
855
855
856 $ hg --verbose kwshrink a
856 $ hg --verbose kwshrink a
857 overwriting x/a shrinking keywords
857 overwriting x/a shrinking keywords
858 $ cat a
858 $ cat a
859 expand $Id$
859 expand $Id$
860 do not process $Id:
860 do not process $Id:
861 xxx $
861 xxx $
862 $Xinfo$
862 $Xinfo$
863 $ cd ..
863 $ cd ..
864
864
865 kwexpand nonexistent
865 kwexpand nonexistent
866
866
867 $ hg kwexpand nonexistent
867 $ hg kwexpand nonexistent
868 nonexistent:* (glob)
868 nonexistent:* (glob)
869
869
870
870
871 hg serve
871 hg serve
872 - expand with hgweb file
872 - expand with hgweb file
873 - no expansion with hgweb annotate/changeset/filediff
873 - no expansion with hgweb annotate/changeset/filediff
874 - check errors
874 - check errors
875
875
876 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
876 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
877 $ cat hg.pid >> $DAEMON_PIDS
877 $ cat hg.pid >> $DAEMON_PIDS
878 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
878 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
879 200 Script output follows
879 200 Script output follows
880
880
881 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
881 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
882 do not process $Id:
882 do not process $Id:
883 xxx $
883 xxx $
884 $Xinfo: User Name <user@example.com>: firstline $
884 $Xinfo: User Name <user@example.com>: firstline $
885 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
885 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
886 200 Script output follows
886 200 Script output follows
887
887
888
888
889 user@1: expand $Id$
889 user@1: expand $Id$
890 user@1: do not process $Id:
890 user@1: do not process $Id:
891 user@1: xxx $
891 user@1: xxx $
892 user@2: $Xinfo$
892 user@2: $Xinfo$
893
893
894
894
895
895
896
896
897 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
897 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
898 200 Script output follows
898 200 Script output follows
899
899
900
900
901 # HG changeset patch
901 # HG changeset patch
902 # User User Name <user@example.com>
902 # User User Name <user@example.com>
903 # Date 3 0
903 # Date 3 0
904 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
904 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
905 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
905 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
906 xa
906 xa
907
907
908 diff -r bb948857c743 -r b4560182a3f9 x/a
908 diff -r bb948857c743 -r b4560182a3f9 x/a
909 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
909 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
910 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
910 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
911 @@ -0,0 +1,4 @@
911 @@ -0,0 +1,4 @@
912 +expand $Id$
912 +expand $Id$
913 +do not process $Id:
913 +do not process $Id:
914 +xxx $
914 +xxx $
915 +$Xinfo$
915 +$Xinfo$
916
916
917 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
917 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
918 200 Script output follows
918 200 Script output follows
919
919
920
920
921 diff -r ef63ca68695b -r bb948857c743 a
921 diff -r ef63ca68695b -r bb948857c743 a
922 --- a/a Thu Jan 01 00:00:00 1970 +0000
922 --- a/a Thu Jan 01 00:00:00 1970 +0000
923 +++ b/a Thu Jan 01 00:00:02 1970 +0000
923 +++ b/a Thu Jan 01 00:00:02 1970 +0000
924 @@ -1,3 +1,4 @@
924 @@ -1,3 +1,4 @@
925 expand $Id$
925 expand $Id$
926 do not process $Id:
926 do not process $Id:
927 xxx $
927 xxx $
928 +$Xinfo$
928 +$Xinfo$
929
929
930
930
931
931
932
932
933 $ cat errors.log
933 $ cat errors.log
934
934
935 Prepare merge and resolve tests
935 Prepare merge and resolve tests
936
936
937 $ echo '$Id$' > m
937 $ echo '$Id$' > m
938 $ hg add m
938 $ hg add m
939 $ hg commit -m 4kw
939 $ hg commit -m 4kw
940 $ echo foo >> m
940 $ echo foo >> m
941 $ hg commit -m 5foo
941 $ hg commit -m 5foo
942
942
943 simplemerge
943 simplemerge
944
944
945 $ hg update 4
945 $ hg update 4
946 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
946 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
947 $ echo foo >> m
947 $ echo foo >> m
948 $ hg commit -m 6foo
948 $ hg commit -m 6foo
949 created new head
949 created new head
950 $ hg merge
950 $ hg merge
951 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
951 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
952 (branch merge, don't forget to commit)
952 (branch merge, don't forget to commit)
953 $ hg commit -m simplemerge
953 $ hg commit -m simplemerge
954 $ cat m
954 $ cat m
955 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
955 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
956 foo
956 foo
957
957
958 conflict: keyword should stay outside conflict zone
958 conflict: keyword should stay outside conflict zone
959
959
960 $ hg update 4
960 $ hg update 4
961 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
961 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
962 $ echo bar >> m
962 $ echo bar >> m
963 $ hg commit -m 8bar
963 $ hg commit -m 8bar
964 created new head
964 created new head
965 $ hg merge
965 $ hg merge
966 merging m
966 merging m
967 warning: conflicts during merge.
967 warning: conflicts during merge.
968 merging m failed!
968 merging m failed!
969 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
969 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
970 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
970 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
971 [1]
971 [1]
972 $ cat m
972 $ cat m
973 $Id$
973 $Id$
974 <<<<<<< local
974 <<<<<<< local
975 bar
975 bar
976 =======
976 =======
977 foo
977 foo
978 >>>>>>> other
978 >>>>>>> other
979
979
980 resolve to local
980 resolve to local
981
981
982 $ HGMERGE=internal:local hg resolve -a
982 $ HGMERGE=internal:local hg resolve -a
983 $ hg commit -m localresolve
983 $ hg commit -m localresolve
984 $ cat m
984 $ cat m
985 $Id: m 41efa6d38e9b Thu, 01 Jan 1970 00:00:00 +0000 test $
985 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
986 bar
986 bar
987
987
988 Test restricted mode with transplant -b
988 Test restricted mode with transplant -b
989
989
990 $ hg update 6
990 $ hg update 6
991 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
991 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
992 $ hg branch foo
992 $ hg branch foo
993 marked working directory as branch foo
993 marked working directory as branch foo
994 $ mv a a.bak
994 $ mv a a.bak
995 $ echo foobranch > a
995 $ echo foobranch > a
996 $ cat a.bak >> a
996 $ cat a.bak >> a
997 $ rm a.bak
997 $ rm a.bak
998 $ hg commit -m 9foobranch
998 $ hg commit -m 9foobranch
999 $ hg update default
999 $ hg update default
1000 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1001 $ hg -y transplant -b foo tip
1001 $ hg -y transplant -b foo tip
1002 applying 4aa30d025d50
1002 applying 4aa30d025d50
1003 4aa30d025d50 transplanted to 5a4da427c162
1003 4aa30d025d50 transplanted to e00abbf63521
1004
1004
1005 Expansion in changeset but not in file
1005 Expansion in changeset but not in file
1006
1006
1007 $ hg tip -p
1007 $ hg tip -p
1008 changeset: 11:5a4da427c162
1008 changeset: 11:e00abbf63521
1009 tag: tip
1009 tag: tip
1010 parent: 9:41efa6d38e9b
1010 parent: 9:800511b3a22d
1011 user: test
1011 user: test
1012 date: Thu Jan 01 00:00:00 1970 +0000
1012 date: Thu Jan 01 00:00:00 1970 +0000
1013 summary: 9foobranch
1013 summary: 9foobranch
1014
1014
1015 diff -r 41efa6d38e9b -r 5a4da427c162 a
1015 diff -r 800511b3a22d -r e00abbf63521 a
1016 --- a/a Thu Jan 01 00:00:00 1970 +0000
1016 --- a/a Thu Jan 01 00:00:00 1970 +0000
1017 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1017 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1018 @@ -1,3 +1,4 @@
1018 @@ -1,3 +1,4 @@
1019 +foobranch
1019 +foobranch
1020 expand $Id$
1020 expand $Id$
1021 do not process $Id:
1021 do not process $Id:
1022 xxx $
1022 xxx $
1023
1023
1024 $ head -n 2 a
1024 $ head -n 2 a
1025 foobranch
1025 foobranch
1026 expand $Id: a 5a4da427c162 Thu, 01 Jan 1970 00:00:00 +0000 test $
1026 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1027
1027
1028 Turn off expansion
1028 Turn off expansion
1029
1029
1030 $ hg -q rollback
1030 $ hg -q rollback
1031 $ hg -q update -C
1031 $ hg -q update -C
1032
1032
1033 kwshrink with unknown file u
1033 kwshrink with unknown file u
1034
1034
1035 $ cp a u
1035 $ cp a u
1036 $ hg --verbose kwshrink
1036 $ hg --verbose kwshrink
1037 overwriting a shrinking keywords
1037 overwriting a shrinking keywords
1038 overwriting m shrinking keywords
1038 overwriting m shrinking keywords
1039 overwriting x/a shrinking keywords
1039 overwriting x/a shrinking keywords
1040
1040
1041 Keywords shrunk in working directory, but not yet disabled
1041 Keywords shrunk in working directory, but not yet disabled
1042 - cat shows unexpanded keywords
1042 - cat shows unexpanded keywords
1043 - hg cat shows expanded keywords
1043 - hg cat shows expanded keywords
1044
1044
1045 $ cat a b
1045 $ cat a b
1046 expand $Id$
1046 expand $Id$
1047 do not process $Id:
1047 do not process $Id:
1048 xxx $
1048 xxx $
1049 $Xinfo$
1049 $Xinfo$
1050 ignore $Id$
1050 ignore $Id$
1051 $ hg cat sym a b && echo
1051 $ hg cat sym a b && echo
1052 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1052 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1053 do not process $Id:
1053 do not process $Id:
1054 xxx $
1054 xxx $
1055 $Xinfo: User Name <user@example.com>: firstline $
1055 $Xinfo: User Name <user@example.com>: firstline $
1056 ignore $Id$
1056 ignore $Id$
1057 a
1057 a
1058
1058
1059 Now disable keyword expansion
1059 Now disable keyword expansion
1060
1060
1061 $ rm "$HGRCPATH"
1061 $ rm "$HGRCPATH"
1062 $ cat a b
1062 $ cat a b
1063 expand $Id$
1063 expand $Id$
1064 do not process $Id:
1064 do not process $Id:
1065 xxx $
1065 xxx $
1066 $Xinfo$
1066 $Xinfo$
1067 ignore $Id$
1067 ignore $Id$
1068 $ hg cat sym a b && echo
1068 $ hg cat sym a b && echo
1069 expand $Id$
1069 expand $Id$
1070 do not process $Id:
1070 do not process $Id:
1071 xxx $
1071 xxx $
1072 $Xinfo$
1072 $Xinfo$
1073 ignore $Id$
1073 ignore $Id$
1074 a
1074 a
@@ -1,194 +1,194
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "mq=" >> $HGRCPATH
2 $ echo "mq=" >> $HGRCPATH
3
3
4 $ hg init a
4 $ hg init a
5 $ cd a
5 $ cd a
6
6
7 $ echo 'base' > base
7 $ echo 'base' > base
8 $ hg ci -Ambase -d '1 0'
8 $ hg ci -Ambase -d '1 0'
9 adding base
9 adding base
10
10
11 $ hg qnew -d '1 0' a
11 $ hg qnew -d '1 0' pa
12 $ hg qnew -d '1 0' b
12 $ hg qnew -d '1 0' pb
13 $ hg qnew -d '1 0' c
13 $ hg qnew -d '1 0' pc
14
14
15 $ hg qdel
15 $ hg qdel
16 abort: qdelete requires at least one revision or patch name
16 abort: qdelete requires at least one revision or patch name
17 [255]
17 [255]
18
18
19 $ hg qdel c
19 $ hg qdel pc
20 abort: cannot delete applied patch c
20 abort: cannot delete applied patch pc
21 [255]
21 [255]
22
22
23 $ hg qpop
23 $ hg qpop
24 popping c
24 popping pc
25 now at: b
25 now at: pb
26
26
27 Delete the same patch twice in one command (issue2427)
27 Delete the same patch twice in one command (issue2427)
28
28
29 $ hg qdel c c
29 $ hg qdel pc pc
30
30
31 $ hg qseries
31 $ hg qseries
32 a
32 pa
33 b
33 pb
34
34
35 $ ls .hg/patches
35 $ ls .hg/patches
36 a
36 pa
37 b
37 pb
38 series
38 series
39 status
39 status
40
40
41 $ hg qpop
41 $ hg qpop
42 popping b
42 popping pb
43 now at: a
43 now at: pa
44
44
45 $ hg qdel -k 1
45 $ hg qdel -k 1
46
46
47 $ ls .hg/patches
47 $ ls .hg/patches
48 a
48 pa
49 b
49 pb
50 series
50 series
51 status
51 status
52
52
53 $ hg qdel -r a
53 $ hg qdel -r pa
54 patch a finalized without changeset message
54 patch pa finalized without changeset message
55
55
56 $ hg qapplied
56 $ hg qapplied
57
57
58 $ hg log --template '{rev} {desc}\n'
58 $ hg log --template '{rev} {desc}\n'
59 1 [mq]: a
59 1 [mq]: pa
60 0 base
60 0 base
61
61
62 $ hg qnew d
62 $ hg qnew pd
63 $ hg qnew e
63 $ hg qnew pe
64 $ hg qnew f
64 $ hg qnew pf
65
65
66 $ hg qdel -r e
66 $ hg qdel -r pe
67 abort: cannot delete revision 3 above applied patches
67 abort: cannot delete revision 3 above applied patches
68 [255]
68 [255]
69
69
70 $ hg qdel -r qbase:e
70 $ hg qdel -r qbase:pe
71 patch d finalized without changeset message
71 patch pd finalized without changeset message
72 patch e finalized without changeset message
72 patch pe finalized without changeset message
73
73
74 $ hg qapplied
74 $ hg qapplied
75 f
75 pf
76
76
77 $ hg log --template '{rev} {desc}\n'
77 $ hg log --template '{rev} {desc}\n'
78 4 [mq]: f
78 4 [mq]: pf
79 3 [mq]: e
79 3 [mq]: pe
80 2 [mq]: d
80 2 [mq]: pd
81 1 [mq]: a
81 1 [mq]: pa
82 0 base
82 0 base
83
83
84 $ cd ..
84 $ cd ..
85
85
86 $ hg init b
86 $ hg init b
87 $ cd b
87 $ cd b
88
88
89 $ echo 'base' > base
89 $ echo 'base' > base
90 $ hg ci -Ambase -d '1 0'
90 $ hg ci -Ambase -d '1 0'
91 adding base
91 adding base
92
92
93 $ hg qfinish
93 $ hg qfinish
94 abort: no revisions specified
94 abort: no revisions specified
95 [255]
95 [255]
96
96
97 $ hg qfinish -a
97 $ hg qfinish -a
98 no patches applied
98 no patches applied
99
99
100 $ hg qnew -d '1 0' a
100 $ hg qnew -d '1 0' pa
101 $ hg qnew -d '1 0' b
101 $ hg qnew -d '1 0' pb
102 $ hg qnew c # XXX fails to apply by /usr/bin/patch if we put a date
102 $ hg qnew pc # XXX fails to apply by /usr/bin/patch if we put a date
103
103
104 $ hg qfinish 0
104 $ hg qfinish 0
105 abort: revision 0 is not managed
105 abort: revision 0 is not managed
106 [255]
106 [255]
107
107
108 $ hg qfinish b
108 $ hg qfinish pb
109 abort: cannot delete revision 2 above applied patches
109 abort: cannot delete revision 2 above applied patches
110 [255]
110 [255]
111
111
112 $ hg qpop
112 $ hg qpop
113 popping c
113 popping pc
114 now at: b
114 now at: pb
115
115
116 $ hg qfinish -a c
116 $ hg qfinish -a pc
117 abort: unknown revision 'c'!
117 abort: unknown revision 'pc'!
118 [255]
118 [255]
119
119
120 $ hg qpush
120 $ hg qpush
121 applying c
121 applying pc
122 patch c is empty
122 patch pc is empty
123 now at: c
123 now at: pc
124
124
125 $ hg qfinish qbase:b
125 $ hg qfinish qbase:pb
126 patch a finalized without changeset message
126 patch pa finalized without changeset message
127 patch b finalized without changeset message
127 patch pb finalized without changeset message
128
128
129 $ hg qapplied
129 $ hg qapplied
130 c
130 pc
131
131
132 $ hg log --template '{rev} {desc}\n'
132 $ hg log --template '{rev} {desc}\n'
133 3 imported patch c
133 3 imported patch pc
134 2 [mq]: b
134 2 [mq]: pb
135 1 [mq]: a
135 1 [mq]: pa
136 0 base
136 0 base
137
137
138 $ hg qfinish -a c
138 $ hg qfinish -a pc
139 patch c finalized without changeset message
139 patch pc finalized without changeset message
140
140
141 $ hg qapplied
141 $ hg qapplied
142
142
143 $ hg log --template '{rev} {desc}\n'
143 $ hg log --template '{rev} {desc}\n'
144 3 imported patch c
144 3 imported patch pc
145 2 [mq]: b
145 2 [mq]: pb
146 1 [mq]: a
146 1 [mq]: pa
147 0 base
147 0 base
148
148
149 $ ls .hg/patches
149 $ ls .hg/patches
150 series
150 series
151 status
151 status
152
152
153 qdel -k X && hg qimp -e X used to trigger spurious output with versioned queues
153 qdel -k X && hg qimp -e X used to trigger spurious output with versioned queues
154
154
155 $ hg init --mq
155 $ hg init --mq
156 $ hg qimport -r 3
156 $ hg qimport -r 3
157 $ hg qpop
157 $ hg qpop
158 popping 3.diff
158 popping 3.diff
159 patch queue now empty
159 patch queue now empty
160 $ hg qdel -k 3.diff
160 $ hg qdel -k 3.diff
161 $ hg qimp -e 3.diff
161 $ hg qimp -e 3.diff
162 adding 3.diff to series file
162 adding 3.diff to series file
163 $ hg qfinish -a
163 $ hg qfinish -a
164 no patches applied
164 no patches applied
165
165
166
166
167 resilience to inconsistency: qfinish -a with applied patches not in series
167 resilience to inconsistency: qfinish -a with applied patches not in series
168
168
169 $ hg qser
169 $ hg qser
170 3.diff
170 3.diff
171 $ hg qapplied
171 $ hg qapplied
172 $ hg qpush
172 $ hg qpush
173 applying 3.diff
173 applying 3.diff
174 patch 3.diff is empty
174 patch 3.diff is empty
175 now at: 3.diff
175 now at: 3.diff
176 $ echo next >> base
176 $ echo next >> base
177 $ hg qrefresh -d '1 0'
177 $ hg qrefresh -d '1 0'
178 $ echo > .hg/patches/series # remove 3.diff from series to confuse mq
178 $ echo > .hg/patches/series # remove 3.diff from series to confuse mq
179 $ hg qfinish -a
179 $ hg qfinish -a
180 revision c4dd2b624061 refers to unknown patches: 3.diff
180 revision 47dfa8501675 refers to unknown patches: 3.diff
181
181
182 more complex state 'both known and unknown patches
182 more complex state 'both known and unknown patches
183
183
184 $ echo hip >> base
184 $ echo hip >> base
185 $ hg qnew -f -d '1 0' -m 4 4.diff
185 $ hg qnew -f -d '1 0' -m 4 4.diff
186 $ echo hop >> base
186 $ echo hop >> base
187 $ hg qnew -f -d '1 0' -m 5 5.diff
187 $ hg qnew -f -d '1 0' -m 5 5.diff
188 $ echo > .hg/patches/series # remove 4.diff and 5.diff from series to confuse mq
188 $ echo > .hg/patches/series # remove 4.diff and 5.diff from series to confuse mq
189 $ echo hup >> base
189 $ echo hup >> base
190 $ hg qnew -f -d '1 0' -m 6 6.diff
190 $ hg qnew -f -d '1 0' -m 6 6.diff
191 $ hg qfinish -a
191 $ hg qfinish -a
192 revision 6fdec4b20ec3 refers to unknown patches: 5.diff
192 revision 2b1c98802260 refers to unknown patches: 5.diff
193 revision 2ba51db7ba24 refers to unknown patches: 4.diff
193 revision 33a6861311c0 refers to unknown patches: 4.diff
194
194
@@ -1,1387 +1,1387
1 $ checkundo()
1 $ checkundo()
2 > {
2 > {
3 > if [ -f .hg/store/undo ]; then
3 > if [ -f .hg/store/undo ]; then
4 > echo ".hg/store/undo still exists after $1"
4 > echo ".hg/store/undo still exists after $1"
5 > fi
5 > fi
6 > }
6 > }
7
7
8 $ echo "[extensions]" >> $HGRCPATH
8 $ echo "[extensions]" >> $HGRCPATH
9 $ echo "mq=" >> $HGRCPATH
9 $ echo "mq=" >> $HGRCPATH
10
10
11 $ echo "[mq]" >> $HGRCPATH
11 $ echo "[mq]" >> $HGRCPATH
12 $ echo "plain=true" >> $HGRCPATH
12 $ echo "plain=true" >> $HGRCPATH
13
13
14
14
15 help
15 help
16
16
17 $ hg help mq
17 $ hg help mq
18 mq extension - manage a stack of patches
18 mq extension - manage a stack of patches
19
19
20 This extension lets you work with a stack of patches in a Mercurial
20 This extension lets you work with a stack of patches in a Mercurial
21 repository. It manages two stacks of patches - all known patches, and applied
21 repository. It manages two stacks of patches - all known patches, and applied
22 patches (subset of known patches).
22 patches (subset of known patches).
23
23
24 Known patches are represented as patch files in the .hg/patches directory.
24 Known patches are represented as patch files in the .hg/patches directory.
25 Applied patches are both patch files and changesets.
25 Applied patches are both patch files and changesets.
26
26
27 Common tasks (use "hg help command" for more details):
27 Common tasks (use "hg help command" for more details):
28
28
29 create new patch qnew
29 create new patch qnew
30 import existing patch qimport
30 import existing patch qimport
31
31
32 print patch series qseries
32 print patch series qseries
33 print applied patches qapplied
33 print applied patches qapplied
34
34
35 add known patch to applied stack qpush
35 add known patch to applied stack qpush
36 remove patch from applied stack qpop
36 remove patch from applied stack qpop
37 refresh contents of top applied patch qrefresh
37 refresh contents of top applied patch qrefresh
38
38
39 By default, mq will automatically use git patches when required to avoid
39 By default, mq will automatically use git patches when required to avoid
40 losing file mode changes, copy records, binary files or empty files creations
40 losing file mode changes, copy records, binary files or empty files creations
41 or deletions. This behaviour can be configured with:
41 or deletions. This behaviour can be configured with:
42
42
43 [mq]
43 [mq]
44 git = auto/keep/yes/no
44 git = auto/keep/yes/no
45
45
46 If set to 'keep', mq will obey the [diff] section configuration while
46 If set to 'keep', mq will obey the [diff] section configuration while
47 preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
47 preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
48 will override the [diff] section and always generate git or regular patches,
48 will override the [diff] section and always generate git or regular patches,
49 possibly losing data in the second case.
49 possibly losing data in the second case.
50
50
51 You will by default be managing a patch queue named "patches". You can create
51 You will by default be managing a patch queue named "patches". You can create
52 other, independent patch queues with the "hg qqueue" command.
52 other, independent patch queues with the "hg qqueue" command.
53
53
54 list of commands:
54 list of commands:
55
55
56 qapplied print the patches already applied
56 qapplied print the patches already applied
57 qclone clone main and patch repository at same time
57 qclone clone main and patch repository at same time
58 qdelete remove patches from queue
58 qdelete remove patches from queue
59 qdiff diff of the current patch and subsequent modifications
59 qdiff diff of the current patch and subsequent modifications
60 qfinish move applied patches into repository history
60 qfinish move applied patches into repository history
61 qfold fold the named patches into the current patch
61 qfold fold the named patches into the current patch
62 qgoto push or pop patches until named patch is at top of stack
62 qgoto push or pop patches until named patch is at top of stack
63 qguard set or print guards for a patch
63 qguard set or print guards for a patch
64 qheader print the header of the topmost or specified patch
64 qheader print the header of the topmost or specified patch
65 qimport import a patch
65 qimport import a patch
66 qnew create a new patch
66 qnew create a new patch
67 qnext print the name of the next patch
67 qnext print the name of the next patch
68 qpop pop the current patch off the stack
68 qpop pop the current patch off the stack
69 qprev print the name of the previous patch
69 qprev print the name of the previous patch
70 qpush push the next patch onto the stack
70 qpush push the next patch onto the stack
71 qqueue manage multiple patch queues
71 qqueue manage multiple patch queues
72 qrefresh update the current patch
72 qrefresh update the current patch
73 qrename rename a patch
73 qrename rename a patch
74 qselect set or print guarded patches to push
74 qselect set or print guarded patches to push
75 qseries print the entire series file
75 qseries print the entire series file
76 qtop print the name of the current patch
76 qtop print the name of the current patch
77 qunapplied print the patches not yet applied
77 qunapplied print the patches not yet applied
78 strip strip changesets and all their descendants from the repository
78 strip strip changesets and all their descendants from the repository
79
79
80 use "hg -v help mq" to show builtin aliases and global options
80 use "hg -v help mq" to show builtin aliases and global options
81
81
82 $ hg init a
82 $ hg init a
83 $ cd a
83 $ cd a
84 $ echo a > a
84 $ echo a > a
85 $ hg ci -Ama
85 $ hg ci -Ama
86 adding a
86 adding a
87
87
88 $ hg clone . ../k
88 $ hg clone . ../k
89 updating to branch default
89 updating to branch default
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91
91
92 $ mkdir b
92 $ mkdir b
93 $ echo z > b/z
93 $ echo z > b/z
94 $ hg ci -Ama
94 $ hg ci -Ama
95 adding b/z
95 adding b/z
96
96
97
97
98 qinit
98 qinit
99
99
100 $ hg qinit
100 $ hg qinit
101
101
102 $ cd ..
102 $ cd ..
103 $ hg init b
103 $ hg init b
104
104
105
105
106 -R qinit
106 -R qinit
107
107
108 $ hg -R b qinit
108 $ hg -R b qinit
109
109
110 $ hg init c
110 $ hg init c
111
111
112
112
113 qinit -c
113 qinit -c
114
114
115 $ hg --cwd c qinit -c
115 $ hg --cwd c qinit -c
116 $ hg -R c/.hg/patches st
116 $ hg -R c/.hg/patches st
117 A .hgignore
117 A .hgignore
118 A series
118 A series
119
119
120
120
121 qinit; qinit -c
121 qinit; qinit -c
122
122
123 $ hg init d
123 $ hg init d
124 $ cd d
124 $ cd d
125 $ hg qinit
125 $ hg qinit
126 $ hg qinit -c
126 $ hg qinit -c
127
127
128 qinit -c should create both files if they don't exist
128 qinit -c should create both files if they don't exist
129
129
130 $ cat .hg/patches/.hgignore
130 $ cat .hg/patches/.hgignore
131 ^\.hg
131 ^\.hg
132 ^\.mq
132 ^\.mq
133 syntax: glob
133 syntax: glob
134 status
134 status
135 guards
135 guards
136 $ cat .hg/patches/series
136 $ cat .hg/patches/series
137 $ hg qinit -c
137 $ hg qinit -c
138 abort: repository $TESTTMP/d/.hg/patches already exists!
138 abort: repository $TESTTMP/d/.hg/patches already exists!
139 [255]
139 [255]
140 $ cd ..
140 $ cd ..
141
141
142 $ echo '% qinit; <stuff>; qinit -c'
142 $ echo '% qinit; <stuff>; qinit -c'
143 % qinit; <stuff>; qinit -c
143 % qinit; <stuff>; qinit -c
144 $ hg init e
144 $ hg init e
145 $ cd e
145 $ cd e
146 $ hg qnew A
146 $ hg qnew A
147 $ checkundo qnew
147 $ checkundo qnew
148 $ echo foo > foo
148 $ echo foo > foo
149 $ hg add foo
149 $ hg add foo
150 $ hg qrefresh
150 $ hg qrefresh
151 $ hg qnew B
151 $ hg qnew B
152 $ echo >> foo
152 $ echo >> foo
153 $ hg qrefresh
153 $ hg qrefresh
154 $ echo status >> .hg/patches/.hgignore
154 $ echo status >> .hg/patches/.hgignore
155 $ echo bleh >> .hg/patches/.hgignore
155 $ echo bleh >> .hg/patches/.hgignore
156 $ hg qinit -c
156 $ hg qinit -c
157 adding .hg/patches/A
157 adding .hg/patches/A
158 adding .hg/patches/B
158 adding .hg/patches/B
159 $ hg -R .hg/patches status
159 $ hg -R .hg/patches status
160 A .hgignore
160 A .hgignore
161 A A
161 A A
162 A B
162 A B
163 A series
163 A series
164
164
165 qinit -c shouldn't touch these files if they already exist
165 qinit -c shouldn't touch these files if they already exist
166
166
167 $ cat .hg/patches/.hgignore
167 $ cat .hg/patches/.hgignore
168 status
168 status
169 bleh
169 bleh
170 $ cat .hg/patches/series
170 $ cat .hg/patches/series
171 A
171 A
172 B
172 B
173
173
174 add an untracked file
174 add an untracked file
175
175
176 $ echo >> .hg/patches/flaf
176 $ echo >> .hg/patches/flaf
177
177
178 status --mq with color (issue2096)
178 status --mq with color (issue2096)
179
179
180 $ hg status --mq --config extensions.color= --config color.mode=ansi --color=always
180 $ hg status --mq --config extensions.color= --config color.mode=ansi --color=always
181 \x1b[0;32;1mA .hgignore\x1b[0m (esc)
181 \x1b[0;32;1mA .hgignore\x1b[0m (esc)
182 \x1b[0;32;1mA A\x1b[0m (esc)
182 \x1b[0;32;1mA A\x1b[0m (esc)
183 \x1b[0;32;1mA B\x1b[0m (esc)
183 \x1b[0;32;1mA B\x1b[0m (esc)
184 \x1b[0;32;1mA series\x1b[0m (esc)
184 \x1b[0;32;1mA series\x1b[0m (esc)
185 \x1b[0;35;1;4m? flaf\x1b[0m (esc)
185 \x1b[0;35;1;4m? flaf\x1b[0m (esc)
186
186
187 try the --mq option on a command provided by an extension
187 try the --mq option on a command provided by an extension
188
188
189 $ hg purge --mq --verbose --config extensions.purge=
189 $ hg purge --mq --verbose --config extensions.purge=
190 Removing file flaf
190 Removing file flaf
191
191
192 $ cd ..
192 $ cd ..
193
193
194 init --mq without repo
194 init --mq without repo
195
195
196 $ mkdir f
196 $ mkdir f
197 $ cd f
197 $ cd f
198 $ hg init --mq
198 $ hg init --mq
199 abort: there is no Mercurial repository here (.hg not found)
199 abort: there is no Mercurial repository here (.hg not found)
200 [255]
200 [255]
201 $ cd ..
201 $ cd ..
202
202
203 init --mq with repo path
203 init --mq with repo path
204
204
205 $ hg init g
205 $ hg init g
206 $ hg init --mq g
206 $ hg init --mq g
207 $ test -d g/.hg/patches/.hg
207 $ test -d g/.hg/patches/.hg
208
208
209 init --mq with nonexistent directory
209 init --mq with nonexistent directory
210
210
211 $ hg init --mq nonexistentdir
211 $ hg init --mq nonexistentdir
212 abort: repository nonexistentdir not found!
212 abort: repository nonexistentdir not found!
213 [255]
213 [255]
214
214
215
215
216 init --mq with bundle (non "local")
216 init --mq with bundle (non "local")
217
217
218 $ hg -R a bundle --all a.bundle >/dev/null
218 $ hg -R a bundle --all a.bundle >/dev/null
219 $ hg init --mq a.bundle
219 $ hg init --mq a.bundle
220 abort: only a local queue repository may be initialized
220 abort: only a local queue repository may be initialized
221 [255]
221 [255]
222
222
223 $ cd a
223 $ cd a
224
224
225 $ hg qnew -m 'foo bar' test.patch
225 $ hg qnew -m 'foo bar' test.patch
226
226
227 $ echo '# comment' > .hg/patches/series.tmp
227 $ echo '# comment' > .hg/patches/series.tmp
228 $ echo >> .hg/patches/series.tmp # empty line
228 $ echo >> .hg/patches/series.tmp # empty line
229 $ cat .hg/patches/series >> .hg/patches/series.tmp
229 $ cat .hg/patches/series >> .hg/patches/series.tmp
230 $ mv .hg/patches/series.tmp .hg/patches/series
230 $ mv .hg/patches/series.tmp .hg/patches/series
231
231
232
232
233 qrefresh
233 qrefresh
234
234
235 $ echo a >> a
235 $ echo a >> a
236 $ hg qrefresh
236 $ hg qrefresh
237 $ cat .hg/patches/test.patch
237 $ cat .hg/patches/test.patch
238 foo bar
238 foo bar
239
239
240 diff -r [a-f0-9]* a (re)
240 diff -r [a-f0-9]* a (re)
241 --- a/a\t(?P<date>.*) (re)
241 --- a/a\t(?P<date>.*) (re)
242 \+\+\+ b/a\t(?P<date2>.*) (re)
242 \+\+\+ b/a\t(?P<date2>.*) (re)
243 @@ -1,1 +1,2 @@
243 @@ -1,1 +1,2 @@
244 a
244 a
245 +a
245 +a
246
246
247 empty qrefresh
247 empty qrefresh
248
248
249 $ hg qrefresh -X a
249 $ hg qrefresh -X a
250
250
251 revision:
251 revision:
252
252
253 $ hg diff -r -2 -r -1
253 $ hg diff -r -2 -r -1
254
254
255 patch:
255 patch:
256
256
257 $ cat .hg/patches/test.patch
257 $ cat .hg/patches/test.patch
258 foo bar
258 foo bar
259
259
260
260
261 working dir diff:
261 working dir diff:
262
262
263 $ hg diff --nodates -q
263 $ hg diff --nodates -q
264 --- a/a
264 --- a/a
265 +++ b/a
265 +++ b/a
266 @@ -1,1 +1,2 @@
266 @@ -1,1 +1,2 @@
267 a
267 a
268 +a
268 +a
269
269
270 restore things
270 restore things
271
271
272 $ hg qrefresh
272 $ hg qrefresh
273 $ checkundo qrefresh
273 $ checkundo qrefresh
274
274
275
275
276 qpop
276 qpop
277
277
278 $ hg qpop
278 $ hg qpop
279 popping test.patch
279 popping test.patch
280 patch queue now empty
280 patch queue now empty
281 $ checkundo qpop
281 $ checkundo qpop
282
282
283
283
284 qpush with dump of tag cache
284 qpush with dump of tag cache
285 Dump the tag cache to ensure that it has exactly one head after qpush.
285 Dump the tag cache to ensure that it has exactly one head after qpush.
286
286
287 $ rm -f .hg/cache/tags
287 $ rm -f .hg/cache/tags
288 $ hg tags > /dev/null
288 $ hg tags > /dev/null
289
289
290 .hg/cache/tags (pre qpush):
290 .hg/cache/tags (pre qpush):
291
291
292 $ cat .hg/cache/tags
292 $ cat .hg/cache/tags
293 1 [\da-f]{40} (re)
293 1 [\da-f]{40} (re)
294
294
295 $ hg qpush
295 $ hg qpush
296 applying test.patch
296 applying test.patch
297 now at: test.patch
297 now at: test.patch
298 $ hg tags > /dev/null
298 $ hg tags > /dev/null
299
299
300 .hg/cache/tags (post qpush):
300 .hg/cache/tags (post qpush):
301
301
302 $ cat .hg/cache/tags
302 $ cat .hg/cache/tags
303 2 [\da-f]{40} (re)
303 2 [\da-f]{40} (re)
304
304
305 $ checkundo qpush
305 $ checkundo qpush
306 $ cd ..
306 $ cd ..
307
307
308
308
309 pop/push outside repo
309 pop/push outside repo
310 $ hg -R a qpop
310 $ hg -R a qpop
311 popping test.patch
311 popping test.patch
312 patch queue now empty
312 patch queue now empty
313 $ hg -R a qpush
313 $ hg -R a qpush
314 applying test.patch
314 applying test.patch
315 now at: test.patch
315 now at: test.patch
316
316
317 $ cd a
317 $ cd a
318 $ hg qnew test2.patch
318 $ hg qnew test2.patch
319
319
320 qrefresh in subdir
320 qrefresh in subdir
321
321
322 $ cd b
322 $ cd b
323 $ echo a > a
323 $ echo a > a
324 $ hg add a
324 $ hg add a
325 $ hg qrefresh
325 $ hg qrefresh
326
326
327 pop/push -a in subdir
327 pop/push -a in subdir
328
328
329 $ hg qpop -a
329 $ hg qpop -a
330 popping test2.patch
330 popping test2.patch
331 popping test.patch
331 popping test.patch
332 patch queue now empty
332 patch queue now empty
333 $ hg --traceback qpush -a
333 $ hg --traceback qpush -a
334 applying test.patch
334 applying test.patch
335 applying test2.patch
335 applying test2.patch
336 now at: test2.patch
336 now at: test2.patch
337
337
338
338
339 setting columns & formatted tests truncating (issue1912)
339 setting columns & formatted tests truncating (issue1912)
340
340
341 $ COLUMNS=4 hg qseries --config ui.formatted=true
341 $ COLUMNS=4 hg qseries --config ui.formatted=true
342 test.patch
342 test.patch
343 test2.patch
343 test2.patch
344 $ COLUMNS=20 hg qseries --config ui.formatted=true -vs
344 $ COLUMNS=20 hg qseries --config ui.formatted=true -vs
345 0 A test.patch: f...
345 0 A test.patch: f...
346 1 A test2.patch:
346 1 A test2.patch:
347 $ hg qpop
347 $ hg qpop
348 popping test2.patch
348 popping test2.patch
349 now at: test.patch
349 now at: test.patch
350 $ hg qseries -vs
350 $ hg qseries -vs
351 0 A test.patch: foo bar
351 0 A test.patch: foo bar
352 1 U test2.patch:
352 1 U test2.patch:
353 $ hg sum | grep mq
353 $ hg sum | grep mq
354 mq: 1 applied, 1 unapplied
354 mq: 1 applied, 1 unapplied
355 $ hg qpush
355 $ hg qpush
356 applying test2.patch
356 applying test2.patch
357 now at: test2.patch
357 now at: test2.patch
358 $ hg sum | grep mq
358 $ hg sum | grep mq
359 mq: 2 applied
359 mq: 2 applied
360 $ hg qapplied
360 $ hg qapplied
361 test.patch
361 test.patch
362 test2.patch
362 test2.patch
363 $ hg qtop
363 $ hg qtop
364 test2.patch
364 test2.patch
365
365
366
366
367 prev
367 prev
368
368
369 $ hg qapp -1
369 $ hg qapp -1
370 test.patch
370 test.patch
371
371
372 next
372 next
373
373
374 $ hg qunapp -1
374 $ hg qunapp -1
375 all patches applied
375 all patches applied
376 [1]
376 [1]
377
377
378 $ hg qpop
378 $ hg qpop
379 popping test2.patch
379 popping test2.patch
380 now at: test.patch
380 now at: test.patch
381
381
382 commit should fail
382 commit should fail
383
383
384 $ hg commit
384 $ hg commit
385 abort: cannot commit over an applied mq patch
385 abort: cannot commit over an applied mq patch
386 [255]
386 [255]
387
387
388 push should fail
388 push should fail
389
389
390 $ hg push ../../k
390 $ hg push ../../k
391 pushing to ../../k
391 pushing to ../../k
392 abort: source has mq patches applied
392 abort: source has mq patches applied
393 [255]
393 [255]
394
394
395
395
396 import should fail
396 import should fail
397
397
398 $ hg st .
398 $ hg st .
399 $ echo foo >> ../a
399 $ echo foo >> ../a
400 $ hg diff > ../../import.diff
400 $ hg diff > ../../import.diff
401 $ hg revert --no-backup ../a
401 $ hg revert --no-backup ../a
402 $ hg import ../../import.diff
402 $ hg import ../../import.diff
403 abort: cannot import over an applied patch
403 abort: cannot import over an applied patch
404 [255]
404 [255]
405 $ hg st
405 $ hg st
406
406
407 import --no-commit should succeed
407 import --no-commit should succeed
408
408
409 $ hg import --no-commit ../../import.diff
409 $ hg import --no-commit ../../import.diff
410 applying ../../import.diff
410 applying ../../import.diff
411 $ hg st
411 $ hg st
412 M a
412 M a
413 $ hg revert --no-backup ../a
413 $ hg revert --no-backup ../a
414
414
415
415
416 qunapplied
416 qunapplied
417
417
418 $ hg qunapplied
418 $ hg qunapplied
419 test2.patch
419 test2.patch
420
420
421
421
422 qpush/qpop with index
422 qpush/qpop with index
423
423
424 $ hg qnew test1b.patch
424 $ hg qnew test1b.patch
425 $ echo 1b > 1b
425 $ echo 1b > 1b
426 $ hg add 1b
426 $ hg add 1b
427 $ hg qrefresh
427 $ hg qrefresh
428 $ hg qpush 2
428 $ hg qpush 2
429 applying test2.patch
429 applying test2.patch
430 now at: test2.patch
430 now at: test2.patch
431 $ hg qpop 0
431 $ hg qpop 0
432 popping test2.patch
432 popping test2.patch
433 popping test1b.patch
433 popping test1b.patch
434 now at: test.patch
434 now at: test.patch
435 $ hg qpush test.patch+1
435 $ hg qpush test.patch+1
436 applying test1b.patch
436 applying test1b.patch
437 now at: test1b.patch
437 now at: test1b.patch
438 $ hg qpush test.patch+2
438 $ hg qpush test.patch+2
439 applying test2.patch
439 applying test2.patch
440 now at: test2.patch
440 now at: test2.patch
441 $ hg qpop test2.patch-1
441 $ hg qpop test2.patch-1
442 popping test2.patch
442 popping test2.patch
443 now at: test1b.patch
443 now at: test1b.patch
444 $ hg qpop test2.patch-2
444 $ hg qpop test2.patch-2
445 popping test1b.patch
445 popping test1b.patch
446 now at: test.patch
446 now at: test.patch
447 $ hg qpush test1b.patch+1
447 $ hg qpush test1b.patch+1
448 applying test1b.patch
448 applying test1b.patch
449 applying test2.patch
449 applying test2.patch
450 now at: test2.patch
450 now at: test2.patch
451
451
452
452
453 qpush --move
453 qpush --move
454
454
455 $ hg qpop -a
455 $ hg qpop -a
456 popping test2.patch
456 popping test2.patch
457 popping test1b.patch
457 popping test1b.patch
458 popping test.patch
458 popping test.patch
459 patch queue now empty
459 patch queue now empty
460 $ hg qguard test1b.patch -- -negguard
460 $ hg qguard test1b.patch -- -negguard
461 $ hg qguard test2.patch -- +posguard
461 $ hg qguard test2.patch -- +posguard
462 $ hg qpush --move test2.patch # can't move guarded patch
462 $ hg qpush --move test2.patch # can't move guarded patch
463 cannot push 'test2.patch' - guarded by ['+posguard']
463 cannot push 'test2.patch' - guarded by ['+posguard']
464 [1]
464 [1]
465 $ hg qselect posguard
465 $ hg qselect posguard
466 number of unguarded, unapplied patches has changed from 2 to 3
466 number of unguarded, unapplied patches has changed from 2 to 3
467 $ hg qpush --move test2.patch # move to front
467 $ hg qpush --move test2.patch # move to front
468 applying test2.patch
468 applying test2.patch
469 now at: test2.patch
469 now at: test2.patch
470 $ hg qpush --move test1b.patch # negative guard unselected
470 $ hg qpush --move test1b.patch # negative guard unselected
471 applying test1b.patch
471 applying test1b.patch
472 now at: test1b.patch
472 now at: test1b.patch
473 $ hg qpush --move test.patch # noop move
473 $ hg qpush --move test.patch # noop move
474 applying test.patch
474 applying test.patch
475 now at: test.patch
475 now at: test.patch
476 $ hg qseries -v
476 $ hg qseries -v
477 0 A test2.patch
477 0 A test2.patch
478 1 A test1b.patch
478 1 A test1b.patch
479 2 A test.patch
479 2 A test.patch
480 $ hg qpop -a
480 $ hg qpop -a
481 popping test.patch
481 popping test.patch
482 popping test1b.patch
482 popping test1b.patch
483 popping test2.patch
483 popping test2.patch
484 patch queue now empty
484 patch queue now empty
485
485
486 cleaning up
486 cleaning up
487
487
488 $ hg qselect --none
488 $ hg qselect --none
489 guards deactivated
489 guards deactivated
490 number of unguarded, unapplied patches has changed from 3 to 2
490 number of unguarded, unapplied patches has changed from 3 to 2
491 $ hg qguard --none test1b.patch
491 $ hg qguard --none test1b.patch
492 $ hg qguard --none test2.patch
492 $ hg qguard --none test2.patch
493 $ hg qpush --move test.patch
493 $ hg qpush --move test.patch
494 applying test.patch
494 applying test.patch
495 now at: test.patch
495 now at: test.patch
496 $ hg qpush --move test1b.patch
496 $ hg qpush --move test1b.patch
497 applying test1b.patch
497 applying test1b.patch
498 now at: test1b.patch
498 now at: test1b.patch
499 $ hg qpush --move bogus # nonexistent patch
499 $ hg qpush --move bogus # nonexistent patch
500 abort: patch bogus not in series
500 abort: patch bogus not in series
501 [255]
501 [255]
502 $ hg qpush --move # no patch
502 $ hg qpush --move # no patch
503 abort: please specify the patch to move
503 abort: please specify the patch to move
504 [255]
504 [255]
505 $ hg qpush --move test.patch # already applied
505 $ hg qpush --move test.patch # already applied
506 abort: cannot push to a previous patch: test.patch
506 abort: cannot push to a previous patch: test.patch
507 [255]
507 [255]
508 $ hg qpush
508 $ hg qpush
509 applying test2.patch
509 applying test2.patch
510 now at: test2.patch
510 now at: test2.patch
511
511
512
512
513 series after move
513 series after move
514
514
515 $ cat `hg root`/.hg/patches/series
515 $ cat `hg root`/.hg/patches/series
516 test.patch
516 test.patch
517 test1b.patch
517 test1b.patch
518 test2.patch
518 test2.patch
519 # comment
519 # comment
520
520
521
521
522
522
523 pop, qapplied, qunapplied
523 pop, qapplied, qunapplied
524
524
525 $ hg qseries -v
525 $ hg qseries -v
526 0 A test.patch
526 0 A test.patch
527 1 A test1b.patch
527 1 A test1b.patch
528 2 A test2.patch
528 2 A test2.patch
529
529
530 qapplied -1 test.patch
530 qapplied -1 test.patch
531
531
532 $ hg qapplied -1 test.patch
532 $ hg qapplied -1 test.patch
533 only one patch applied
533 only one patch applied
534 [1]
534 [1]
535
535
536 qapplied -1 test1b.patch
536 qapplied -1 test1b.patch
537
537
538 $ hg qapplied -1 test1b.patch
538 $ hg qapplied -1 test1b.patch
539 test.patch
539 test.patch
540
540
541 qapplied -1 test2.patch
541 qapplied -1 test2.patch
542
542
543 $ hg qapplied -1 test2.patch
543 $ hg qapplied -1 test2.patch
544 test1b.patch
544 test1b.patch
545
545
546 qapplied -1
546 qapplied -1
547
547
548 $ hg qapplied -1
548 $ hg qapplied -1
549 test1b.patch
549 test1b.patch
550
550
551 qapplied
551 qapplied
552
552
553 $ hg qapplied
553 $ hg qapplied
554 test.patch
554 test.patch
555 test1b.patch
555 test1b.patch
556 test2.patch
556 test2.patch
557
557
558 qapplied test1b.patch
558 qapplied test1b.patch
559
559
560 $ hg qapplied test1b.patch
560 $ hg qapplied test1b.patch
561 test.patch
561 test.patch
562 test1b.patch
562 test1b.patch
563
563
564 qunapplied -1
564 qunapplied -1
565
565
566 $ hg qunapplied -1
566 $ hg qunapplied -1
567 all patches applied
567 all patches applied
568 [1]
568 [1]
569
569
570 qunapplied
570 qunapplied
571
571
572 $ hg qunapplied
572 $ hg qunapplied
573
573
574 popping
574 popping
575
575
576 $ hg qpop
576 $ hg qpop
577 popping test2.patch
577 popping test2.patch
578 now at: test1b.patch
578 now at: test1b.patch
579
579
580 qunapplied -1
580 qunapplied -1
581
581
582 $ hg qunapplied -1
582 $ hg qunapplied -1
583 test2.patch
583 test2.patch
584
584
585 qunapplied
585 qunapplied
586
586
587 $ hg qunapplied
587 $ hg qunapplied
588 test2.patch
588 test2.patch
589
589
590 qunapplied test2.patch
590 qunapplied test2.patch
591
591
592 $ hg qunapplied test2.patch
592 $ hg qunapplied test2.patch
593
593
594 qunapplied -1 test2.patch
594 qunapplied -1 test2.patch
595
595
596 $ hg qunapplied -1 test2.patch
596 $ hg qunapplied -1 test2.patch
597 all patches applied
597 all patches applied
598 [1]
598 [1]
599
599
600 popping -a
600 popping -a
601
601
602 $ hg qpop -a
602 $ hg qpop -a
603 popping test1b.patch
603 popping test1b.patch
604 popping test.patch
604 popping test.patch
605 patch queue now empty
605 patch queue now empty
606
606
607 qapplied
607 qapplied
608
608
609 $ hg qapplied
609 $ hg qapplied
610
610
611 qapplied -1
611 qapplied -1
612
612
613 $ hg qapplied -1
613 $ hg qapplied -1
614 no patches applied
614 no patches applied
615 [1]
615 [1]
616 $ hg qpush
616 $ hg qpush
617 applying test.patch
617 applying test.patch
618 now at: test.patch
618 now at: test.patch
619
619
620
620
621 push should succeed
621 push should succeed
622
622
623 $ hg qpop -a
623 $ hg qpop -a
624 popping test.patch
624 popping test.patch
625 patch queue now empty
625 patch queue now empty
626 $ hg push ../../k
626 $ hg push ../../k
627 pushing to ../../k
627 pushing to ../../k
628 searching for changes
628 searching for changes
629 adding changesets
629 adding changesets
630 adding manifests
630 adding manifests
631 adding file changes
631 adding file changes
632 added 1 changesets with 1 changes to 1 files
632 added 1 changesets with 1 changes to 1 files
633
633
634
634
635 we want to start with some patches applied
635 we want to start with some patches applied
636
636
637 $ hg qpush -a
637 $ hg qpush -a
638 applying test.patch
638 applying test.patch
639 applying test1b.patch
639 applying test1b.patch
640 applying test2.patch
640 applying test2.patch
641 now at: test2.patch
641 now at: test2.patch
642
642
643 % pops all patches and succeeds
643 % pops all patches and succeeds
644
644
645 $ hg qpop -a
645 $ hg qpop -a
646 popping test2.patch
646 popping test2.patch
647 popping test1b.patch
647 popping test1b.patch
648 popping test.patch
648 popping test.patch
649 patch queue now empty
649 patch queue now empty
650
650
651 % does nothing and succeeds
651 % does nothing and succeeds
652
652
653 $ hg qpop -a
653 $ hg qpop -a
654 no patches applied
654 no patches applied
655
655
656 % fails - nothing else to pop
656 % fails - nothing else to pop
657
657
658 $ hg qpop
658 $ hg qpop
659 no patches applied
659 no patches applied
660 [1]
660 [1]
661
661
662 % pushes a patch and succeeds
662 % pushes a patch and succeeds
663
663
664 $ hg qpush
664 $ hg qpush
665 applying test.patch
665 applying test.patch
666 now at: test.patch
666 now at: test.patch
667
667
668 % pops a patch and succeeds
668 % pops a patch and succeeds
669
669
670 $ hg qpop
670 $ hg qpop
671 popping test.patch
671 popping test.patch
672 patch queue now empty
672 patch queue now empty
673
673
674 % pushes up to test1b.patch and succeeds
674 % pushes up to test1b.patch and succeeds
675
675
676 $ hg qpush test1b.patch
676 $ hg qpush test1b.patch
677 applying test.patch
677 applying test.patch
678 applying test1b.patch
678 applying test1b.patch
679 now at: test1b.patch
679 now at: test1b.patch
680
680
681 % does nothing and succeeds
681 % does nothing and succeeds
682
682
683 $ hg qpush test1b.patch
683 $ hg qpush test1b.patch
684 qpush: test1b.patch is already at the top
684 qpush: test1b.patch is already at the top
685
685
686 % does nothing and succeeds
686 % does nothing and succeeds
687
687
688 $ hg qpop test1b.patch
688 $ hg qpop test1b.patch
689 qpop: test1b.patch is already at the top
689 qpop: test1b.patch is already at the top
690
690
691 % fails - can't push to this patch
691 % fails - can't push to this patch
692
692
693 $ hg qpush test.patch
693 $ hg qpush test.patch
694 abort: cannot push to a previous patch: test.patch
694 abort: cannot push to a previous patch: test.patch
695 [255]
695 [255]
696
696
697 % fails - can't pop to this patch
697 % fails - can't pop to this patch
698
698
699 $ hg qpop test2.patch
699 $ hg qpop test2.patch
700 abort: patch test2.patch is not applied
700 abort: patch test2.patch is not applied
701 [255]
701 [255]
702
702
703 % pops up to test.patch and succeeds
703 % pops up to test.patch and succeeds
704
704
705 $ hg qpop test.patch
705 $ hg qpop test.patch
706 popping test1b.patch
706 popping test1b.patch
707 now at: test.patch
707 now at: test.patch
708
708
709 % pushes all patches and succeeds
709 % pushes all patches and succeeds
710
710
711 $ hg qpush -a
711 $ hg qpush -a
712 applying test1b.patch
712 applying test1b.patch
713 applying test2.patch
713 applying test2.patch
714 now at: test2.patch
714 now at: test2.patch
715
715
716 % does nothing and succeeds
716 % does nothing and succeeds
717
717
718 $ hg qpush -a
718 $ hg qpush -a
719 all patches are currently applied
719 all patches are currently applied
720
720
721 % fails - nothing else to push
721 % fails - nothing else to push
722
722
723 $ hg qpush
723 $ hg qpush
724 patch series already fully applied
724 patch series already fully applied
725 [1]
725 [1]
726
726
727 % does nothing and succeeds
727 % does nothing and succeeds
728
728
729 $ hg qpush test2.patch
729 $ hg qpush test2.patch
730 qpush: test2.patch is already at the top
730 qpush: test2.patch is already at the top
731
731
732 strip
732 strip
733
733
734 $ cd ../../b
734 $ cd ../../b
735 $ echo x>x
735 $ echo x>x
736 $ hg ci -Ama
736 $ hg ci -Ama
737 adding x
737 adding x
738 $ hg strip tip
738 $ hg strip tip
739 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
739 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
740 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
740 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
741 $ hg unbundle .hg/strip-backup/*
741 $ hg unbundle .hg/strip-backup/*
742 adding changesets
742 adding changesets
743 adding manifests
743 adding manifests
744 adding file changes
744 adding file changes
745 added 1 changesets with 1 changes to 1 files
745 added 1 changesets with 1 changes to 1 files
746 (run 'hg update' to get a working copy)
746 (run 'hg update' to get a working copy)
747
747
748
748
749 strip with local changes, should complain
749 strip with local changes, should complain
750
750
751 $ hg up
751 $ hg up
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 $ echo y>y
753 $ echo y>y
754 $ hg add y
754 $ hg add y
755 $ hg strip tip
755 $ hg strip tip
756 abort: local changes found
756 abort: local changes found
757 [255]
757 [255]
758
758
759 --force strip with local changes
759 --force strip with local changes
760
760
761 $ hg strip -f tip
761 $ hg strip -f tip
762 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
762 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
763 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
763 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
764
764
765
765
766 cd b; hg qrefresh
766 cd b; hg qrefresh
767
767
768 $ hg init refresh
768 $ hg init refresh
769 $ cd refresh
769 $ cd refresh
770 $ echo a > a
770 $ echo a > a
771 $ hg ci -Ama
771 $ hg ci -Ama
772 adding a
772 adding a
773 $ hg qnew -mfoo foo
773 $ hg qnew -mfoo foo
774 $ echo a >> a
774 $ echo a >> a
775 $ hg qrefresh
775 $ hg qrefresh
776 $ mkdir b
776 $ mkdir b
777 $ cd b
777 $ cd b
778 $ echo f > f
778 $ echo f > f
779 $ hg add f
779 $ hg add f
780 $ hg qrefresh
780 $ hg qrefresh
781 $ cat ../.hg/patches/foo
781 $ cat ../.hg/patches/foo
782 foo
782 foo
783
783
784 diff -r cb9a9f314b8b a
784 diff -r cb9a9f314b8b a
785 --- a/a\t(?P<date>.*) (re)
785 --- a/a\t(?P<date>.*) (re)
786 \+\+\+ b/a\t(?P<date>.*) (re)
786 \+\+\+ b/a\t(?P<date>.*) (re)
787 @@ -1,1 +1,2 @@
787 @@ -1,1 +1,2 @@
788 a
788 a
789 +a
789 +a
790 diff -r cb9a9f314b8b b/f
790 diff -r cb9a9f314b8b b/f
791 --- /dev/null\t(?P<date>.*) (re)
791 --- /dev/null\t(?P<date>.*) (re)
792 \+\+\+ b/b/f\t(?P<date>.*) (re)
792 \+\+\+ b/b/f\t(?P<date>.*) (re)
793 @@ -0,0 +1,1 @@
793 @@ -0,0 +1,1 @@
794 +f
794 +f
795
795
796 hg qrefresh .
796 hg qrefresh .
797
797
798 $ hg qrefresh .
798 $ hg qrefresh .
799 $ cat ../.hg/patches/foo
799 $ cat ../.hg/patches/foo
800 foo
800 foo
801
801
802 diff -r cb9a9f314b8b b/f
802 diff -r cb9a9f314b8b b/f
803 --- /dev/null\t(?P<date>.*) (re)
803 --- /dev/null\t(?P<date>.*) (re)
804 \+\+\+ b/b/f\t(?P<date>.*) (re)
804 \+\+\+ b/b/f\t(?P<date>.*) (re)
805 @@ -0,0 +1,1 @@
805 @@ -0,0 +1,1 @@
806 +f
806 +f
807 $ hg status
807 $ hg status
808 M a
808 M a
809
809
810
810
811 qpush failure
811 qpush failure
812
812
813 $ cd ..
813 $ cd ..
814 $ hg qrefresh
814 $ hg qrefresh
815 $ hg qnew -mbar bar
815 $ hg qnew -mbar bar
816 $ echo foo > foo
816 $ echo foo > foo
817 $ echo bar > bar
817 $ echo bar > bar
818 $ hg add foo bar
818 $ hg add foo bar
819 $ hg qrefresh
819 $ hg qrefresh
820 $ hg qpop -a
820 $ hg qpop -a
821 popping bar
821 popping bar
822 popping foo
822 popping foo
823 patch queue now empty
823 patch queue now empty
824 $ echo bar > foo
824 $ echo bar > foo
825 $ hg qpush -a
825 $ hg qpush -a
826 applying foo
826 applying foo
827 applying bar
827 applying bar
828 file foo already exists
828 file foo already exists
829 1 out of 1 hunks FAILED -- saving rejects to file foo.rej
829 1 out of 1 hunks FAILED -- saving rejects to file foo.rej
830 patch failed, unable to continue (try -v)
830 patch failed, unable to continue (try -v)
831 patch failed, rejects left in working dir
831 patch failed, rejects left in working dir
832 errors during apply, please fix and refresh bar
832 errors during apply, please fix and refresh bar
833 [2]
833 [2]
834 $ hg st
834 $ hg st
835 ? foo
835 ? foo
836 ? foo.rej
836 ? foo.rej
837
837
838
838
839 mq tags
839 mq tags
840
840
841 $ hg log --template '{rev} {tags}\n' -r qparent:qtip
841 $ hg log --template '{rev} {tags}\n' -r qparent:qtip
842 0 qparent
842 0 qparent
843 1 foo qbase
843 1 foo qbase
844 2 bar qtip tip
844 2 bar qtip tip
845
845
846
846
847 bad node in status
847 bad node in status
848
848
849 $ hg qpop
849 $ hg qpop
850 popping bar
850 popping bar
851 now at: foo
851 now at: foo
852 $ hg strip -qn tip
852 $ hg strip -qn tip
853 $ hg tip
853 $ hg tip
854 changeset: 0:cb9a9f314b8b
854 changeset: 0:cb9a9f314b8b
855 tag: tip
855 tag: tip
856 user: test
856 user: test
857 date: Thu Jan 01 00:00:00 1970 +0000
857 date: Thu Jan 01 00:00:00 1970 +0000
858 summary: a
858 summary: a
859
859
860 $ hg branches
860 $ hg branches
861 default 0:cb9a9f314b8b
861 default 0:cb9a9f314b8b
862 $ hg qpop
862 $ hg qpop
863 no patches applied
863 no patches applied
864 [1]
864 [1]
865
865
866 $ cat >>$HGRCPATH <<EOF
866 $ cat >>$HGRCPATH <<EOF
867 > [diff]
867 > [diff]
868 > git = True
868 > git = True
869 > EOF
869 > EOF
870 $ cd ..
870 $ cd ..
871 $ hg init git
871 $ hg init git
872 $ cd git
872 $ cd git
873 $ hg qinit
873 $ hg qinit
874
874
875 $ hg qnew -m'new file' new
875 $ hg qnew -m'new file' new
876 $ echo foo > new
876 $ echo foo > new
877 $ chmod +x new
877 $ chmod +x new
878 $ hg add new
878 $ hg add new
879 $ hg qrefresh
879 $ hg qrefresh
880 $ cat .hg/patches/new
880 $ cat .hg/patches/new
881 new file
881 new file
882
882
883 diff --git a/new b/new
883 diff --git a/new b/new
884 new file mode 100755
884 new file mode 100755
885 --- /dev/null
885 --- /dev/null
886 +++ b/new
886 +++ b/new
887 @@ -0,0 +1,1 @@
887 @@ -0,0 +1,1 @@
888 +foo
888 +foo
889
889
890 $ hg qnew -m'copy file' copy
890 $ hg qnew -m'copy file' copy
891 $ hg cp new copy
891 $ hg cp new copy
892 $ hg qrefresh
892 $ hg qrefresh
893 $ cat .hg/patches/copy
893 $ cat .hg/patches/copy
894 copy file
894 copy file
895
895
896 diff --git a/new b/copy
896 diff --git a/new b/copy
897 copy from new
897 copy from new
898 copy to copy
898 copy to copy
899
899
900 $ hg qpop
900 $ hg qpop
901 popping copy
901 popping copy
902 now at: new
902 now at: new
903 $ hg qpush
903 $ hg qpush
904 applying copy
904 applying copy
905 now at: copy
905 now at: copy
906 $ hg qdiff
906 $ hg qdiff
907 diff --git a/new b/copy
907 diff --git a/new b/copy
908 copy from new
908 copy from new
909 copy to copy
909 copy to copy
910 $ cat >>$HGRCPATH <<EOF
910 $ cat >>$HGRCPATH <<EOF
911 > [diff]
911 > [diff]
912 > git = False
912 > git = False
913 > EOF
913 > EOF
914 $ hg qdiff --git
914 $ hg qdiff --git
915 diff --git a/new b/copy
915 diff --git a/new b/copy
916 copy from new
916 copy from new
917 copy to copy
917 copy to copy
918 $ cd ..
918 $ cd ..
919
919
920 empty lines in status
920 empty lines in status
921
921
922 $ hg init emptystatus
922 $ hg init emptystatus
923 $ cd emptystatus
923 $ cd emptystatus
924 $ hg qinit
924 $ hg qinit
925 $ printf '\n\n' > .hg/patches/status
925 $ printf '\n\n' > .hg/patches/status
926 $ hg qser
926 $ hg qser
927 $ cd ..
927 $ cd ..
928
928
929 bad line in status (without ":")
929 bad line in status (without ":")
930
930
931 $ hg init badstatus
931 $ hg init badstatus
932 $ cd badstatus
932 $ cd badstatus
933 $ hg qinit
933 $ hg qinit
934 $ printf 'babar has no colon in this line\n' > .hg/patches/status
934 $ printf 'babar has no colon in this line\n' > .hg/patches/status
935 $ hg qser
935 $ hg qser
936 malformated mq status line: ['babar has no colon in this line']
936 malformated mq status line: ['babar has no colon in this line']
937 $ cd ..
937 $ cd ..
938
938
939
939
940 test file addition in slow path
940 test file addition in slow path
941
941
942 $ hg init slow
942 $ hg init slow
943 $ cd slow
943 $ cd slow
944 $ hg qinit
944 $ hg qinit
945 $ echo foo > foo
945 $ echo foo > foo
946 $ hg add foo
946 $ hg add foo
947 $ hg ci -m 'add foo'
947 $ hg ci -m 'add foo'
948 $ hg qnew bar
948 $ hg qnew bar
949 $ echo bar > bar
949 $ echo bar > bar
950 $ hg add bar
950 $ hg add bar
951 $ hg mv foo baz
951 $ hg mv foo baz
952 $ hg qrefresh --git
952 $ hg qrefresh --git
953 $ hg up -C 0
953 $ hg up -C 0
954 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
954 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
955 $ echo >> foo
955 $ echo >> foo
956 $ hg ci -m 'change foo'
956 $ hg ci -m 'change foo'
957 created new head
957 created new head
958 $ hg up -C 1
958 $ hg up -C 1
959 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
959 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
960 $ hg qrefresh --git
960 $ hg qrefresh --git
961 $ cat .hg/patches/bar
961 $ cat .hg/patches/bar
962 diff --git a/bar b/bar
962 diff --git a/bar b/bar
963 new file mode 100644
963 new file mode 100644
964 --- /dev/null
964 --- /dev/null
965 +++ b/bar
965 +++ b/bar
966 @@ -0,0 +1,1 @@
966 @@ -0,0 +1,1 @@
967 +bar
967 +bar
968 diff --git a/foo b/baz
968 diff --git a/foo b/baz
969 rename from foo
969 rename from foo
970 rename to baz
970 rename to baz
971 $ hg log -v --template '{rev} {file_copies}\n' -r .
971 $ hg log -v --template '{rev} {file_copies}\n' -r .
972 2 baz (foo)
972 2 baz (foo)
973 $ hg qrefresh --git
973 $ hg qrefresh --git
974 $ cat .hg/patches/bar
974 $ cat .hg/patches/bar
975 diff --git a/bar b/bar
975 diff --git a/bar b/bar
976 new file mode 100644
976 new file mode 100644
977 --- /dev/null
977 --- /dev/null
978 +++ b/bar
978 +++ b/bar
979 @@ -0,0 +1,1 @@
979 @@ -0,0 +1,1 @@
980 +bar
980 +bar
981 diff --git a/foo b/baz
981 diff --git a/foo b/baz
982 rename from foo
982 rename from foo
983 rename to baz
983 rename to baz
984 $ hg log -v --template '{rev} {file_copies}\n' -r .
984 $ hg log -v --template '{rev} {file_copies}\n' -r .
985 2 baz (foo)
985 2 baz (foo)
986 $ hg qrefresh
986 $ hg qrefresh
987 $ grep 'diff --git' .hg/patches/bar
987 $ grep 'diff --git' .hg/patches/bar
988 diff --git a/bar b/bar
988 diff --git a/bar b/bar
989 diff --git a/foo b/baz
989 diff --git a/foo b/baz
990
990
991
991
992 test file move chains in the slow path
992 test file move chains in the slow path
993
993
994 $ hg up -C 1
994 $ hg up -C 1
995 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
995 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
996 $ echo >> foo
996 $ echo >> foo
997 $ hg ci -m 'change foo again'
997 $ hg ci -m 'change foo again'
998 $ hg up -C 2
998 $ hg up -C 2
999 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
999 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1000 $ hg mv bar quux
1000 $ hg mv bar quux
1001 $ hg mv baz bleh
1001 $ hg mv baz bleh
1002 $ hg qrefresh --git
1002 $ hg qrefresh --git
1003 $ cat .hg/patches/bar
1003 $ cat .hg/patches/bar
1004 diff --git a/foo b/bleh
1004 diff --git a/foo b/bleh
1005 rename from foo
1005 rename from foo
1006 rename to bleh
1006 rename to bleh
1007 diff --git a/quux b/quux
1007 diff --git a/quux b/quux
1008 new file mode 100644
1008 new file mode 100644
1009 --- /dev/null
1009 --- /dev/null
1010 +++ b/quux
1010 +++ b/quux
1011 @@ -0,0 +1,1 @@
1011 @@ -0,0 +1,1 @@
1012 +bar
1012 +bar
1013 $ hg log -v --template '{rev} {file_copies}\n' -r .
1013 $ hg log -v --template '{rev} {file_copies}\n' -r .
1014 3 bleh (foo)
1014 3 bleh (foo)
1015 $ hg mv quux fred
1015 $ hg mv quux fred
1016 $ hg mv bleh barney
1016 $ hg mv bleh barney
1017 $ hg qrefresh --git
1017 $ hg qrefresh --git
1018 $ cat .hg/patches/bar
1018 $ cat .hg/patches/bar
1019 diff --git a/foo b/barney
1019 diff --git a/foo b/barney
1020 rename from foo
1020 rename from foo
1021 rename to barney
1021 rename to barney
1022 diff --git a/fred b/fred
1022 diff --git a/fred b/fred
1023 new file mode 100644
1023 new file mode 100644
1024 --- /dev/null
1024 --- /dev/null
1025 +++ b/fred
1025 +++ b/fred
1026 @@ -0,0 +1,1 @@
1026 @@ -0,0 +1,1 @@
1027 +bar
1027 +bar
1028 $ hg log -v --template '{rev} {file_copies}\n' -r .
1028 $ hg log -v --template '{rev} {file_copies}\n' -r .
1029 3 barney (foo)
1029 3 barney (foo)
1030
1030
1031
1031
1032 refresh omitting an added file
1032 refresh omitting an added file
1033
1033
1034 $ hg qnew baz
1034 $ hg qnew baz
1035 $ echo newfile > newfile
1035 $ echo newfile > newfile
1036 $ hg add newfile
1036 $ hg add newfile
1037 $ hg qrefresh
1037 $ hg qrefresh
1038 $ hg st -A newfile
1038 $ hg st -A newfile
1039 C newfile
1039 C newfile
1040 $ hg qrefresh -X newfile
1040 $ hg qrefresh -X newfile
1041 $ hg st -A newfile
1041 $ hg st -A newfile
1042 A newfile
1042 A newfile
1043 $ hg revert newfile
1043 $ hg revert newfile
1044 $ rm newfile
1044 $ rm newfile
1045 $ hg qpop
1045 $ hg qpop
1046 popping baz
1046 popping baz
1047 now at: bar
1047 now at: bar
1048 $ hg qdel baz
1048 $ hg qdel baz
1049
1049
1050
1050
1051 create a git patch
1051 create a git patch
1052
1052
1053 $ echo a > alexander
1053 $ echo a > alexander
1054 $ hg add alexander
1054 $ hg add alexander
1055 $ hg qnew -f --git addalexander
1055 $ hg qnew -f --git addalexander
1056 $ grep diff .hg/patches/addalexander
1056 $ grep diff .hg/patches/addalexander
1057 diff --git a/alexander b/alexander
1057 diff --git a/alexander b/alexander
1058
1058
1059
1059
1060 create a git binary patch
1060 create a git binary patch
1061
1061
1062 $ cat > writebin.py <<EOF
1062 $ cat > writebin.py <<EOF
1063 > import sys
1063 > import sys
1064 > path = sys.argv[1]
1064 > path = sys.argv[1]
1065 > open(path, 'wb').write('BIN\x00ARY')
1065 > open(path, 'wb').write('BIN\x00ARY')
1066 > EOF
1066 > EOF
1067 $ python writebin.py bucephalus
1067 $ python writebin.py bucephalus
1068
1068
1069 $ python "$TESTDIR/md5sum.py" bucephalus
1069 $ python "$TESTDIR/md5sum.py" bucephalus
1070 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1070 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1071 $ hg add bucephalus
1071 $ hg add bucephalus
1072 $ hg qnew -f --git addbucephalus
1072 $ hg qnew -f --git addbucephalus
1073 $ grep diff .hg/patches/addbucephalus
1073 $ grep diff .hg/patches/addbucephalus
1074 diff --git a/bucephalus b/bucephalus
1074 diff --git a/bucephalus b/bucephalus
1075
1075
1076
1076
1077 check binary patches can be popped and pushed
1077 check binary patches can be popped and pushed
1078
1078
1079 $ hg qpop
1079 $ hg qpop
1080 popping addbucephalus
1080 popping addbucephalus
1081 now at: addalexander
1081 now at: addalexander
1082 $ test -f bucephalus && echo % bucephalus should not be there
1082 $ test -f bucephalus && echo % bucephalus should not be there
1083 [1]
1083 [1]
1084 $ hg qpush
1084 $ hg qpush
1085 applying addbucephalus
1085 applying addbucephalus
1086 now at: addbucephalus
1086 now at: addbucephalus
1087 $ test -f bucephalus
1087 $ test -f bucephalus
1088 $ python "$TESTDIR/md5sum.py" bucephalus
1088 $ python "$TESTDIR/md5sum.py" bucephalus
1089 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1089 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1090
1090
1091
1091
1092
1092
1093 strip again
1093 strip again
1094
1094
1095 $ cd ..
1095 $ cd ..
1096 $ hg init strip
1096 $ hg init strip
1097 $ cd strip
1097 $ cd strip
1098 $ touch foo
1098 $ touch foo
1099 $ hg add foo
1099 $ hg add foo
1100 $ hg ci -m 'add foo'
1100 $ hg ci -m 'add foo'
1101 $ echo >> foo
1101 $ echo >> foo
1102 $ hg ci -m 'change foo 1'
1102 $ hg ci -m 'change foo 1'
1103 $ hg up -C 0
1103 $ hg up -C 0
1104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1105 $ echo 1 >> foo
1105 $ echo 1 >> foo
1106 $ hg ci -m 'change foo 2'
1106 $ hg ci -m 'change foo 2'
1107 created new head
1107 created new head
1108 $ HGMERGE=true hg merge
1108 $ HGMERGE=true hg merge
1109 merging foo
1109 merging foo
1110 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1110 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1111 (branch merge, don't forget to commit)
1111 (branch merge, don't forget to commit)
1112 $ hg ci -m merge
1112 $ hg ci -m merge
1113 $ hg log
1113 $ hg log
1114 changeset: 3:99615015637b
1114 changeset: 3:99615015637b
1115 tag: tip
1115 tag: tip
1116 parent: 2:20cbbe65cff7
1116 parent: 2:20cbbe65cff7
1117 parent: 1:d2871fc282d4
1117 parent: 1:d2871fc282d4
1118 user: test
1118 user: test
1119 date: Thu Jan 01 00:00:00 1970 +0000
1119 date: Thu Jan 01 00:00:00 1970 +0000
1120 summary: merge
1120 summary: merge
1121
1121
1122 changeset: 2:20cbbe65cff7
1122 changeset: 2:20cbbe65cff7
1123 parent: 0:53245c60e682
1123 parent: 0:53245c60e682
1124 user: test
1124 user: test
1125 date: Thu Jan 01 00:00:00 1970 +0000
1125 date: Thu Jan 01 00:00:00 1970 +0000
1126 summary: change foo 2
1126 summary: change foo 2
1127
1127
1128 changeset: 1:d2871fc282d4
1128 changeset: 1:d2871fc282d4
1129 user: test
1129 user: test
1130 date: Thu Jan 01 00:00:00 1970 +0000
1130 date: Thu Jan 01 00:00:00 1970 +0000
1131 summary: change foo 1
1131 summary: change foo 1
1132
1132
1133 changeset: 0:53245c60e682
1133 changeset: 0:53245c60e682
1134 user: test
1134 user: test
1135 date: Thu Jan 01 00:00:00 1970 +0000
1135 date: Thu Jan 01 00:00:00 1970 +0000
1136 summary: add foo
1136 summary: add foo
1137
1137
1138 $ hg strip 1
1138 $ hg strip 1
1139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1140 saved backup bundle to $TESTTMP/b/strip/.hg/strip-backup/*-backup.hg (glob)
1140 saved backup bundle to $TESTTMP/b/strip/.hg/strip-backup/*-backup.hg (glob)
1141 $ checkundo strip
1141 $ checkundo strip
1142 $ hg log
1142 $ hg log
1143 changeset: 1:20cbbe65cff7
1143 changeset: 1:20cbbe65cff7
1144 tag: tip
1144 tag: tip
1145 user: test
1145 user: test
1146 date: Thu Jan 01 00:00:00 1970 +0000
1146 date: Thu Jan 01 00:00:00 1970 +0000
1147 summary: change foo 2
1147 summary: change foo 2
1148
1148
1149 changeset: 0:53245c60e682
1149 changeset: 0:53245c60e682
1150 user: test
1150 user: test
1151 date: Thu Jan 01 00:00:00 1970 +0000
1151 date: Thu Jan 01 00:00:00 1970 +0000
1152 summary: add foo
1152 summary: add foo
1153
1153
1154 $ cd ..
1154 $ cd ..
1155
1155
1156
1156
1157 qclone
1157 qclone
1158
1158
1159 $ qlog()
1159 $ qlog()
1160 > {
1160 > {
1161 > echo 'main repo:'
1161 > echo 'main repo:'
1162 > hg log --template ' rev {rev}: {desc}\n'
1162 > hg log --template ' rev {rev}: {desc}\n'
1163 > echo 'patch repo:'
1163 > echo 'patch repo:'
1164 > hg -R .hg/patches log --template ' rev {rev}: {desc}\n'
1164 > hg -R .hg/patches log --template ' rev {rev}: {desc}\n'
1165 > }
1165 > }
1166 $ hg init qclonesource
1166 $ hg init qclonesource
1167 $ cd qclonesource
1167 $ cd qclonesource
1168 $ echo foo > foo
1168 $ echo foo > foo
1169 $ hg add foo
1169 $ hg add foo
1170 $ hg ci -m 'add foo'
1170 $ hg ci -m 'add foo'
1171 $ hg qinit
1171 $ hg qinit
1172 $ hg qnew patch1
1172 $ hg qnew patch1
1173 $ echo bar >> foo
1173 $ echo bar >> foo
1174 $ hg qrefresh -m 'change foo'
1174 $ hg qrefresh -m 'change foo'
1175 $ cd ..
1175 $ cd ..
1176
1176
1177
1177
1178 repo with unversioned patch dir
1178 repo with unversioned patch dir
1179
1179
1180 $ hg qclone qclonesource failure
1180 $ hg qclone qclonesource failure
1181 abort: versioned patch repository not found (see init --mq)
1181 abort: versioned patch repository not found (see init --mq)
1182 [255]
1182 [255]
1183
1183
1184 $ cd qclonesource
1184 $ cd qclonesource
1185 $ hg qinit -c
1185 $ hg qinit -c
1186 adding .hg/patches/patch1
1186 adding .hg/patches/patch1
1187 $ hg qci -m checkpoint
1187 $ hg qci -m checkpoint
1188 $ qlog
1188 $ qlog
1189 main repo:
1189 main repo:
1190 rev 1: change foo
1190 rev 1: change foo
1191 rev 0: add foo
1191 rev 0: add foo
1192 patch repo:
1192 patch repo:
1193 rev 0: checkpoint
1193 rev 0: checkpoint
1194 $ cd ..
1194 $ cd ..
1195
1195
1196
1196
1197 repo with patches applied
1197 repo with patches applied
1198
1198
1199 $ hg qclone qclonesource qclonedest
1199 $ hg qclone qclonesource qclonedest
1200 updating to branch default
1200 updating to branch default
1201 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1201 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1202 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1202 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1203 $ cd qclonedest
1203 $ cd qclonedest
1204 $ qlog
1204 $ qlog
1205 main repo:
1205 main repo:
1206 rev 0: add foo
1206 rev 0: add foo
1207 patch repo:
1207 patch repo:
1208 rev 0: checkpoint
1208 rev 0: checkpoint
1209 $ cd ..
1209 $ cd ..
1210
1210
1211
1211
1212 repo with patches unapplied
1212 repo with patches unapplied
1213
1213
1214 $ cd qclonesource
1214 $ cd qclonesource
1215 $ hg qpop -a
1215 $ hg qpop -a
1216 popping patch1
1216 popping patch1
1217 patch queue now empty
1217 patch queue now empty
1218 $ qlog
1218 $ qlog
1219 main repo:
1219 main repo:
1220 rev 0: add foo
1220 rev 0: add foo
1221 patch repo:
1221 patch repo:
1222 rev 0: checkpoint
1222 rev 0: checkpoint
1223 $ cd ..
1223 $ cd ..
1224 $ hg qclone qclonesource qclonedest2
1224 $ hg qclone qclonesource qclonedest2
1225 updating to branch default
1225 updating to branch default
1226 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1226 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1228 $ cd qclonedest2
1228 $ cd qclonedest2
1229 $ qlog
1229 $ qlog
1230 main repo:
1230 main repo:
1231 rev 0: add foo
1231 rev 0: add foo
1232 patch repo:
1232 patch repo:
1233 rev 0: checkpoint
1233 rev 0: checkpoint
1234 $ cd ..
1234 $ cd ..
1235
1235
1236
1236
1237 Issue1033: test applying on an empty file
1237 Issue1033: test applying on an empty file
1238
1238
1239 $ hg init empty
1239 $ hg init empty
1240 $ cd empty
1240 $ cd empty
1241 $ touch a
1241 $ touch a
1242 $ hg ci -Am addempty
1242 $ hg ci -Am addempty
1243 adding a
1243 adding a
1244 $ echo a > a
1244 $ echo a > a
1245 $ hg qnew -f -e changea
1245 $ hg qnew -f -e changea
1246 $ hg qpop
1246 $ hg qpop
1247 popping changea
1247 popping changea
1248 patch queue now empty
1248 patch queue now empty
1249 $ hg qpush
1249 $ hg qpush
1250 applying changea
1250 applying changea
1251 now at: changea
1251 now at: changea
1252 $ cd ..
1252 $ cd ..
1253
1253
1254
1254
1255 test qpush with --force, issue1087
1255 test qpush with --force, issue1087
1256
1256
1257 $ hg init forcepush
1257 $ hg init forcepush
1258 $ cd forcepush
1258 $ cd forcepush
1259 $ echo hello > hello.txt
1259 $ echo hello > hello.txt
1260 $ echo bye > bye.txt
1260 $ echo bye > bye.txt
1261 $ hg ci -Ama
1261 $ hg ci -Ama
1262 adding bye.txt
1262 adding bye.txt
1263 adding hello.txt
1263 adding hello.txt
1264 $ hg qnew -d '0 0' empty
1264 $ hg qnew -d '0 0' empty
1265 $ hg qpop
1265 $ hg qpop
1266 popping empty
1266 popping empty
1267 patch queue now empty
1267 patch queue now empty
1268 $ echo world >> hello.txt
1268 $ echo world >> hello.txt
1269
1269
1270
1270
1271 qpush should fail, local changes
1271 qpush should fail, local changes
1272
1272
1273 $ hg qpush
1273 $ hg qpush
1274 abort: local changes found, refresh first
1274 abort: local changes found, refresh first
1275 [255]
1275 [255]
1276
1276
1277
1277
1278 apply force, should not discard changes with empty patch
1278 apply force, should not discard changes with empty patch
1279
1279
1280 $ hg qpush -f
1280 $ hg qpush -f
1281 applying empty
1281 applying empty
1282 patch empty is empty
1282 patch empty is empty
1283 now at: empty
1283 now at: empty
1284 $ hg diff --config diff.nodates=True
1284 $ hg diff --config diff.nodates=True
1285 diff -r bf5fc3f07a0a hello.txt
1285 diff -r d58265112590 hello.txt
1286 --- a/hello.txt
1286 --- a/hello.txt
1287 +++ b/hello.txt
1287 +++ b/hello.txt
1288 @@ -1,1 +1,2 @@
1288 @@ -1,1 +1,2 @@
1289 hello
1289 hello
1290 +world
1290 +world
1291 $ hg qdiff --config diff.nodates=True
1291 $ hg qdiff --config diff.nodates=True
1292 diff -r 9ecee4f634e3 hello.txt
1292 diff -r 9ecee4f634e3 hello.txt
1293 --- a/hello.txt
1293 --- a/hello.txt
1294 +++ b/hello.txt
1294 +++ b/hello.txt
1295 @@ -1,1 +1,2 @@
1295 @@ -1,1 +1,2 @@
1296 hello
1296 hello
1297 +world
1297 +world
1298 $ hg log -l1 -p
1298 $ hg log -l1 -p
1299 changeset: 1:bf5fc3f07a0a
1299 changeset: 1:d58265112590
1300 tag: empty
1300 tag: empty
1301 tag: qbase
1301 tag: qbase
1302 tag: qtip
1302 tag: qtip
1303 tag: tip
1303 tag: tip
1304 user: test
1304 user: test
1305 date: Thu Jan 01 00:00:00 1970 +0000
1305 date: Thu Jan 01 00:00:00 1970 +0000
1306 summary: imported patch empty
1306 summary: imported patch empty
1307
1307
1308
1308
1309 $ hg qref -d '0 0'
1309 $ hg qref -d '0 0'
1310 $ hg qpop
1310 $ hg qpop
1311 popping empty
1311 popping empty
1312 patch queue now empty
1312 patch queue now empty
1313 $ echo universe >> hello.txt
1313 $ echo universe >> hello.txt
1314 $ echo universe >> bye.txt
1314 $ echo universe >> bye.txt
1315
1315
1316
1316
1317 qpush should fail, local changes
1317 qpush should fail, local changes
1318
1318
1319 $ hg qpush
1319 $ hg qpush
1320 abort: local changes found, refresh first
1320 abort: local changes found, refresh first
1321 [255]
1321 [255]
1322
1322
1323
1323
1324 apply force, should discard changes in hello, but not bye
1324 apply force, should discard changes in hello, but not bye
1325
1325
1326 $ hg qpush -f
1326 $ hg qpush -f
1327 applying empty
1327 applying empty
1328 now at: empty
1328 now at: empty
1329 $ hg st
1329 $ hg st
1330 M bye.txt
1330 M bye.txt
1331 $ hg diff --config diff.nodates=True
1331 $ hg diff --config diff.nodates=True
1332 diff -r ba252371dbc1 bye.txt
1332 diff -r ba252371dbc1 bye.txt
1333 --- a/bye.txt
1333 --- a/bye.txt
1334 +++ b/bye.txt
1334 +++ b/bye.txt
1335 @@ -1,1 +1,2 @@
1335 @@ -1,1 +1,2 @@
1336 bye
1336 bye
1337 +universe
1337 +universe
1338 $ hg qdiff --config diff.nodates=True
1338 $ hg qdiff --config diff.nodates=True
1339 diff -r 9ecee4f634e3 bye.txt
1339 diff -r 9ecee4f634e3 bye.txt
1340 --- a/bye.txt
1340 --- a/bye.txt
1341 +++ b/bye.txt
1341 +++ b/bye.txt
1342 @@ -1,1 +1,2 @@
1342 @@ -1,1 +1,2 @@
1343 bye
1343 bye
1344 +universe
1344 +universe
1345 diff -r 9ecee4f634e3 hello.txt
1345 diff -r 9ecee4f634e3 hello.txt
1346 --- a/hello.txt
1346 --- a/hello.txt
1347 +++ b/hello.txt
1347 +++ b/hello.txt
1348 @@ -1,1 +1,3 @@
1348 @@ -1,1 +1,3 @@
1349 hello
1349 hello
1350 +world
1350 +world
1351 +universe
1351 +universe
1352
1352
1353
1353
1354 test popping revisions not in working dir ancestry
1354 test popping revisions not in working dir ancestry
1355
1355
1356 $ hg qseries -v
1356 $ hg qseries -v
1357 0 A empty
1357 0 A empty
1358 $ hg up qparent
1358 $ hg up qparent
1359 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1359 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1360 $ hg qpop
1360 $ hg qpop
1361 popping empty
1361 popping empty
1362 patch queue now empty
1362 patch queue now empty
1363
1363
1364 $ cd ..
1364 $ cd ..
1365 $ hg init deletion-order
1365 $ hg init deletion-order
1366 $ cd deletion-order
1366 $ cd deletion-order
1367
1367
1368 $ touch a
1368 $ touch a
1369 $ hg ci -Aqm0
1369 $ hg ci -Aqm0
1370
1370
1371 $ hg qnew rename-dir
1371 $ hg qnew rename-dir
1372 $ hg rm a
1372 $ hg rm a
1373 $ hg qrefresh
1373 $ hg qrefresh
1374
1374
1375 $ mkdir a b
1375 $ mkdir a b
1376 $ touch a/a b/b
1376 $ touch a/a b/b
1377 $ hg add -q a b
1377 $ hg add -q a b
1378 $ hg qrefresh
1378 $ hg qrefresh
1379
1379
1380
1380
1381 test popping must remove files added in subdirectories first
1381 test popping must remove files added in subdirectories first
1382
1382
1383 $ hg qpop
1383 $ hg qpop
1384 popping rename-dir
1384 popping rename-dir
1385 patch queue now empty
1385 patch queue now empty
1386 $ cd ..
1386 $ cd ..
1387
1387
@@ -1,321 +1,321
1 $ branchcache=.hg/cache/branchheads
1 $ branchcache=.hg/cache/branchheads
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 $ hg branches
6 $ hg branches
7 $ echo foo > a
7 $ echo foo > a
8 $ hg add a
8 $ hg add a
9 $ hg ci -m "initial"
9 $ hg ci -m "initial"
10 $ hg branch foo
10 $ hg branch foo
11 marked working directory as branch foo
11 marked working directory as branch foo
12 $ hg branch
12 $ hg branch
13 foo
13 foo
14 $ hg ci -m "add branch name"
14 $ hg ci -m "add branch name"
15 $ hg branch bar
15 $ hg branch bar
16 marked working directory as branch bar
16 marked working directory as branch bar
17 $ hg ci -m "change branch name"
17 $ hg ci -m "change branch name"
18
18
19 Branch shadowing:
19 Branch shadowing:
20
20
21 $ hg branch default
21 $ hg branch default
22 abort: a branch of the same name already exists (use 'hg update' to switch to it)
22 abort: a branch of the same name already exists (use 'hg update' to switch to it)
23 [255]
23 [255]
24
24
25 $ hg branch -f default
25 $ hg branch -f default
26 marked working directory as branch default
26 marked working directory as branch default
27
27
28 $ hg ci -m "clear branch name"
28 $ hg ci -m "clear branch name"
29 created new head
29 created new head
30
30
31 There should be only one default branch head
31 There should be only one default branch head
32
32
33 $ hg heads .
33 $ hg heads .
34 changeset: 3:9d567d0b51f9
34 changeset: 3:1c28f494dae6
35 tag: tip
35 tag: tip
36 user: test
36 user: test
37 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
38 summary: clear branch name
38 summary: clear branch name
39
39
40
40
41 $ hg co foo
41 $ hg co foo
42 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 $ hg branch
43 $ hg branch
44 foo
44 foo
45 $ echo bleah > a
45 $ echo bleah > a
46 $ hg ci -m "modify a branch"
46 $ hg ci -m "modify a branch"
47
47
48 $ hg merge default
48 $ hg merge default
49 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 (branch merge, don't forget to commit)
50 (branch merge, don't forget to commit)
51
51
52 $ hg branch
52 $ hg branch
53 foo
53 foo
54 $ hg ci -m "merge"
54 $ hg ci -m "merge"
55
55
56 $ hg log
56 $ hg log
57 changeset: 5:dc140083783b
57 changeset: 5:530046499edf
58 branch: foo
58 branch: foo
59 tag: tip
59 tag: tip
60 parent: 4:98d14f698afe
60 parent: 4:adf1a74a7f7b
61 parent: 3:9d567d0b51f9
61 parent: 3:1c28f494dae6
62 user: test
62 user: test
63 date: Thu Jan 01 00:00:00 1970 +0000
63 date: Thu Jan 01 00:00:00 1970 +0000
64 summary: merge
64 summary: merge
65
65
66 changeset: 4:98d14f698afe
66 changeset: 4:adf1a74a7f7b
67 branch: foo
67 branch: foo
68 parent: 1:0079f24813e2
68 parent: 1:6c0e42da283a
69 user: test
69 user: test
70 date: Thu Jan 01 00:00:00 1970 +0000
70 date: Thu Jan 01 00:00:00 1970 +0000
71 summary: modify a branch
71 summary: modify a branch
72
72
73 changeset: 3:9d567d0b51f9
73 changeset: 3:1c28f494dae6
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: clear branch name
76 summary: clear branch name
77
77
78 changeset: 2:ed2bbf4e0102
78 changeset: 2:c21617b13b22
79 branch: bar
79 branch: bar
80 user: test
80 user: test
81 date: Thu Jan 01 00:00:00 1970 +0000
81 date: Thu Jan 01 00:00:00 1970 +0000
82 summary: change branch name
82 summary: change branch name
83
83
84 changeset: 1:0079f24813e2
84 changeset: 1:6c0e42da283a
85 branch: foo
85 branch: foo
86 user: test
86 user: test
87 date: Thu Jan 01 00:00:00 1970 +0000
87 date: Thu Jan 01 00:00:00 1970 +0000
88 summary: add branch name
88 summary: add branch name
89
89
90 changeset: 0:db01e8ea3388
90 changeset: 0:db01e8ea3388
91 user: test
91 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
92 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: initial
93 summary: initial
94
94
95 $ hg branches
95 $ hg branches
96 foo 5:dc140083783b
96 foo 5:530046499edf
97 default 3:9d567d0b51f9 (inactive)
97 default 3:1c28f494dae6 (inactive)
98 bar 2:ed2bbf4e0102 (inactive)
98 bar 2:c21617b13b22 (inactive)
99
99
100 $ hg branches -q
100 $ hg branches -q
101 foo
101 foo
102 default
102 default
103 bar
103 bar
104
104
105 Test for invalid branch cache:
105 Test for invalid branch cache:
106
106
107 $ hg rollback
107 $ hg rollback
108 repository tip rolled back to revision 4 (undo commit)
108 repository tip rolled back to revision 4 (undo commit)
109 working directory now based on revisions 4 and 3
109 working directory now based on revisions 4 and 3
110
110
111 $ cp $branchcache .hg/bc-invalid
111 $ cp $branchcache .hg/bc-invalid
112
112
113 $ hg log -r foo
113 $ hg log -r foo
114 changeset: 4:98d14f698afe
114 changeset: 4:adf1a74a7f7b
115 branch: foo
115 branch: foo
116 tag: tip
116 tag: tip
117 parent: 1:0079f24813e2
117 parent: 1:6c0e42da283a
118 user: test
118 user: test
119 date: Thu Jan 01 00:00:00 1970 +0000
119 date: Thu Jan 01 00:00:00 1970 +0000
120 summary: modify a branch
120 summary: modify a branch
121
121
122 $ cp .hg/bc-invalid $branchcache
122 $ cp .hg/bc-invalid $branchcache
123
123
124 $ hg --debug log -r foo
124 $ hg --debug log -r foo
125 invalidating branch cache (tip differs)
125 invalidating branch cache (tip differs)
126 changeset: 4:98d14f698afeaff8cb612dcf215ce95e639effc3
126 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
127 branch: foo
127 branch: foo
128 tag: tip
128 tag: tip
129 parent: 1:0079f24813e2b73a891577c243684c5066347bc8
129 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
130 parent: -1:0000000000000000000000000000000000000000
130 parent: -1:0000000000000000000000000000000000000000
131 manifest: 4:d01b250baaa05909152f7ae07d7a649deea0df9a
131 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
132 user: test
132 user: test
133 date: Thu Jan 01 00:00:00 1970 +0000
133 date: Thu Jan 01 00:00:00 1970 +0000
134 files: a
134 files: a
135 extra: branch=foo
135 extra: branch=foo
136 description:
136 description:
137 modify a branch
137 modify a branch
138
138
139
139
140 $ rm $branchcache
140 $ rm $branchcache
141 $ echo corrupted > $branchcache
141 $ echo corrupted > $branchcache
142
142
143 $ hg log -qr foo
143 $ hg log -qr foo
144 4:98d14f698afe
144 4:adf1a74a7f7b
145
145
146 $ cat $branchcache
146 $ cat $branchcache
147 98d14f698afeaff8cb612dcf215ce95e639effc3 4
147 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
148 9d567d0b51f9e2068b054e1948e1a927f99b5874 default
148 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
149 98d14f698afeaff8cb612dcf215ce95e639effc3 foo
149 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
150 ed2bbf4e01029020711be82ca905283e883f0e11 bar
150 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
151
151
152 Push should update the branch cache:
152 Push should update the branch cache:
153
153
154 $ hg init ../target
154 $ hg init ../target
155
155
156 Pushing just rev 0:
156 Pushing just rev 0:
157
157
158 $ hg push -qr 0 ../target
158 $ hg push -qr 0 ../target
159
159
160 $ cat ../target/$branchcache
160 $ cat ../target/$branchcache
161 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
161 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
162 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
162 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
163
163
164 Pushing everything:
164 Pushing everything:
165
165
166 $ hg push -qf ../target
166 $ hg push -qf ../target
167
167
168 $ cat ../target/$branchcache
168 $ cat ../target/$branchcache
169 98d14f698afeaff8cb612dcf215ce95e639effc3 4
169 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
170 9d567d0b51f9e2068b054e1948e1a927f99b5874 default
170 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
171 98d14f698afeaff8cb612dcf215ce95e639effc3 foo
171 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
172 ed2bbf4e01029020711be82ca905283e883f0e11 bar
172 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
173
173
174 Update with no arguments: tipmost revision of the current branch:
174 Update with no arguments: tipmost revision of the current branch:
175
175
176 $ hg up -q -C 0
176 $ hg up -q -C 0
177 $ hg up -q
177 $ hg up -q
178 $ hg id
178 $ hg id
179 9d567d0b51f9
179 1c28f494dae6
180
180
181 $ hg up -q 1
181 $ hg up -q 1
182 $ hg up -q
182 $ hg up -q
183 $ hg id
183 $ hg id
184 98d14f698afe (foo) tip
184 adf1a74a7f7b (foo) tip
185
185
186 $ hg branch foobar
186 $ hg branch foobar
187 marked working directory as branch foobar
187 marked working directory as branch foobar
188
188
189 $ hg up
189 $ hg up
190 abort: branch foobar not found
190 abort: branch foobar not found
191 [255]
191 [255]
192
192
193 Fastforward merge:
193 Fastforward merge:
194
194
195 $ hg branch ff
195 $ hg branch ff
196 marked working directory as branch ff
196 marked working directory as branch ff
197
197
198 $ echo ff > ff
198 $ echo ff > ff
199 $ hg ci -Am'fast forward'
199 $ hg ci -Am'fast forward'
200 adding ff
200 adding ff
201
201
202 $ hg up foo
202 $ hg up foo
203 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
203 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
204
204
205 $ hg merge ff
205 $ hg merge ff
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 (branch merge, don't forget to commit)
207 (branch merge, don't forget to commit)
208
208
209 $ hg branch
209 $ hg branch
210 foo
210 foo
211 $ hg commit -m'Merge ff into foo'
211 $ hg commit -m'Merge ff into foo'
212 $ hg parents
212 $ hg parents
213 changeset: 6:917eb54e1b4b
213 changeset: 6:185ffbfefa30
214 branch: foo
214 branch: foo
215 tag: tip
215 tag: tip
216 parent: 4:98d14f698afe
216 parent: 4:adf1a74a7f7b
217 parent: 5:6683a60370cb
217 parent: 5:1a3c27dc5e11
218 user: test
218 user: test
219 date: Thu Jan 01 00:00:00 1970 +0000
219 date: Thu Jan 01 00:00:00 1970 +0000
220 summary: Merge ff into foo
220 summary: Merge ff into foo
221
221
222 $ hg manifest
222 $ hg manifest
223 a
223 a
224 ff
224 ff
225
225
226
226
227 Test merging, add 3 default heads and one test head:
227 Test merging, add 3 default heads and one test head:
228
228
229 $ cd ..
229 $ cd ..
230 $ hg init merges
230 $ hg init merges
231 $ cd merges
231 $ cd merges
232 $ echo a > a
232 $ echo a > a
233 $ hg ci -Ama
233 $ hg ci -Ama
234 adding a
234 adding a
235
235
236 $ echo b > b
236 $ echo b > b
237 $ hg ci -Amb
237 $ hg ci -Amb
238 adding b
238 adding b
239
239
240 $ hg up 0
240 $ hg up 0
241 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
241 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
242 $ echo c > c
242 $ echo c > c
243 $ hg ci -Amc
243 $ hg ci -Amc
244 adding c
244 adding c
245 created new head
245 created new head
246
246
247 $ hg up 0
247 $ hg up 0
248 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
248 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
249 $ echo d > d
249 $ echo d > d
250 $ hg ci -Amd
250 $ hg ci -Amd
251 adding d
251 adding d
252 created new head
252 created new head
253
253
254 $ hg up 0
254 $ hg up 0
255 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
255 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
256 $ hg branch test
256 $ hg branch test
257 marked working directory as branch test
257 marked working directory as branch test
258 $ echo e >> e
258 $ echo e >> e
259 $ hg ci -Ame
259 $ hg ci -Ame
260 adding e
260 adding e
261
261
262 $ hg log
262 $ hg log
263 changeset: 4:3a1e01ed1df4
263 changeset: 4:3a1e01ed1df4
264 branch: test
264 branch: test
265 tag: tip
265 tag: tip
266 parent: 0:cb9a9f314b8b
266 parent: 0:cb9a9f314b8b
267 user: test
267 user: test
268 date: Thu Jan 01 00:00:00 1970 +0000
268 date: Thu Jan 01 00:00:00 1970 +0000
269 summary: e
269 summary: e
270
270
271 changeset: 3:980f7dc84c29
271 changeset: 3:980f7dc84c29
272 parent: 0:cb9a9f314b8b
272 parent: 0:cb9a9f314b8b
273 user: test
273 user: test
274 date: Thu Jan 01 00:00:00 1970 +0000
274 date: Thu Jan 01 00:00:00 1970 +0000
275 summary: d
275 summary: d
276
276
277 changeset: 2:d36c0562f908
277 changeset: 2:d36c0562f908
278 parent: 0:cb9a9f314b8b
278 parent: 0:cb9a9f314b8b
279 user: test
279 user: test
280 date: Thu Jan 01 00:00:00 1970 +0000
280 date: Thu Jan 01 00:00:00 1970 +0000
281 summary: c
281 summary: c
282
282
283 changeset: 1:d2ae7f538514
283 changeset: 1:d2ae7f538514
284 user: test
284 user: test
285 date: Thu Jan 01 00:00:00 1970 +0000
285 date: Thu Jan 01 00:00:00 1970 +0000
286 summary: b
286 summary: b
287
287
288 changeset: 0:cb9a9f314b8b
288 changeset: 0:cb9a9f314b8b
289 user: test
289 user: test
290 date: Thu Jan 01 00:00:00 1970 +0000
290 date: Thu Jan 01 00:00:00 1970 +0000
291 summary: a
291 summary: a
292
292
293 Implicit merge with test branch as parent:
293 Implicit merge with test branch as parent:
294
294
295 $ hg merge
295 $ hg merge
296 abort: branch 'test' has one head - please merge with an explicit rev
296 abort: branch 'test' has one head - please merge with an explicit rev
297 (run 'hg heads' to see all heads)
297 (run 'hg heads' to see all heads)
298 [255]
298 [255]
299 $ hg up -C default
299 $ hg up -C default
300 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
300 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
301
301
302 Implicit merge with default branch as parent:
302 Implicit merge with default branch as parent:
303
303
304 $ hg merge
304 $ hg merge
305 abort: branch 'default' has 3 heads - please merge with an explicit rev
305 abort: branch 'default' has 3 heads - please merge with an explicit rev
306 (run 'hg heads .' to see heads)
306 (run 'hg heads .' to see heads)
307 [255]
307 [255]
308
308
309 3 branch heads, explicit merge required:
309 3 branch heads, explicit merge required:
310
310
311 $ hg merge 2
311 $ hg merge 2
312 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
312 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
313 (branch merge, don't forget to commit)
313 (branch merge, don't forget to commit)
314 $ hg ci -m merge
314 $ hg ci -m merge
315
315
316 2 branch heads, implicit merge works:
316 2 branch heads, implicit merge works:
317
317
318 $ hg merge
318 $ hg merge
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
320 (branch merge, don't forget to commit)
320 (branch merge, don't forget to commit)
321
321
@@ -1,353 +1,353
1
1
2 $ cat <<EOF >> $HGRCPATH
2 $ cat <<EOF >> $HGRCPATH
3 > [extensions]
3 > [extensions]
4 > notify=
4 > notify=
5 >
5 >
6 > [hooks]
6 > [hooks]
7 > incoming.notify = python:hgext.notify.hook
7 > incoming.notify = python:hgext.notify.hook
8 >
8 >
9 > [notify]
9 > [notify]
10 > sources = pull
10 > sources = pull
11 > diffstat = False
11 > diffstat = False
12 >
12 >
13 > [usersubs]
13 > [usersubs]
14 > foo@bar = *
14 > foo@bar = *
15 >
15 >
16 > [reposubs]
16 > [reposubs]
17 > * = baz
17 > * = baz
18 > EOF
18 > EOF
19 $ hg help notify
19 $ hg help notify
20 notify extension - hooks for sending email notifications at commit/push time
20 notify extension - hooks for sending email notifications at commit/push time
21
21
22 Subscriptions can be managed through a hgrc file. Default mode is to print
22 Subscriptions can be managed through a hgrc file. Default mode is to print
23 messages to stdout, for testing and configuring.
23 messages to stdout, for testing and configuring.
24
24
25 To use, configure the notify extension and enable it in hgrc like this:
25 To use, configure the notify extension and enable it in hgrc like this:
26
26
27 [extensions]
27 [extensions]
28 notify =
28 notify =
29
29
30 [hooks]
30 [hooks]
31 # one email for each incoming changeset
31 # one email for each incoming changeset
32 incoming.notify = python:hgext.notify.hook
32 incoming.notify = python:hgext.notify.hook
33 # batch emails when many changesets incoming at one time
33 # batch emails when many changesets incoming at one time
34 changegroup.notify = python:hgext.notify.hook
34 changegroup.notify = python:hgext.notify.hook
35
35
36 [notify]
36 [notify]
37 # config items go here
37 # config items go here
38
38
39 Required configuration items:
39 Required configuration items:
40
40
41 config = /path/to/file # file containing subscriptions
41 config = /path/to/file # file containing subscriptions
42
42
43 Optional configuration items:
43 Optional configuration items:
44
44
45 test = True # print messages to stdout for testing
45 test = True # print messages to stdout for testing
46 strip = 3 # number of slashes to strip for url paths
46 strip = 3 # number of slashes to strip for url paths
47 domain = example.com # domain to use if committer missing domain
47 domain = example.com # domain to use if committer missing domain
48 style = ... # style file to use when formatting email
48 style = ... # style file to use when formatting email
49 template = ... # template to use when formatting email
49 template = ... # template to use when formatting email
50 incoming = ... # template to use when run as incoming hook
50 incoming = ... # template to use when run as incoming hook
51 changegroup = ... # template when run as changegroup hook
51 changegroup = ... # template when run as changegroup hook
52 maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
52 maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
53 maxsubject = 67 # truncate subject line longer than this
53 maxsubject = 67 # truncate subject line longer than this
54 diffstat = True # add a diffstat before the diff content
54 diffstat = True # add a diffstat before the diff content
55 sources = serve # notify if source of incoming changes in this list
55 sources = serve # notify if source of incoming changes in this list
56 # (serve == ssh or http, push, pull, bundle)
56 # (serve == ssh or http, push, pull, bundle)
57 merge = False # send notification for merges (default True)
57 merge = False # send notification for merges (default True)
58 [email]
58 [email]
59 from = user@host.com # email address to send as if none given
59 from = user@host.com # email address to send as if none given
60 [web]
60 [web]
61 baseurl = http://hgserver/... # root of hg web site for browsing commits
61 baseurl = http://hgserver/... # root of hg web site for browsing commits
62
62
63 The notify config file has same format as a regular hgrc file. It has two
63 The notify config file has same format as a regular hgrc file. It has two
64 sections so you can express subscriptions in whatever way is handier for you.
64 sections so you can express subscriptions in whatever way is handier for you.
65
65
66 [usersubs]
66 [usersubs]
67 # key is subscriber email, value is ","-separated list of glob patterns
67 # key is subscriber email, value is ","-separated list of glob patterns
68 user@host = pattern
68 user@host = pattern
69
69
70 [reposubs]
70 [reposubs]
71 # key is glob pattern, value is ","-separated list of subscriber emails
71 # key is glob pattern, value is ","-separated list of subscriber emails
72 pattern = user@host
72 pattern = user@host
73
73
74 Glob patterns are matched against path to repository root.
74 Glob patterns are matched against path to repository root.
75
75
76 If you like, you can put notify config file in repository that users can push
76 If you like, you can put notify config file in repository that users can push
77 changes to, they can manage their own subscriptions.
77 changes to, they can manage their own subscriptions.
78
78
79 no commands defined
79 no commands defined
80 $ hg init a
80 $ hg init a
81 $ echo a > a/a
81 $ echo a > a/a
82
82
83 commit
83 commit
84
84
85 $ hg --cwd a commit -Ama -d '0 0'
85 $ hg --cwd a commit -Ama -d '0 0'
86 adding a
86 adding a
87
87
88
88
89 clone
89 clone
90
90
91 $ hg --traceback clone a b
91 $ hg --traceback clone a b
92 updating to branch default
92 updating to branch default
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 $ echo a >> a/a
94 $ echo a >> a/a
95
95
96 commit
96 commit
97
97
98 $ hg --traceback --cwd a commit -Amb -d '1 0'
98 $ hg --traceback --cwd a commit -Amb -d '1 0'
99
99
100 on Mac OS X 10.5 the tmp path is very long so would get stripped in the subject line
100 on Mac OS X 10.5 the tmp path is very long so would get stripped in the subject line
101
101
102 $ cat <<EOF >> $HGRCPATH
102 $ cat <<EOF >> $HGRCPATH
103 > [notify]
103 > [notify]
104 > maxsubject = 200
104 > maxsubject = 200
105 > EOF
105 > EOF
106
106
107 the python call below wraps continuation lines, which appear on Mac OS X 10.5 because
107 the python call below wraps continuation lines, which appear on Mac OS X 10.5 because
108 of the very long subject line
108 of the very long subject line
109 pull (minimal config)
109 pull (minimal config)
110
110
111 $ hg --traceback --cwd b pull ../a | \
111 $ hg --traceback --cwd b pull ../a | \
112 > python -c 'import sys,re; print re.sub("\n[\t ]", " ", sys.stdin.read()),'
112 > python -c 'import sys,re; print re.sub("\n[\t ]", " ", sys.stdin.read()),'
113 pulling from ../a
113 pulling from ../a
114 searching for changes
114 searching for changes
115 adding changesets
115 adding changesets
116 adding manifests
116 adding manifests
117 adding file changes
117 adding file changes
118 added 1 changesets with 1 changes to 1 files
118 added 1 changesets with 1 changes to 1 files
119 Content-Type: text/plain; charset="us-ascii"
119 Content-Type: text/plain; charset="us-ascii"
120 MIME-Version: 1.0
120 MIME-Version: 1.0
121 Content-Transfer-Encoding: 7bit
121 Content-Transfer-Encoding: 7bit
122 Date: * (glob)
122 Date: * (glob)
123 Subject: changeset in $TESTTMP/b: b
123 Subject: changeset in $TESTTMP/b: b
124 From: test
124 From: test
125 X-Hg-Notification: changeset 0647d048b600
125 X-Hg-Notification: changeset 0647d048b600
126 Message-Id: <*> (glob)
126 Message-Id: <*> (glob)
127 To: baz, foo@bar
127 To: baz, foo@bar
128
128
129 changeset 0647d048b600 in $TESTTMP/b
129 changeset 0647d048b600 in $TESTTMP/b
130 details: $TESTTMP/b?cmd=changeset;node=0647d048b600
130 details: $TESTTMP/b?cmd=changeset;node=0647d048b600
131 description: b
131 description: b
132
132
133 diffs (6 lines):
133 diffs (6 lines):
134
134
135 diff -r cb9a9f314b8b -r 0647d048b600 a
135 diff -r cb9a9f314b8b -r 0647d048b600 a
136 --- a/a Thu Jan 01 00:00:00 1970 +0000
136 --- a/a Thu Jan 01 00:00:00 1970 +0000
137 +++ b/a Thu Jan 01 00:00:01 1970 +0000
137 +++ b/a Thu Jan 01 00:00:01 1970 +0000
138 @@ -1,1 +1,2 @@ a
138 @@ -1,1 +1,2 @@ a
139 +a
139 +a
140 (run 'hg update' to get a working copy)
140 (run 'hg update' to get a working copy)
141 $ cat <<EOF >> $HGRCPATH
141 $ cat <<EOF >> $HGRCPATH
142 > [notify]
142 > [notify]
143 > config = `pwd`/.notify.conf
143 > config = `pwd`/.notify.conf
144 > domain = test.com
144 > domain = test.com
145 > strip = 42
145 > strip = 42
146 > template = Subject: {desc|firstline|strip}\nFrom: {author}\nX-Test: foo\n\nchangeset {node|short} in {webroot}\ndescription:\n\t{desc|tabindent|strip}
146 > template = Subject: {desc|firstline|strip}\nFrom: {author}\nX-Test: foo\n\nchangeset {node|short} in {webroot}\ndescription:\n\t{desc|tabindent|strip}
147 >
147 >
148 > [web]
148 > [web]
149 > baseurl = http://test/
149 > baseurl = http://test/
150 > EOF
150 > EOF
151
151
152 fail for config file is missing
152 fail for config file is missing
153
153
154 $ hg --cwd b rollback
154 $ hg --cwd b rollback
155 repository tip rolled back to revision 0 (undo pull)
155 repository tip rolled back to revision 0 (undo pull)
156 working directory now based on revision 0
156 working directory now based on revision 0
157 $ hg --cwd b pull ../a 2>&1 | grep 'error.*\.notify\.conf' > /dev/null && echo pull failed
157 $ hg --cwd b pull ../a 2>&1 | grep 'error.*\.notify\.conf' > /dev/null && echo pull failed
158 pull failed
158 pull failed
159 $ touch ".notify.conf"
159 $ touch ".notify.conf"
160
160
161 pull
161 pull
162
162
163 $ hg --cwd b rollback
163 $ hg --cwd b rollback
164 repository tip rolled back to revision 0 (undo pull)
164 repository tip rolled back to revision 0 (undo pull)
165 working directory now based on revision 0
165 working directory now based on revision 0
166 $ hg --traceback --cwd b pull ../a | \
166 $ hg --traceback --cwd b pull ../a | \
167 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
167 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
168 pulling from ../a
168 pulling from ../a
169 searching for changes
169 searching for changes
170 adding changesets
170 adding changesets
171 adding manifests
171 adding manifests
172 adding file changes
172 adding file changes
173 added 1 changesets with 1 changes to 1 files
173 added 1 changesets with 1 changes to 1 files
174 Content-Type: text/plain; charset="us-ascii"
174 Content-Type: text/plain; charset="us-ascii"
175 MIME-Version: 1.0
175 MIME-Version: 1.0
176 Content-Transfer-Encoding: 7bit
176 Content-Transfer-Encoding: 7bit
177 X-Test: foo
177 X-Test: foo
178 Date: * (glob)
178 Date: * (glob)
179 Subject: b
179 Subject: b
180 From: test@test.com
180 From: test@test.com
181 X-Hg-Notification: changeset 0647d048b600
181 X-Hg-Notification: changeset 0647d048b600
182 Message-Id: <*> (glob)
182 Message-Id: <*> (glob)
183 To: baz@test.com, foo@bar
183 To: baz@test.com, foo@bar
184
184
185 changeset 0647d048b600 in b
185 changeset 0647d048b600 in b
186 description: b
186 description: b
187 diffs (6 lines):
187 diffs (6 lines):
188
188
189 diff -r cb9a9f314b8b -r 0647d048b600 a
189 diff -r cb9a9f314b8b -r 0647d048b600 a
190 --- a/a Thu Jan 01 00:00:00 1970 +0000
190 --- a/a Thu Jan 01 00:00:00 1970 +0000
191 +++ b/a Thu Jan 01 00:00:01 1970 +0000
191 +++ b/a Thu Jan 01 00:00:01 1970 +0000
192 @@ -1,1 +1,2 @@
192 @@ -1,1 +1,2 @@
193 a
193 a
194 +a
194 +a
195 (run 'hg update' to get a working copy)
195 (run 'hg update' to get a working copy)
196
196
197 $ cat << EOF >> $HGRCPATH
197 $ cat << EOF >> $HGRCPATH
198 > [hooks]
198 > [hooks]
199 > incoming.notify = python:hgext.notify.hook
199 > incoming.notify = python:hgext.notify.hook
200 >
200 >
201 > [notify]
201 > [notify]
202 > sources = pull
202 > sources = pull
203 > diffstat = True
203 > diffstat = True
204 > EOF
204 > EOF
205
205
206 pull
206 pull
207
207
208 $ hg --cwd b rollback
208 $ hg --cwd b rollback
209 repository tip rolled back to revision 0 (undo pull)
209 repository tip rolled back to revision 0 (undo pull)
210 working directory now based on revision 0
210 working directory now based on revision 0
211 $ hg --traceback --cwd b pull ../a | \
211 $ hg --traceback --cwd b pull ../a | \
212 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
212 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
213 pulling from ../a
213 pulling from ../a
214 searching for changes
214 searching for changes
215 adding changesets
215 adding changesets
216 adding manifests
216 adding manifests
217 adding file changes
217 adding file changes
218 added 1 changesets with 1 changes to 1 files
218 added 1 changesets with 1 changes to 1 files
219 Content-Type: text/plain; charset="us-ascii"
219 Content-Type: text/plain; charset="us-ascii"
220 MIME-Version: 1.0
220 MIME-Version: 1.0
221 Content-Transfer-Encoding: 7bit
221 Content-Transfer-Encoding: 7bit
222 X-Test: foo
222 X-Test: foo
223 Date: * (glob)
223 Date: * (glob)
224 Subject: b
224 Subject: b
225 From: test@test.com
225 From: test@test.com
226 X-Hg-Notification: changeset 0647d048b600
226 X-Hg-Notification: changeset 0647d048b600
227 Message-Id: <*> (glob)
227 Message-Id: <*> (glob)
228 To: baz@test.com, foo@bar
228 To: baz@test.com, foo@bar
229
229
230 changeset 0647d048b600 in b
230 changeset 0647d048b600 in b
231 description: b
231 description: b
232 diffstat:
232 diffstat:
233
233
234 a | 1 +
234 a | 1 +
235 1 files changed, 1 insertions(+), 0 deletions(-)
235 1 files changed, 1 insertions(+), 0 deletions(-)
236
236
237 diffs (6 lines):
237 diffs (6 lines):
238
238
239 diff -r cb9a9f314b8b -r 0647d048b600 a
239 diff -r cb9a9f314b8b -r 0647d048b600 a
240 --- a/a Thu Jan 01 00:00:00 1970 +0000
240 --- a/a Thu Jan 01 00:00:00 1970 +0000
241 +++ b/a Thu Jan 01 00:00:01 1970 +0000
241 +++ b/a Thu Jan 01 00:00:01 1970 +0000
242 @@ -1,1 +1,2 @@
242 @@ -1,1 +1,2 @@
243 a
243 a
244 +a
244 +a
245 (run 'hg update' to get a working copy)
245 (run 'hg update' to get a working copy)
246
246
247 test merge
247 test merge
248
248
249 $ cd a
249 $ cd a
250 $ hg up -C 0
250 $ hg up -C 0
251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
251 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 $ echo a >> a
252 $ echo a >> a
253 $ hg ci -Am adda2 -d '2 0'
253 $ hg ci -Am adda2 -d '2 0'
254 created new head
254 created new head
255 $ hg merge
255 $ hg merge
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 (branch merge, don't forget to commit)
257 (branch merge, don't forget to commit)
258 $ hg ci -m merge -d '3 0'
258 $ hg ci -m merge -d '3 0'
259 $ cd ..
259 $ cd ..
260 $ hg --traceback --cwd b pull ../a | \
260 $ hg --traceback --cwd b pull ../a | \
261 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
261 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
262 pulling from ../a
262 pulling from ../a
263 searching for changes
263 searching for changes
264 adding changesets
264 adding changesets
265 adding manifests
265 adding manifests
266 adding file changes
266 adding file changes
267 added 2 changesets with 0 changes to 0 files
267 added 2 changesets with 0 changes to 0 files
268 Content-Type: text/plain; charset="us-ascii"
268 Content-Type: text/plain; charset="us-ascii"
269 MIME-Version: 1.0
269 MIME-Version: 1.0
270 Content-Transfer-Encoding: 7bit
270 Content-Transfer-Encoding: 7bit
271 X-Test: foo
271 X-Test: foo
272 Date: * (glob)
272 Date: * (glob)
273 Subject: adda2
273 Subject: adda2
274 From: test@test.com
274 From: test@test.com
275 X-Hg-Notification: changeset 0a184ce6067f
275 X-Hg-Notification: changeset 0a184ce6067f
276 Message-Id: <*> (glob)
276 Message-Id: <*> (glob)
277 To: baz@test.com, foo@bar
277 To: baz@test.com, foo@bar
278
278
279 changeset 0a184ce6067f in b
279 changeset 0a184ce6067f in b
280 description: adda2
280 description: adda2
281 diffstat:
281 diffstat:
282
282
283 a | 1 +
283 a | 1 +
284 1 files changed, 1 insertions(+), 0 deletions(-)
284 1 files changed, 1 insertions(+), 0 deletions(-)
285
285
286 diffs (6 lines):
286 diffs (6 lines):
287
287
288 diff -r cb9a9f314b8b -r 0a184ce6067f a
288 diff -r cb9a9f314b8b -r 0a184ce6067f a
289 --- a/a Thu Jan 01 00:00:00 1970 +0000
289 --- a/a Thu Jan 01 00:00:00 1970 +0000
290 +++ b/a Thu Jan 01 00:00:02 1970 +0000
290 +++ b/a Thu Jan 01 00:00:02 1970 +0000
291 @@ -1,1 +1,2 @@
291 @@ -1,1 +1,2 @@
292 a
292 a
293 +a
293 +a
294 Content-Type: text/plain; charset="us-ascii"
294 Content-Type: text/plain; charset="us-ascii"
295 MIME-Version: 1.0
295 MIME-Version: 1.0
296 Content-Transfer-Encoding: 7bit
296 Content-Transfer-Encoding: 7bit
297 X-Test: foo
297 X-Test: foo
298 Date: * (glob)
298 Date: * (glob)
299 Subject: merge
299 Subject: merge
300 From: test@test.com
300 From: test@test.com
301 X-Hg-Notification: changeset 22c88b85aa27
301 X-Hg-Notification: changeset 6a0cf76b2701
302 Message-Id: <*> (glob)
302 Message-Id: <*> (glob)
303 To: baz@test.com, foo@bar
303 To: baz@test.com, foo@bar
304
304
305 changeset 22c88b85aa27 in b
305 changeset 6a0cf76b2701 in b
306 description: merge
306 description: merge
307 (run 'hg update' to get a working copy)
307 (run 'hg update' to get a working copy)
308
308
309 truncate multi-byte subject
309 truncate multi-byte subject
310
310
311 $ cat <<EOF >> $HGRCPATH
311 $ cat <<EOF >> $HGRCPATH
312 > [notify]
312 > [notify]
313 > maxsubject = 4
313 > maxsubject = 4
314 > EOF
314 > EOF
315 $ echo a >> a/a
315 $ echo a >> a/a
316 $ hg --cwd a --encoding utf-8 commit -A -d '0 0' \
316 $ hg --cwd a --encoding utf-8 commit -A -d '0 0' \
317 > -m `python -c 'print "\xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4"'`
317 > -m `python -c 'print "\xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4"'`
318 $ hg --traceback --cwd b --encoding utf-8 pull ../a | \
318 $ hg --traceback --cwd b --encoding utf-8 pull ../a | \
319 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
319 > python -c 'import sys,re; print re.sub("\n\t", " ", sys.stdin.read()),'
320 pulling from ../a
320 pulling from ../a
321 searching for changes
321 searching for changes
322 adding changesets
322 adding changesets
323 adding manifests
323 adding manifests
324 adding file changes
324 adding file changes
325 added 1 changesets with 1 changes to 1 files
325 added 1 changesets with 1 changes to 1 files
326 Content-Type: text/plain; charset="us-ascii"
326 Content-Type: text/plain; charset="us-ascii"
327 MIME-Version: 1.0
327 MIME-Version: 1.0
328 Content-Transfer-Encoding: 8bit
328 Content-Transfer-Encoding: 8bit
329 X-Test: foo
329 X-Test: foo
330 Date: * (glob)
330 Date: * (glob)
331 Subject: \xc3\xa0... (esc)
331 Subject: \xc3\xa0... (esc)
332 From: test@test.com
332 From: test@test.com
333 X-Hg-Notification: changeset 4a47f01c1356
333 X-Hg-Notification: changeset 7ea05ad269dc
334 Message-Id: <*> (glob)
334 Message-Id: <*> (glob)
335 To: baz@test.com, foo@bar
335 To: baz@test.com, foo@bar
336
336
337 changeset 4a47f01c1356 in b
337 changeset 7ea05ad269dc in b
338 description: \xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4 (esc)
338 description: \xc3\xa0\xc3\xa1\xc3\xa2\xc3\xa3\xc3\xa4 (esc)
339 diffstat:
339 diffstat:
340
340
341 a | 1 +
341 a | 1 +
342 1 files changed, 1 insertions(+), 0 deletions(-)
342 1 files changed, 1 insertions(+), 0 deletions(-)
343
343
344 diffs (7 lines):
344 diffs (7 lines):
345
345
346 diff -r 22c88b85aa27 -r 4a47f01c1356 a
346 diff -r 6a0cf76b2701 -r 7ea05ad269dc a
347 --- a/a Thu Jan 01 00:00:03 1970 +0000
347 --- a/a Thu Jan 01 00:00:03 1970 +0000
348 +++ b/a Thu Jan 01 00:00:00 1970 +0000
348 +++ b/a Thu Jan 01 00:00:00 1970 +0000
349 @@ -1,2 +1,3 @@
349 @@ -1,2 +1,3 @@
350 a
350 a
351 a
351 a
352 +a
352 +a
353 (run 'hg update' to get a working copy)
353 (run 'hg update' to get a working copy)
@@ -1,103 +1,103
1 $ hg init repo
1 $ hg init repo
2 $ cd repo
2 $ cd repo
3 $ echo foo > foo
3 $ echo foo > foo
4 $ hg ci -qAm 'add foo'
4 $ hg ci -qAm 'add foo'
5 $ echo >> foo
5 $ echo >> foo
6 $ hg ci -m 'change foo'
6 $ hg ci -m 'change foo'
7 $ hg up -qC 0
7 $ hg up -qC 0
8 $ echo bar > bar
8 $ echo bar > bar
9 $ hg ci -qAm 'add bar'
9 $ hg ci -qAm 'add bar'
10
10
11 $ hg log
11 $ hg log
12 changeset: 2:effea6de0384
12 changeset: 2:effea6de0384
13 tag: tip
13 tag: tip
14 parent: 0:bbd179dfa0a7
14 parent: 0:bbd179dfa0a7
15 user: test
15 user: test
16 date: Thu Jan 01 00:00:00 1970 +0000
16 date: Thu Jan 01 00:00:00 1970 +0000
17 summary: add bar
17 summary: add bar
18
18
19 changeset: 1:ed1b79f46b9a
19 changeset: 1:ed1b79f46b9a
20 user: test
20 user: test
21 date: Thu Jan 01 00:00:00 1970 +0000
21 date: Thu Jan 01 00:00:00 1970 +0000
22 summary: change foo
22 summary: change foo
23
23
24 changeset: 0:bbd179dfa0a7
24 changeset: 0:bbd179dfa0a7
25 user: test
25 user: test
26 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
27 summary: add foo
27 summary: add foo
28
28
29 $ cd ..
29 $ cd ..
30
30
31 don't show "(+1 heads)" message when pulling closed head
31 don't show "(+1 heads)" message when pulling closed head
32
32
33 $ hg clone -q repo repo2
33 $ hg clone -q repo repo2
34 $ hg clone -q repo2 repo3
34 $ hg clone -q repo2 repo3
35 $ cd repo2
35 $ cd repo2
36 $ hg up -q 0
36 $ hg up -q 0
37 $ echo hello >> foo
37 $ echo hello >> foo
38 $ hg ci -mx1
38 $ hg ci -mx1
39 created new head
39 created new head
40 $ hg ci -mx2 --close-branch
40 $ hg ci -mx2 --close-branch
41 $ cd ../repo3
41 $ cd ../repo3
42 $ hg heads -q --closed
42 $ hg heads -q --closed
43 2:effea6de0384
43 2:effea6de0384
44 1:ed1b79f46b9a
44 1:ed1b79f46b9a
45 $ hg pull
45 $ hg pull
46 pulling from $TESTTMP/repo2
46 pulling from $TESTTMP/repo2
47 searching for changes
47 searching for changes
48 adding changesets
48 adding changesets
49 adding manifests
49 adding manifests
50 adding file changes
50 adding file changes
51 added 2 changesets with 1 changes to 1 files
51 added 2 changesets with 1 changes to 1 files
52 (run 'hg update' to get a working copy)
52 (run 'hg update' to get a working copy)
53 $ hg heads -q --closed
53 $ hg heads -q --closed
54 4:996201fa1abf
54 4:00cfe9073916
55 2:effea6de0384
55 2:effea6de0384
56 1:ed1b79f46b9a
56 1:ed1b79f46b9a
57
57
58 $ cd ..
58 $ cd ..
59
59
60 $ hg init copy
60 $ hg init copy
61 $ cd copy
61 $ cd copy
62
62
63 Pull a missing revision:
63 Pull a missing revision:
64
64
65 $ hg pull -qr missing ../repo
65 $ hg pull -qr missing ../repo
66 abort: unknown revision 'missing'!
66 abort: unknown revision 'missing'!
67 [255]
67 [255]
68
68
69 Pull multiple revisions with update:
69 Pull multiple revisions with update:
70
70
71 $ hg pull -qu -r 0 -r 1 ../repo
71 $ hg pull -qu -r 0 -r 1 ../repo
72 $ hg -q parents
72 $ hg -q parents
73 0:bbd179dfa0a7
73 0:bbd179dfa0a7
74 $ hg rollback
74 $ hg rollback
75 repository tip rolled back to revision -1 (undo pull)
75 repository tip rolled back to revision -1 (undo pull)
76 working directory now based on revision -1
76 working directory now based on revision -1
77
77
78 $ hg pull -qr 0 ../repo
78 $ hg pull -qr 0 ../repo
79 $ hg log
79 $ hg log
80 changeset: 0:bbd179dfa0a7
80 changeset: 0:bbd179dfa0a7
81 tag: tip
81 tag: tip
82 user: test
82 user: test
83 date: Thu Jan 01 00:00:00 1970 +0000
83 date: Thu Jan 01 00:00:00 1970 +0000
84 summary: add foo
84 summary: add foo
85
85
86 $ hg pull -qr 1 ../repo
86 $ hg pull -qr 1 ../repo
87 $ hg log
87 $ hg log
88 changeset: 1:ed1b79f46b9a
88 changeset: 1:ed1b79f46b9a
89 tag: tip
89 tag: tip
90 user: test
90 user: test
91 date: Thu Jan 01 00:00:00 1970 +0000
91 date: Thu Jan 01 00:00:00 1970 +0000
92 summary: change foo
92 summary: change foo
93
93
94 changeset: 0:bbd179dfa0a7
94 changeset: 0:bbd179dfa0a7
95 user: test
95 user: test
96 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
97 summary: add foo
97 summary: add foo
98
98
99
99
100 This used to abort: received changelog group is empty:
100 This used to abort: received changelog group is empty:
101
101
102 $ hg pull -qr 1 ../repo
102 $ hg pull -qr 1 ../repo
103
103
@@ -1,257 +1,257
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > rebase=
4 > rebase=
5 >
5 >
6 > [alias]
6 > [alias]
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 > theads = heads --template "{rev}: '{desc}' {branches}\n"
8 > theads = heads --template "{rev}: '{desc}' {branches}\n"
9 > EOF
9 > EOF
10
10
11 $ hg init a
11 $ hg init a
12 $ cd a
12 $ cd a
13
13
14 $ echo a > a
14 $ echo a > a
15 $ hg ci -Am A
15 $ hg ci -Am A
16 adding a
16 adding a
17
17
18 $ hg branch branch1
18 $ hg branch branch1
19 marked working directory as branch branch1
19 marked working directory as branch branch1
20 $ hg ci -m 'branch1'
20 $ hg ci -m 'branch1'
21
21
22 $ echo b > b
22 $ echo b > b
23 $ hg ci -Am B
23 $ hg ci -Am B
24 adding b
24 adding b
25
25
26 $ hg up -q 0
26 $ hg up -q 0
27
27
28 $ hg branch branch2
28 $ hg branch branch2
29 marked working directory as branch branch2
29 marked working directory as branch branch2
30 $ hg ci -m 'branch2'
30 $ hg ci -m 'branch2'
31
31
32 $ echo c > C
32 $ echo c > C
33 $ hg ci -Am C
33 $ hg ci -Am C
34 adding C
34 adding C
35
35
36 $ hg up -q 2
36 $ hg up -q 2
37
37
38 $ hg branch -f branch2
38 $ hg branch -f branch2
39 marked working directory as branch branch2
39 marked working directory as branch branch2
40 $ echo d > d
40 $ echo d > d
41 $ hg ci -Am D
41 $ hg ci -Am D
42 adding d
42 adding d
43 created new head
43 created new head
44
44
45 $ echo e > e
45 $ echo e > e
46 $ hg ci -Am E
46 $ hg ci -Am E
47 adding e
47 adding e
48
48
49 $ hg update default
49 $ hg update default
50 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
50 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
51
51
52 $ hg branch branch3
52 $ hg branch branch3
53 marked working directory as branch branch3
53 marked working directory as branch branch3
54 $ hg ci -m 'branch3'
54 $ hg ci -m 'branch3'
55
55
56 $ echo f > f
56 $ echo f > f
57 $ hg ci -Am F
57 $ hg ci -Am F
58 adding f
58 adding f
59
59
60 $ cd ..
60 $ cd ..
61
61
62
62
63 Rebase part of branch2 (5-6) onto branch3 (8):
63 Rebase part of branch2 (5-6) onto branch3 (8):
64
64
65 $ hg clone -q -u . a a1
65 $ hg clone -q -u . a a1
66 $ cd a1
66 $ cd a1
67
67
68 $ hg tglog
68 $ hg tglog
69 @ 8: 'F' branch3
69 @ 8: 'F' branch3
70 |
70 |
71 o 7: 'branch3' branch3
71 o 7: 'branch3' branch3
72 |
72 |
73 | o 6: 'E' branch2
73 | o 6: 'E' branch2
74 | |
74 | |
75 | o 5: 'D' branch2
75 | o 5: 'D' branch2
76 | |
76 | |
77 | | o 4: 'C' branch2
77 | | o 4: 'C' branch2
78 | | |
78 | | |
79 +---o 3: 'branch2' branch2
79 +---o 3: 'branch2' branch2
80 | |
80 | |
81 | o 2: 'B' branch1
81 | o 2: 'B' branch1
82 | |
82 | |
83 | o 1: 'branch1' branch1
83 | o 1: 'branch1' branch1
84 |/
84 |/
85 o 0: 'A'
85 o 0: 'A'
86
86
87 $ hg branches
87 $ hg branches
88 branch3 8:05b64c4ca2d8
88 branch3 8:4666b71e8e32
89 branch2 6:b410fbec727a
89 branch2 6:5097051d331d
90 branch1 2:9d931918fcf7 (inactive)
90 branch1 2:0a03079c47fd (inactive)
91 default 0:1994f17a630e (inactive)
91 default 0:1994f17a630e (inactive)
92
92
93 $ hg theads
93 $ hg theads
94 8: 'F' branch3
94 8: 'F' branch3
95 6: 'E' branch2
95 6: 'E' branch2
96 4: 'C' branch2
96 4: 'C' branch2
97 2: 'B' branch1
97 2: 'B' branch1
98 0: 'A'
98 0: 'A'
99
99
100 $ hg rebase --detach -s 5 -d 8
100 $ hg rebase --detach -s 5 -d 8
101 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
101 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
102
102
103 $ hg branches
103 $ hg branches
104 branch3 8:c1d4b9719987
104 branch3 8:466cdfb14b62
105 branch2 4:1be2b203ae5e
105 branch2 4:e4fdb121d036
106 branch1 2:9d931918fcf7
106 branch1 2:0a03079c47fd
107 default 0:1994f17a630e (inactive)
107 default 0:1994f17a630e (inactive)
108
108
109 $ hg theads
109 $ hg theads
110 8: 'E' branch3
110 8: 'E' branch3
111 4: 'C' branch2
111 4: 'C' branch2
112 2: 'B' branch1
112 2: 'B' branch1
113 0: 'A'
113 0: 'A'
114
114
115 $ hg tglog
115 $ hg tglog
116 @ 8: 'E' branch3
116 @ 8: 'E' branch3
117 |
117 |
118 o 7: 'D' branch3
118 o 7: 'D' branch3
119 |
119 |
120 o 6: 'F' branch3
120 o 6: 'F' branch3
121 |
121 |
122 o 5: 'branch3' branch3
122 o 5: 'branch3' branch3
123 |
123 |
124 | o 4: 'C' branch2
124 | o 4: 'C' branch2
125 | |
125 | |
126 | o 3: 'branch2' branch2
126 | o 3: 'branch2' branch2
127 |/
127 |/
128 | o 2: 'B' branch1
128 | o 2: 'B' branch1
129 | |
129 | |
130 | o 1: 'branch1' branch1
130 | o 1: 'branch1' branch1
131 |/
131 |/
132 o 0: 'A'
132 o 0: 'A'
133
133
134 $ cd ..
134 $ cd ..
135
135
136
136
137 Rebase head of branch3 (8) onto branch2 (6):
137 Rebase head of branch3 (8) onto branch2 (6):
138
138
139 $ hg clone -q -u . a a2
139 $ hg clone -q -u . a a2
140 $ cd a2
140 $ cd a2
141
141
142 $ hg tglog
142 $ hg tglog
143 @ 8: 'F' branch3
143 @ 8: 'F' branch3
144 |
144 |
145 o 7: 'branch3' branch3
145 o 7: 'branch3' branch3
146 |
146 |
147 | o 6: 'E' branch2
147 | o 6: 'E' branch2
148 | |
148 | |
149 | o 5: 'D' branch2
149 | o 5: 'D' branch2
150 | |
150 | |
151 | | o 4: 'C' branch2
151 | | o 4: 'C' branch2
152 | | |
152 | | |
153 +---o 3: 'branch2' branch2
153 +---o 3: 'branch2' branch2
154 | |
154 | |
155 | o 2: 'B' branch1
155 | o 2: 'B' branch1
156 | |
156 | |
157 | o 1: 'branch1' branch1
157 | o 1: 'branch1' branch1
158 |/
158 |/
159 o 0: 'A'
159 o 0: 'A'
160
160
161 $ hg rebase --detach -s 8 -d 6
161 $ hg rebase --detach -s 8 -d 6
162 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
162 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
163
163
164 $ hg branches
164 $ hg branches
165 branch2 8:e1e80ed73210
165 branch2 8:6b4bdc1b5ac0
166 branch3 7:75fd7b643dce
166 branch3 7:653b9feb4616
167 branch1 2:9d931918fcf7 (inactive)
167 branch1 2:0a03079c47fd (inactive)
168 default 0:1994f17a630e (inactive)
168 default 0:1994f17a630e (inactive)
169
169
170 $ hg theads
170 $ hg theads
171 8: 'F' branch2
171 8: 'F' branch2
172 7: 'branch3' branch3
172 7: 'branch3' branch3
173 4: 'C' branch2
173 4: 'C' branch2
174 2: 'B' branch1
174 2: 'B' branch1
175 0: 'A'
175 0: 'A'
176
176
177 $ hg tglog
177 $ hg tglog
178 @ 8: 'F' branch2
178 @ 8: 'F' branch2
179 |
179 |
180 | o 7: 'branch3' branch3
180 | o 7: 'branch3' branch3
181 | |
181 | |
182 o | 6: 'E' branch2
182 o | 6: 'E' branch2
183 | |
183 | |
184 o | 5: 'D' branch2
184 o | 5: 'D' branch2
185 | |
185 | |
186 | | o 4: 'C' branch2
186 | | o 4: 'C' branch2
187 | | |
187 | | |
188 | | o 3: 'branch2' branch2
188 | | o 3: 'branch2' branch2
189 | |/
189 | |/
190 o | 2: 'B' branch1
190 o | 2: 'B' branch1
191 | |
191 | |
192 o | 1: 'branch1' branch1
192 o | 1: 'branch1' branch1
193 |/
193 |/
194 o 0: 'A'
194 o 0: 'A'
195
195
196 $ hg verify -q
196 $ hg verify -q
197
197
198 $ cd ..
198 $ cd ..
199
199
200
200
201 Rebase entire branch3 (7-8) onto branch2 (6):
201 Rebase entire branch3 (7-8) onto branch2 (6):
202
202
203 $ hg clone -q -u . a a3
203 $ hg clone -q -u . a a3
204 $ cd a3
204 $ cd a3
205
205
206 $ hg tglog
206 $ hg tglog
207 @ 8: 'F' branch3
207 @ 8: 'F' branch3
208 |
208 |
209 o 7: 'branch3' branch3
209 o 7: 'branch3' branch3
210 |
210 |
211 | o 6: 'E' branch2
211 | o 6: 'E' branch2
212 | |
212 | |
213 | o 5: 'D' branch2
213 | o 5: 'D' branch2
214 | |
214 | |
215 | | o 4: 'C' branch2
215 | | o 4: 'C' branch2
216 | | |
216 | | |
217 +---o 3: 'branch2' branch2
217 +---o 3: 'branch2' branch2
218 | |
218 | |
219 | o 2: 'B' branch1
219 | o 2: 'B' branch1
220 | |
220 | |
221 | o 1: 'branch1' branch1
221 | o 1: 'branch1' branch1
222 |/
222 |/
223 o 0: 'A'
223 o 0: 'A'
224
224
225 $ hg rebase --detach -s 7 -d 6
225 $ hg rebase --detach -s 7 -d 6
226 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
226 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
227
227
228 $ hg branches
228 $ hg branches
229 branch2 7:e1e80ed73210
229 branch2 7:6b4bdc1b5ac0
230 branch1 2:9d931918fcf7 (inactive)
230 branch1 2:0a03079c47fd (inactive)
231 default 0:1994f17a630e (inactive)
231 default 0:1994f17a630e (inactive)
232
232
233 $ hg theads
233 $ hg theads
234 7: 'F' branch2
234 7: 'F' branch2
235 4: 'C' branch2
235 4: 'C' branch2
236 2: 'B' branch1
236 2: 'B' branch1
237 0: 'A'
237 0: 'A'
238
238
239 $ hg tglog
239 $ hg tglog
240 @ 7: 'F' branch2
240 @ 7: 'F' branch2
241 |
241 |
242 o 6: 'E' branch2
242 o 6: 'E' branch2
243 |
243 |
244 o 5: 'D' branch2
244 o 5: 'D' branch2
245 |
245 |
246 | o 4: 'C' branch2
246 | o 4: 'C' branch2
247 | |
247 | |
248 | o 3: 'branch2' branch2
248 | o 3: 'branch2' branch2
249 | |
249 | |
250 o | 2: 'B' branch1
250 o | 2: 'B' branch1
251 | |
251 | |
252 o | 1: 'branch1' branch1
252 o | 1: 'branch1' branch1
253 |/
253 |/
254 o 0: 'A'
254 o 0: 'A'
255
255
256 $ hg verify -q
256 $ hg verify -q
257
257
@@ -1,298 +1,298
1 $ hg init test
1 $ hg init test
2 $ cd test
2 $ cd test
3
3
4 $ echo a > a
4 $ echo a > a
5 $ hg add a
5 $ hg add a
6 $ hg commit -m "test"
6 $ hg commit -m "test"
7 $ hg history
7 $ hg history
8 changeset: 0:acb14030fe0a
8 changeset: 0:acb14030fe0a
9 tag: tip
9 tag: tip
10 user: test
10 user: test
11 date: Thu Jan 01 00:00:00 1970 +0000
11 date: Thu Jan 01 00:00:00 1970 +0000
12 summary: test
12 summary: test
13
13
14
14
15 $ hg tag ' '
15 $ hg tag ' '
16 abort: tag names cannot consist entirely of whitespace
16 abort: tag names cannot consist entirely of whitespace
17 [255]
17 [255]
18
18
19 $ hg tag "bleah"
19 $ hg tag "bleah"
20 $ hg history
20 $ hg history
21 changeset: 1:d4f0d2909abc
21 changeset: 1:d4f0d2909abc
22 tag: tip
22 tag: tip
23 user: test
23 user: test
24 date: Thu Jan 01 00:00:00 1970 +0000
24 date: Thu Jan 01 00:00:00 1970 +0000
25 summary: Added tag bleah for changeset acb14030fe0a
25 summary: Added tag bleah for changeset acb14030fe0a
26
26
27 changeset: 0:acb14030fe0a
27 changeset: 0:acb14030fe0a
28 tag: bleah
28 tag: bleah
29 user: test
29 user: test
30 date: Thu Jan 01 00:00:00 1970 +0000
30 date: Thu Jan 01 00:00:00 1970 +0000
31 summary: test
31 summary: test
32
32
33
33
34 $ echo foo >> .hgtags
34 $ echo foo >> .hgtags
35 $ hg tag "bleah2"
35 $ hg tag "bleah2"
36 abort: working copy of .hgtags is changed (please commit .hgtags manually)
36 abort: working copy of .hgtags is changed (please commit .hgtags manually)
37 [255]
37 [255]
38
38
39 $ hg revert .hgtags
39 $ hg revert .hgtags
40 $ hg tag -r 0 x y z y y z
40 $ hg tag -r 0 x y z y y z
41 abort: tag names must be unique
41 abort: tag names must be unique
42 [255]
42 [255]
43 $ hg tag tap nada dot tip null .
43 $ hg tag tap nada dot tip null .
44 abort: the name 'tip' is reserved
44 abort: the name 'tip' is reserved
45 [255]
45 [255]
46 $ hg tag "bleah"
46 $ hg tag "bleah"
47 abort: tag 'bleah' already exists (use -f to force)
47 abort: tag 'bleah' already exists (use -f to force)
48 [255]
48 [255]
49 $ hg tag "blecch" "bleah"
49 $ hg tag "blecch" "bleah"
50 abort: tag 'bleah' already exists (use -f to force)
50 abort: tag 'bleah' already exists (use -f to force)
51 [255]
51 [255]
52
52
53 $ hg tag --remove "blecch"
53 $ hg tag --remove "blecch"
54 abort: tag 'blecch' does not exist
54 abort: tag 'blecch' does not exist
55 [255]
55 [255]
56 $ hg tag --remove "bleah" "blecch" "blough"
56 $ hg tag --remove "bleah" "blecch" "blough"
57 abort: tag 'blecch' does not exist
57 abort: tag 'blecch' does not exist
58 [255]
58 [255]
59
59
60 $ hg tag -r 0 "bleah0"
60 $ hg tag -r 0 "bleah0"
61 $ hg tag -l -r 1 "bleah1"
61 $ hg tag -l -r 1 "bleah1"
62 $ hg tag gack gawk gorp
62 $ hg tag gack gawk gorp
63 $ hg tag -f gack
63 $ hg tag -f gack
64 $ hg tag --remove gack gorp
64 $ hg tag --remove gack gorp
65
65
66 $ hg tag "bleah "
66 $ hg tag "bleah "
67 abort: tag 'bleah' already exists (use -f to force)
67 abort: tag 'bleah' already exists (use -f to force)
68 [255]
68 [255]
69 $ hg tag " bleah"
69 $ hg tag " bleah"
70 abort: tag 'bleah' already exists (use -f to force)
70 abort: tag 'bleah' already exists (use -f to force)
71 [255]
71 [255]
72 $ hg tag " bleah"
72 $ hg tag " bleah"
73 abort: tag 'bleah' already exists (use -f to force)
73 abort: tag 'bleah' already exists (use -f to force)
74 [255]
74 [255]
75 $ hg tag -r 0 " bleahbleah "
75 $ hg tag -r 0 " bleahbleah "
76 $ hg tag -r 0 " bleah bleah "
76 $ hg tag -r 0 " bleah bleah "
77
77
78 $ cat .hgtags
78 $ cat .hgtags
79 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
79 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah
80 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
80 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah0
81 336fccc858a4eb69609a291105009e484a6b6b8d gack
81 336fccc858a4eb69609a291105009e484a6b6b8d gack
82 336fccc858a4eb69609a291105009e484a6b6b8d gawk
82 336fccc858a4eb69609a291105009e484a6b6b8d gawk
83 336fccc858a4eb69609a291105009e484a6b6b8d gorp
83 336fccc858a4eb69609a291105009e484a6b6b8d gorp
84 336fccc858a4eb69609a291105009e484a6b6b8d gack
84 336fccc858a4eb69609a291105009e484a6b6b8d gack
85 799667b6f2d9b957f73fa644a918c2df22bab58f gack
85 799667b6f2d9b957f73fa644a918c2df22bab58f gack
86 799667b6f2d9b957f73fa644a918c2df22bab58f gack
86 799667b6f2d9b957f73fa644a918c2df22bab58f gack
87 0000000000000000000000000000000000000000 gack
87 0000000000000000000000000000000000000000 gack
88 336fccc858a4eb69609a291105009e484a6b6b8d gorp
88 336fccc858a4eb69609a291105009e484a6b6b8d gorp
89 0000000000000000000000000000000000000000 gorp
89 0000000000000000000000000000000000000000 gorp
90 acb14030fe0a21b60322c440ad2d20cf7685a376 bleahbleah
90 acb14030fe0a21b60322c440ad2d20cf7685a376 bleahbleah
91 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah bleah
91 acb14030fe0a21b60322c440ad2d20cf7685a376 bleah bleah
92
92
93 $ cat .hg/localtags
93 $ cat .hg/localtags
94 d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
94 d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
95
95
96 tagging on a non-head revision
96 tagging on a non-head revision
97
97
98 $ hg update 0
98 $ hg update 0
99 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
99 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
100 $ hg tag -l localblah
100 $ hg tag -l localblah
101 $ hg tag "foobar"
101 $ hg tag "foobar"
102 abort: not at a branch head (use -f to force)
102 abort: not at a branch head (use -f to force)
103 [255]
103 [255]
104 $ hg tag -f "foobar"
104 $ hg tag -f "foobar"
105 $ cat .hgtags
105 $ cat .hgtags
106 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
106 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
107 $ cat .hg/localtags
107 $ cat .hg/localtags
108 d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
108 d4f0d2909abc9290e2773c08837d70c1794e3f5a bleah1
109 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
109 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
110
110
111 $ hg tag -l 'xx
111 $ hg tag -l 'xx
112 > newline'
112 > newline'
113 abort: '\n' cannot be used in a tag name
113 abort: '\n' cannot be used in a tag name
114 [255]
114 [255]
115 $ hg tag -l 'xx:xx'
115 $ hg tag -l 'xx:xx'
116 abort: ':' cannot be used in a tag name
116 abort: ':' cannot be used in a tag name
117 [255]
117 [255]
118
118
119 cloning local tags
119 cloning local tags
120
120
121 $ cd ..
121 $ cd ..
122 $ hg -R test log -r0:5
122 $ hg -R test log -r0:5
123 changeset: 0:acb14030fe0a
123 changeset: 0:acb14030fe0a
124 tag: bleah
124 tag: bleah
125 tag: bleah bleah
125 tag: bleah bleah
126 tag: bleah0
126 tag: bleah0
127 tag: bleahbleah
127 tag: bleahbleah
128 tag: foobar
128 tag: foobar
129 tag: localblah
129 tag: localblah
130 user: test
130 user: test
131 date: Thu Jan 01 00:00:00 1970 +0000
131 date: Thu Jan 01 00:00:00 1970 +0000
132 summary: test
132 summary: test
133
133
134 changeset: 1:d4f0d2909abc
134 changeset: 1:d4f0d2909abc
135 tag: bleah1
135 tag: bleah1
136 user: test
136 user: test
137 date: Thu Jan 01 00:00:00 1970 +0000
137 date: Thu Jan 01 00:00:00 1970 +0000
138 summary: Added tag bleah for changeset acb14030fe0a
138 summary: Added tag bleah for changeset acb14030fe0a
139
139
140 changeset: 2:336fccc858a4
140 changeset: 2:336fccc858a4
141 tag: gawk
141 tag: gawk
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
143 date: Thu Jan 01 00:00:00 1970 +0000
144 summary: Added tag bleah0 for changeset acb14030fe0a
144 summary: Added tag bleah0 for changeset acb14030fe0a
145
145
146 changeset: 3:799667b6f2d9
146 changeset: 3:799667b6f2d9
147 user: test
147 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
148 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: Added tag gack, gawk, gorp for changeset 336fccc858a4
149 summary: Added tag gack, gawk, gorp for changeset 336fccc858a4
150
150
151 changeset: 4:154eeb7c0138
151 changeset: 4:154eeb7c0138
152 user: test
152 user: test
153 date: Thu Jan 01 00:00:00 1970 +0000
153 date: Thu Jan 01 00:00:00 1970 +0000
154 summary: Added tag gack for changeset 799667b6f2d9
154 summary: Added tag gack for changeset 799667b6f2d9
155
155
156 changeset: 5:b4bb47aaff09
156 changeset: 5:b4bb47aaff09
157 user: test
157 user: test
158 date: Thu Jan 01 00:00:00 1970 +0000
158 date: Thu Jan 01 00:00:00 1970 +0000
159 summary: Removed tag gack, gorp
159 summary: Removed tag gack, gorp
160
160
161 $ hg clone -q -rbleah1 test test1
161 $ hg clone -q -rbleah1 test test1
162 $ hg -R test1 parents --style=compact
162 $ hg -R test1 parents --style=compact
163 1[tip] d4f0d2909abc 1970-01-01 00:00 +0000 test
163 1[tip] d4f0d2909abc 1970-01-01 00:00 +0000 test
164 Added tag bleah for changeset acb14030fe0a
164 Added tag bleah for changeset acb14030fe0a
165
165
166 $ hg clone -q -r5 test#bleah1 test2
166 $ hg clone -q -r5 test#bleah1 test2
167 $ hg -R test2 parents --style=compact
167 $ hg -R test2 parents --style=compact
168 5[tip] b4bb47aaff09 1970-01-01 00:00 +0000 test
168 5[tip] b4bb47aaff09 1970-01-01 00:00 +0000 test
169 Removed tag gack, gorp
169 Removed tag gack, gorp
170
170
171 $ hg clone -q -U test#bleah1 test3
171 $ hg clone -q -U test#bleah1 test3
172 $ hg -R test3 parents --style=compact
172 $ hg -R test3 parents --style=compact
173
173
174 $ cd test
174 $ cd test
175
175
176 Issue601: hg tag doesn't do the right thing if .hgtags or localtags
176 Issue601: hg tag doesn't do the right thing if .hgtags or localtags
177 doesn't end with EOL
177 doesn't end with EOL
178
178
179 $ python << EOF
179 $ python << EOF
180 > f = file('.hg/localtags'); last = f.readlines()[-1][:-1]; f.close()
180 > f = file('.hg/localtags'); last = f.readlines()[-1][:-1]; f.close()
181 > f = file('.hg/localtags', 'w'); f.write(last); f.close()
181 > f = file('.hg/localtags', 'w'); f.write(last); f.close()
182 > EOF
182 > EOF
183 $ cat .hg/localtags; echo
183 $ cat .hg/localtags; echo
184 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
184 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
185 $ hg tag -l localnewline
185 $ hg tag -l localnewline
186 $ cat .hg/localtags; echo
186 $ cat .hg/localtags; echo
187 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
187 acb14030fe0a21b60322c440ad2d20cf7685a376 localblah
188 c2899151f4e76890c602a2597a650a72666681bf localnewline
188 c2899151f4e76890c602a2597a650a72666681bf localnewline
189
189
190
190
191 $ python << EOF
191 $ python << EOF
192 > f = file('.hgtags'); last = f.readlines()[-1][:-1]; f.close()
192 > f = file('.hgtags'); last = f.readlines()[-1][:-1]; f.close()
193 > f = file('.hgtags', 'w'); f.write(last); f.close()
193 > f = file('.hgtags', 'w'); f.write(last); f.close()
194 > EOF
194 > EOF
195 $ hg ci -m'broken manual edit of .hgtags'
195 $ hg ci -m'broken manual edit of .hgtags'
196 $ cat .hgtags; echo
196 $ cat .hgtags; echo
197 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
197 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
198 $ hg tag newline
198 $ hg tag newline
199 $ cat .hgtags; echo
199 $ cat .hgtags; echo
200 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
200 acb14030fe0a21b60322c440ad2d20cf7685a376 foobar
201 a0eea09de1eeec777b46f2085260a373b2fbc293 newline
201 a0eea09de1eeec777b46f2085260a373b2fbc293 newline
202
202
203
203
204 tag and branch using same name
204 tag and branch using same name
205
205
206 $ hg branch tag-and-branch-same-name
206 $ hg branch tag-and-branch-same-name
207 marked working directory as branch tag-and-branch-same-name
207 marked working directory as branch tag-and-branch-same-name
208 $ hg ci -m"discouraged"
208 $ hg ci -m"discouraged"
209 $ hg tag tag-and-branch-same-name
209 $ hg tag tag-and-branch-same-name
210 warning: tag tag-and-branch-same-name conflicts with existing branch name
210 warning: tag tag-and-branch-same-name conflicts with existing branch name
211
211
212 test custom commit messages
212 test custom commit messages
213
213
214 $ cat > editor << '__EOF__'
214 $ cat > editor << '__EOF__'
215 > #!/bin/sh
215 > #!/bin/sh
216 > echo "custom tag message" > "$1"
216 > echo "custom tag message" > "$1"
217 > echo "second line" >> "$1"
217 > echo "second line" >> "$1"
218 > __EOF__
218 > __EOF__
219 $ chmod +x editor
219 $ chmod +x editor
220 $ HGEDITOR="'`pwd`'"/editor hg tag custom-tag -e
220 $ HGEDITOR="'`pwd`'"/editor hg tag custom-tag -e
221 $ hg log -l1 --template "{desc}\n"
221 $ hg log -l1 --template "{desc}\n"
222 custom tag message
222 custom tag message
223 second line
223 second line
224
224
225
225
226 local tag with .hgtags modified
226 local tag with .hgtags modified
227
227
228 $ hg tag hgtags-modified
228 $ hg tag hgtags-modified
229 $ hg rollback
229 $ hg rollback
230 repository tip rolled back to revision 13 (undo commit)
230 repository tip rolled back to revision 13 (undo commit)
231 working directory now based on revision 13
231 working directory now based on revision 13
232 $ hg st
232 $ hg st
233 M .hgtags
233 M .hgtags
234 ? .hgtags.orig
234 ? .hgtags.orig
235 ? editor
235 ? editor
236 $ hg tag --local baz
236 $ hg tag --local baz
237 $ hg revert --no-backup .hgtags
237 $ hg revert --no-backup .hgtags
238
238
239
239
240 tagging when at named-branch-head that's not a topo-head
240 tagging when at named-branch-head that's not a topo-head
241
241
242 $ hg up default
242 $ hg up default
243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
243 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
244 $ hg merge -t internal:local
244 $ hg merge -t internal:local
245 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
245 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
246 (branch merge, don't forget to commit)
246 (branch merge, don't forget to commit)
247 $ hg ci -m 'merge named branch'
247 $ hg ci -m 'merge named branch'
248 $ hg up 13
248 $ hg up 13
249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
250 $ hg tag new-topo-head
250 $ hg tag new-topo-head
251
251
252
252
253 tagging on null rev
253 tagging on null rev
254
254
255 $ hg up null
255 $ hg up null
256 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
256 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
257 $ hg tag nullrev
257 $ hg tag nullrev
258 abort: not at a branch head (use -f to force)
258 abort: not at a branch head (use -f to force)
259 [255]
259 [255]
260
260
261 $ hg init empty
261 $ hg init empty
262 $ hg tag -R empty nullrev
262 $ hg tag -R empty nullrev
263
263
264 $ cd ..
264 $ cd ..
265
265
266 tagging on an uncommitted merge (issue2542)
266 tagging on an uncommitted merge (issue2542)
267
267
268 $ hg init repo-tag-uncommitted-merge
268 $ hg init repo-tag-uncommitted-merge
269 $ cd repo-tag-uncommitted-merge
269 $ cd repo-tag-uncommitted-merge
270 $ echo c1 > f1
270 $ echo c1 > f1
271 $ hg ci -Am0
271 $ hg ci -Am0
272 adding f1
272 adding f1
273 $ echo c2 > f2
273 $ echo c2 > f2
274 $ hg ci -Am1
274 $ hg ci -Am1
275 adding f2
275 adding f2
276 $ hg co -q 0
276 $ hg co -q 0
277 $ hg branch b1
277 $ hg branch b1
278 marked working directory as branch b1
278 marked working directory as branch b1
279 $ hg ci -m2
279 $ hg ci -m2
280 $ hg up default
280 $ hg up default
281 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
282 $ hg merge b1
282 $ hg merge b1
283 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 (branch merge, don't forget to commit)
284 (branch merge, don't forget to commit)
285
285
286 $ hg tag t1
286 $ hg tag t1
287 abort: uncommitted merge
287 abort: uncommitted merge
288 [255]
288 [255]
289 $ hg status
289 $ hg status
290 $ hg tag --rev 1 t2
290 $ hg tag --rev 1 t2
291 abort: uncommitted merge
291 abort: uncommitted merge
292 [255]
292 [255]
293 $ hg tag --rev 1 --local t3
293 $ hg tag --rev 1 --local t3
294 $ hg tags -v
294 $ hg tags -v
295 tip 2:8a8f787d0d5c
295 tip 2:2a156e8887cc
296 t3 1:c3adabd1a5f4 local
296 t3 1:c3adabd1a5f4 local
297
297
298 $ cd ..
298 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now