##// END OF EJS Templates
rollback: improve message
Matt Mackall -
r10893:468876bc default
parent child Browse files
Show More
@@ -1,2228 +1,2229 b''
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
10 import repo, changegroup, subrepo
11 import changelog, dirstate, filelog, manifest, context
11 import changelog, dirstate, filelog, manifest, context
12 import lock, transaction, store, encoding
12 import lock, transaction, store, encoding
13 import util, extensions, hook, error
13 import 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 import url as urlmod
17 import url as urlmod
18 from lock import release
18 from lock import release
19 import weakref, stat, errno, os, time, inspect
19 import weakref, stat, errno, os, time, inspect
20 propertycache = util.propertycache
20 propertycache = util.propertycache
21
21
22 class localrepository(repo.repository):
22 class localrepository(repo.repository):
23 capabilities = set(('lookup', 'changegroupsubset', 'branchmap'))
23 capabilities = set(('lookup', 'changegroupsubset', 'branchmap'))
24 supported = set('revlogv1 store fncache shared'.split())
24 supported = set('revlogv1 store fncache shared'.split())
25
25
26 def __init__(self, baseui, path=None, create=0):
26 def __init__(self, baseui, path=None, create=0):
27 repo.repository.__init__(self)
27 repo.repository.__init__(self)
28 self.root = os.path.realpath(path)
28 self.root = os.path.realpath(path)
29 self.path = os.path.join(self.root, ".hg")
29 self.path = os.path.join(self.root, ".hg")
30 self.origroot = path
30 self.origroot = path
31 self.opener = util.opener(self.path)
31 self.opener = util.opener(self.path)
32 self.wopener = util.opener(self.root)
32 self.wopener = util.opener(self.root)
33 self.baseui = baseui
33 self.baseui = baseui
34 self.ui = baseui.copy()
34 self.ui = baseui.copy()
35
35
36 try:
36 try:
37 self.ui.readconfig(self.join("hgrc"), self.root)
37 self.ui.readconfig(self.join("hgrc"), self.root)
38 extensions.loadall(self.ui)
38 extensions.loadall(self.ui)
39 except IOError:
39 except IOError:
40 pass
40 pass
41
41
42 if not os.path.isdir(self.path):
42 if not os.path.isdir(self.path):
43 if create:
43 if create:
44 if not os.path.exists(path):
44 if not os.path.exists(path):
45 os.mkdir(path)
45 os.mkdir(path)
46 os.mkdir(self.path)
46 os.mkdir(self.path)
47 requirements = ["revlogv1"]
47 requirements = ["revlogv1"]
48 if self.ui.configbool('format', 'usestore', True):
48 if self.ui.configbool('format', 'usestore', True):
49 os.mkdir(os.path.join(self.path, "store"))
49 os.mkdir(os.path.join(self.path, "store"))
50 requirements.append("store")
50 requirements.append("store")
51 if self.ui.configbool('format', 'usefncache', True):
51 if self.ui.configbool('format', 'usefncache', True):
52 requirements.append("fncache")
52 requirements.append("fncache")
53 # create an invalid changelog
53 # create an invalid changelog
54 self.opener("00changelog.i", "a").write(
54 self.opener("00changelog.i", "a").write(
55 '\0\0\0\2' # represents revlogv2
55 '\0\0\0\2' # represents revlogv2
56 ' dummy changelog to prevent using the old repo layout'
56 ' dummy changelog to prevent using the old repo layout'
57 )
57 )
58 reqfile = self.opener("requires", "w")
58 reqfile = self.opener("requires", "w")
59 for r in requirements:
59 for r in requirements:
60 reqfile.write("%s\n" % r)
60 reqfile.write("%s\n" % r)
61 reqfile.close()
61 reqfile.close()
62 else:
62 else:
63 raise error.RepoError(_("repository %s not found") % path)
63 raise error.RepoError(_("repository %s not found") % path)
64 elif create:
64 elif create:
65 raise error.RepoError(_("repository %s already exists") % path)
65 raise error.RepoError(_("repository %s already exists") % path)
66 else:
66 else:
67 # find requirements
67 # find requirements
68 requirements = set()
68 requirements = set()
69 try:
69 try:
70 requirements = set(self.opener("requires").read().splitlines())
70 requirements = set(self.opener("requires").read().splitlines())
71 except IOError, inst:
71 except IOError, inst:
72 if inst.errno != errno.ENOENT:
72 if inst.errno != errno.ENOENT:
73 raise
73 raise
74 for r in requirements - self.supported:
74 for r in requirements - self.supported:
75 raise error.RepoError(_("requirement '%s' not supported") % r)
75 raise error.RepoError(_("requirement '%s' not supported") % r)
76
76
77 self.sharedpath = self.path
77 self.sharedpath = self.path
78 try:
78 try:
79 s = os.path.realpath(self.opener("sharedpath").read())
79 s = os.path.realpath(self.opener("sharedpath").read())
80 if not os.path.exists(s):
80 if not os.path.exists(s):
81 raise error.RepoError(
81 raise error.RepoError(
82 _('.hg/sharedpath points to nonexistent directory %s') % s)
82 _('.hg/sharedpath points to nonexistent directory %s') % s)
83 self.sharedpath = s
83 self.sharedpath = s
84 except IOError, inst:
84 except IOError, inst:
85 if inst.errno != errno.ENOENT:
85 if inst.errno != errno.ENOENT:
86 raise
86 raise
87
87
88 self.store = store.store(requirements, self.sharedpath, util.opener)
88 self.store = store.store(requirements, self.sharedpath, util.opener)
89 self.spath = self.store.path
89 self.spath = self.store.path
90 self.sopener = self.store.opener
90 self.sopener = self.store.opener
91 self.sjoin = self.store.join
91 self.sjoin = self.store.join
92 self.opener.createmode = self.store.createmode
92 self.opener.createmode = self.store.createmode
93 self.sopener.options = {}
93 self.sopener.options = {}
94
94
95 # These two define the set of tags for this repository. _tags
95 # These two define the set of tags for this repository. _tags
96 # maps tag name to node; _tagtypes maps tag name to 'global' or
96 # maps tag name to node; _tagtypes maps tag name to 'global' or
97 # 'local'. (Global tags are defined by .hgtags across all
97 # 'local'. (Global tags are defined by .hgtags across all
98 # heads, and local tags are defined in .hg/localtags.) They
98 # heads, and local tags are defined in .hg/localtags.) They
99 # constitute the in-memory cache of tags.
99 # constitute the in-memory cache of tags.
100 self._tags = None
100 self._tags = None
101 self._tagtypes = None
101 self._tagtypes = None
102
102
103 self._branchcache = None # in UTF-8
103 self._branchcache = None # in UTF-8
104 self._branchcachetip = None
104 self._branchcachetip = None
105 self.nodetagscache = None
105 self.nodetagscache = None
106 self.filterpats = {}
106 self.filterpats = {}
107 self._datafilters = {}
107 self._datafilters = {}
108 self._transref = self._lockref = self._wlockref = None
108 self._transref = self._lockref = self._wlockref = None
109
109
110 @propertycache
110 @propertycache
111 def changelog(self):
111 def changelog(self):
112 c = changelog.changelog(self.sopener)
112 c = changelog.changelog(self.sopener)
113 if 'HG_PENDING' in os.environ:
113 if 'HG_PENDING' in os.environ:
114 p = os.environ['HG_PENDING']
114 p = os.environ['HG_PENDING']
115 if p.startswith(self.root):
115 if p.startswith(self.root):
116 c.readpending('00changelog.i.a')
116 c.readpending('00changelog.i.a')
117 self.sopener.options['defversion'] = c.version
117 self.sopener.options['defversion'] = c.version
118 return c
118 return c
119
119
120 @propertycache
120 @propertycache
121 def manifest(self):
121 def manifest(self):
122 return manifest.manifest(self.sopener)
122 return manifest.manifest(self.sopener)
123
123
124 @propertycache
124 @propertycache
125 def dirstate(self):
125 def dirstate(self):
126 return dirstate.dirstate(self.opener, self.ui, self.root)
126 return dirstate.dirstate(self.opener, self.ui, self.root)
127
127
128 def __getitem__(self, changeid):
128 def __getitem__(self, changeid):
129 if changeid is None:
129 if changeid is None:
130 return context.workingctx(self)
130 return context.workingctx(self)
131 return context.changectx(self, changeid)
131 return context.changectx(self, changeid)
132
132
133 def __contains__(self, changeid):
133 def __contains__(self, changeid):
134 try:
134 try:
135 return bool(self.lookup(changeid))
135 return bool(self.lookup(changeid))
136 except error.RepoLookupError:
136 except error.RepoLookupError:
137 return False
137 return False
138
138
139 def __nonzero__(self):
139 def __nonzero__(self):
140 return True
140 return True
141
141
142 def __len__(self):
142 def __len__(self):
143 return len(self.changelog)
143 return len(self.changelog)
144
144
145 def __iter__(self):
145 def __iter__(self):
146 for i in xrange(len(self)):
146 for i in xrange(len(self)):
147 yield i
147 yield i
148
148
149 def url(self):
149 def url(self):
150 return 'file:' + self.root
150 return 'file:' + self.root
151
151
152 def hook(self, name, throw=False, **args):
152 def hook(self, name, throw=False, **args):
153 return hook.hook(self.ui, self, name, throw, **args)
153 return hook.hook(self.ui, self, name, throw, **args)
154
154
155 tag_disallowed = ':\r\n'
155 tag_disallowed = ':\r\n'
156
156
157 def _tag(self, names, node, message, local, user, date, extra={}):
157 def _tag(self, names, node, message, local, user, date, extra={}):
158 if isinstance(names, str):
158 if isinstance(names, str):
159 allchars = names
159 allchars = names
160 names = (names,)
160 names = (names,)
161 else:
161 else:
162 allchars = ''.join(names)
162 allchars = ''.join(names)
163 for c in self.tag_disallowed:
163 for c in self.tag_disallowed:
164 if c in allchars:
164 if c in allchars:
165 raise util.Abort(_('%r cannot be used in a tag name') % c)
165 raise util.Abort(_('%r cannot be used in a tag name') % c)
166
166
167 for name in names:
167 for name in names:
168 self.hook('pretag', throw=True, node=hex(node), tag=name,
168 self.hook('pretag', throw=True, node=hex(node), tag=name,
169 local=local)
169 local=local)
170
170
171 def writetags(fp, names, munge, prevtags):
171 def writetags(fp, names, munge, prevtags):
172 fp.seek(0, 2)
172 fp.seek(0, 2)
173 if prevtags and prevtags[-1] != '\n':
173 if prevtags and prevtags[-1] != '\n':
174 fp.write('\n')
174 fp.write('\n')
175 for name in names:
175 for name in names:
176 m = munge and munge(name) or name
176 m = munge and munge(name) or name
177 if self._tagtypes and name in self._tagtypes:
177 if self._tagtypes and name in self._tagtypes:
178 old = self._tags.get(name, nullid)
178 old = self._tags.get(name, nullid)
179 fp.write('%s %s\n' % (hex(old), m))
179 fp.write('%s %s\n' % (hex(old), m))
180 fp.write('%s %s\n' % (hex(node), m))
180 fp.write('%s %s\n' % (hex(node), m))
181 fp.close()
181 fp.close()
182
182
183 prevtags = ''
183 prevtags = ''
184 if local:
184 if local:
185 try:
185 try:
186 fp = self.opener('localtags', 'r+')
186 fp = self.opener('localtags', 'r+')
187 except IOError:
187 except IOError:
188 fp = self.opener('localtags', 'a')
188 fp = self.opener('localtags', 'a')
189 else:
189 else:
190 prevtags = fp.read()
190 prevtags = fp.read()
191
191
192 # local tags are stored in the current charset
192 # local tags are stored in the current charset
193 writetags(fp, names, None, prevtags)
193 writetags(fp, names, None, prevtags)
194 for name in names:
194 for name in names:
195 self.hook('tag', node=hex(node), tag=name, local=local)
195 self.hook('tag', node=hex(node), tag=name, local=local)
196 return
196 return
197
197
198 try:
198 try:
199 fp = self.wfile('.hgtags', 'rb+')
199 fp = self.wfile('.hgtags', 'rb+')
200 except IOError:
200 except IOError:
201 fp = self.wfile('.hgtags', 'ab')
201 fp = self.wfile('.hgtags', 'ab')
202 else:
202 else:
203 prevtags = fp.read()
203 prevtags = fp.read()
204
204
205 # committed tags are stored in UTF-8
205 # committed tags are stored in UTF-8
206 writetags(fp, names, encoding.fromlocal, prevtags)
206 writetags(fp, names, encoding.fromlocal, prevtags)
207
207
208 if '.hgtags' not in self.dirstate:
208 if '.hgtags' not in self.dirstate:
209 self.add(['.hgtags'])
209 self.add(['.hgtags'])
210
210
211 m = matchmod.exact(self.root, '', ['.hgtags'])
211 m = matchmod.exact(self.root, '', ['.hgtags'])
212 tagnode = self.commit(message, user, date, extra=extra, match=m)
212 tagnode = self.commit(message, user, date, extra=extra, match=m)
213
213
214 for name in names:
214 for name in names:
215 self.hook('tag', node=hex(node), tag=name, local=local)
215 self.hook('tag', node=hex(node), tag=name, local=local)
216
216
217 return tagnode
217 return tagnode
218
218
219 def tag(self, names, node, message, local, user, date):
219 def tag(self, names, node, message, local, user, date):
220 '''tag a revision with one or more symbolic names.
220 '''tag a revision with one or more symbolic names.
221
221
222 names is a list of strings or, when adding a single tag, names may be a
222 names is a list of strings or, when adding a single tag, names may be a
223 string.
223 string.
224
224
225 if local is True, the tags are stored in a per-repository file.
225 if local is True, the tags are stored in a per-repository file.
226 otherwise, they are stored in the .hgtags file, and a new
226 otherwise, they are stored in the .hgtags file, and a new
227 changeset is committed with the change.
227 changeset is committed with the change.
228
228
229 keyword arguments:
229 keyword arguments:
230
230
231 local: whether to store tags in non-version-controlled file
231 local: whether to store tags in non-version-controlled file
232 (default False)
232 (default False)
233
233
234 message: commit message to use if committing
234 message: commit message to use if committing
235
235
236 user: name of user to use if committing
236 user: name of user to use if committing
237
237
238 date: date tuple to use if committing'''
238 date: date tuple to use if committing'''
239
239
240 for x in self.status()[:5]:
240 for x in self.status()[:5]:
241 if '.hgtags' in x:
241 if '.hgtags' in x:
242 raise util.Abort(_('working copy of .hgtags is changed '
242 raise util.Abort(_('working copy of .hgtags is changed '
243 '(please commit .hgtags manually)'))
243 '(please commit .hgtags manually)'))
244
244
245 self.tags() # instantiate the cache
245 self.tags() # instantiate the cache
246 self._tag(names, node, message, local, user, date)
246 self._tag(names, node, message, local, user, date)
247
247
248 def tags(self):
248 def tags(self):
249 '''return a mapping of tag to node'''
249 '''return a mapping of tag to node'''
250 if self._tags is None:
250 if self._tags is None:
251 (self._tags, self._tagtypes) = self._findtags()
251 (self._tags, self._tagtypes) = self._findtags()
252
252
253 return self._tags
253 return self._tags
254
254
255 def _findtags(self):
255 def _findtags(self):
256 '''Do the hard work of finding tags. Return a pair of dicts
256 '''Do the hard work of finding tags. Return a pair of dicts
257 (tags, tagtypes) where tags maps tag name to node, and tagtypes
257 (tags, tagtypes) where tags maps tag name to node, and tagtypes
258 maps tag name to a string like \'global\' or \'local\'.
258 maps tag name to a string like \'global\' or \'local\'.
259 Subclasses or extensions are free to add their own tags, but
259 Subclasses or extensions are free to add their own tags, but
260 should be aware that the returned dicts will be retained for the
260 should be aware that the returned dicts will be retained for the
261 duration of the localrepo object.'''
261 duration of the localrepo object.'''
262
262
263 # XXX what tagtype should subclasses/extensions use? Currently
263 # XXX what tagtype should subclasses/extensions use? Currently
264 # mq and bookmarks add tags, but do not set the tagtype at all.
264 # mq and bookmarks add tags, but do not set the tagtype at all.
265 # Should each extension invent its own tag type? Should there
265 # Should each extension invent its own tag type? Should there
266 # be one tagtype for all such "virtual" tags? Or is the status
266 # be one tagtype for all such "virtual" tags? Or is the status
267 # quo fine?
267 # quo fine?
268
268
269 alltags = {} # map tag name to (node, hist)
269 alltags = {} # map tag name to (node, hist)
270 tagtypes = {}
270 tagtypes = {}
271
271
272 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
272 tagsmod.findglobaltags(self.ui, self, alltags, tagtypes)
273 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
273 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
274
274
275 # Build the return dicts. Have to re-encode tag names because
275 # Build the return dicts. Have to re-encode tag names because
276 # the tags module always uses UTF-8 (in order not to lose info
276 # the tags module always uses UTF-8 (in order not to lose info
277 # writing to the cache), but the rest of Mercurial wants them in
277 # writing to the cache), but the rest of Mercurial wants them in
278 # local encoding.
278 # local encoding.
279 tags = {}
279 tags = {}
280 for (name, (node, hist)) in alltags.iteritems():
280 for (name, (node, hist)) in alltags.iteritems():
281 if node != nullid:
281 if node != nullid:
282 tags[encoding.tolocal(name)] = node
282 tags[encoding.tolocal(name)] = node
283 tags['tip'] = self.changelog.tip()
283 tags['tip'] = self.changelog.tip()
284 tagtypes = dict([(encoding.tolocal(name), value)
284 tagtypes = dict([(encoding.tolocal(name), value)
285 for (name, value) in tagtypes.iteritems()])
285 for (name, value) in tagtypes.iteritems()])
286 return (tags, tagtypes)
286 return (tags, tagtypes)
287
287
288 def tagtype(self, tagname):
288 def tagtype(self, tagname):
289 '''
289 '''
290 return the type of the given tag. result can be:
290 return the type of the given tag. result can be:
291
291
292 'local' : a local tag
292 'local' : a local tag
293 'global' : a global tag
293 'global' : a global tag
294 None : tag does not exist
294 None : tag does not exist
295 '''
295 '''
296
296
297 self.tags()
297 self.tags()
298
298
299 return self._tagtypes.get(tagname)
299 return self._tagtypes.get(tagname)
300
300
301 def tagslist(self):
301 def tagslist(self):
302 '''return a list of tags ordered by revision'''
302 '''return a list of tags ordered by revision'''
303 l = []
303 l = []
304 for t, n in self.tags().iteritems():
304 for t, n in self.tags().iteritems():
305 try:
305 try:
306 r = self.changelog.rev(n)
306 r = self.changelog.rev(n)
307 except:
307 except:
308 r = -2 # sort to the beginning of the list if unknown
308 r = -2 # sort to the beginning of the list if unknown
309 l.append((r, t, n))
309 l.append((r, t, n))
310 return [(t, n) for r, t, n in sorted(l)]
310 return [(t, n) for r, t, n in sorted(l)]
311
311
312 def nodetags(self, node):
312 def nodetags(self, node):
313 '''return the tags associated with a node'''
313 '''return the tags associated with a node'''
314 if not self.nodetagscache:
314 if not self.nodetagscache:
315 self.nodetagscache = {}
315 self.nodetagscache = {}
316 for t, n in self.tags().iteritems():
316 for t, n in self.tags().iteritems():
317 self.nodetagscache.setdefault(n, []).append(t)
317 self.nodetagscache.setdefault(n, []).append(t)
318 return self.nodetagscache.get(node, [])
318 return self.nodetagscache.get(node, [])
319
319
320 def _branchtags(self, partial, lrev):
320 def _branchtags(self, partial, lrev):
321 # TODO: rename this function?
321 # TODO: rename this function?
322 tiprev = len(self) - 1
322 tiprev = len(self) - 1
323 if lrev != tiprev:
323 if lrev != tiprev:
324 ctxgen = (self[r] for r in xrange(lrev + 1, tiprev + 1))
324 ctxgen = (self[r] for r in xrange(lrev + 1, tiprev + 1))
325 self._updatebranchcache(partial, ctxgen)
325 self._updatebranchcache(partial, ctxgen)
326 self._writebranchcache(partial, self.changelog.tip(), tiprev)
326 self._writebranchcache(partial, self.changelog.tip(), tiprev)
327
327
328 return partial
328 return partial
329
329
330 def branchmap(self):
330 def branchmap(self):
331 '''returns a dictionary {branch: [branchheads]}'''
331 '''returns a dictionary {branch: [branchheads]}'''
332 tip = self.changelog.tip()
332 tip = self.changelog.tip()
333 if self._branchcache is not None and self._branchcachetip == tip:
333 if self._branchcache is not None and self._branchcachetip == tip:
334 return self._branchcache
334 return self._branchcache
335
335
336 oldtip = self._branchcachetip
336 oldtip = self._branchcachetip
337 self._branchcachetip = tip
337 self._branchcachetip = tip
338 if oldtip is None or oldtip not in self.changelog.nodemap:
338 if oldtip is None or oldtip not in self.changelog.nodemap:
339 partial, last, lrev = self._readbranchcache()
339 partial, last, lrev = self._readbranchcache()
340 else:
340 else:
341 lrev = self.changelog.rev(oldtip)
341 lrev = self.changelog.rev(oldtip)
342 partial = self._branchcache
342 partial = self._branchcache
343
343
344 self._branchtags(partial, lrev)
344 self._branchtags(partial, lrev)
345 # this private cache holds all heads (not just tips)
345 # this private cache holds all heads (not just tips)
346 self._branchcache = partial
346 self._branchcache = partial
347
347
348 return self._branchcache
348 return self._branchcache
349
349
350 def branchtags(self):
350 def branchtags(self):
351 '''return a dict where branch names map to the tipmost head of
351 '''return a dict where branch names map to the tipmost head of
352 the branch, open heads come before closed'''
352 the branch, open heads come before closed'''
353 bt = {}
353 bt = {}
354 for bn, heads in self.branchmap().iteritems():
354 for bn, heads in self.branchmap().iteritems():
355 tip = heads[-1]
355 tip = heads[-1]
356 for h in reversed(heads):
356 for h in reversed(heads):
357 if 'close' not in self.changelog.read(h)[5]:
357 if 'close' not in self.changelog.read(h)[5]:
358 tip = h
358 tip = h
359 break
359 break
360 bt[bn] = tip
360 bt[bn] = tip
361 return bt
361 return bt
362
362
363
363
364 def _readbranchcache(self):
364 def _readbranchcache(self):
365 partial = {}
365 partial = {}
366 try:
366 try:
367 f = self.opener("branchheads.cache")
367 f = self.opener("branchheads.cache")
368 lines = f.read().split('\n')
368 lines = f.read().split('\n')
369 f.close()
369 f.close()
370 except (IOError, OSError):
370 except (IOError, OSError):
371 return {}, nullid, nullrev
371 return {}, nullid, nullrev
372
372
373 try:
373 try:
374 last, lrev = lines.pop(0).split(" ", 1)
374 last, lrev = lines.pop(0).split(" ", 1)
375 last, lrev = bin(last), int(lrev)
375 last, lrev = bin(last), int(lrev)
376 if lrev >= len(self) or self[lrev].node() != last:
376 if lrev >= len(self) or self[lrev].node() != last:
377 # invalidate the cache
377 # invalidate the cache
378 raise ValueError('invalidating branch cache (tip differs)')
378 raise ValueError('invalidating branch cache (tip differs)')
379 for l in lines:
379 for l in lines:
380 if not l:
380 if not l:
381 continue
381 continue
382 node, label = l.split(" ", 1)
382 node, label = l.split(" ", 1)
383 partial.setdefault(label.strip(), []).append(bin(node))
383 partial.setdefault(label.strip(), []).append(bin(node))
384 except KeyboardInterrupt:
384 except KeyboardInterrupt:
385 raise
385 raise
386 except Exception, inst:
386 except Exception, inst:
387 if self.ui.debugflag:
387 if self.ui.debugflag:
388 self.ui.warn(str(inst), '\n')
388 self.ui.warn(str(inst), '\n')
389 partial, last, lrev = {}, nullid, nullrev
389 partial, last, lrev = {}, nullid, nullrev
390 return partial, last, lrev
390 return partial, last, lrev
391
391
392 def _writebranchcache(self, branches, tip, tiprev):
392 def _writebranchcache(self, branches, tip, tiprev):
393 try:
393 try:
394 f = self.opener("branchheads.cache", "w", atomictemp=True)
394 f = self.opener("branchheads.cache", "w", atomictemp=True)
395 f.write("%s %s\n" % (hex(tip), tiprev))
395 f.write("%s %s\n" % (hex(tip), tiprev))
396 for label, nodes in branches.iteritems():
396 for label, nodes in branches.iteritems():
397 for node in nodes:
397 for node in nodes:
398 f.write("%s %s\n" % (hex(node), label))
398 f.write("%s %s\n" % (hex(node), label))
399 f.rename()
399 f.rename()
400 except (IOError, OSError):
400 except (IOError, OSError):
401 pass
401 pass
402
402
403 def _updatebranchcache(self, partial, ctxgen):
403 def _updatebranchcache(self, partial, ctxgen):
404 # collect new branch entries
404 # collect new branch entries
405 newbranches = {}
405 newbranches = {}
406 for c in ctxgen:
406 for c in ctxgen:
407 newbranches.setdefault(c.branch(), []).append(c.node())
407 newbranches.setdefault(c.branch(), []).append(c.node())
408 # if older branchheads are reachable from new ones, they aren't
408 # if older branchheads are reachable from new ones, they aren't
409 # really branchheads. Note checking parents is insufficient:
409 # really branchheads. Note checking parents is insufficient:
410 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
410 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
411 for branch, newnodes in newbranches.iteritems():
411 for branch, newnodes in newbranches.iteritems():
412 bheads = partial.setdefault(branch, [])
412 bheads = partial.setdefault(branch, [])
413 bheads.extend(newnodes)
413 bheads.extend(newnodes)
414 if len(bheads) < 2:
414 if len(bheads) < 2:
415 continue
415 continue
416 newbheads = []
416 newbheads = []
417 # starting from tip means fewer passes over reachable
417 # starting from tip means fewer passes over reachable
418 while newnodes:
418 while newnodes:
419 latest = newnodes.pop()
419 latest = newnodes.pop()
420 if latest not in bheads:
420 if latest not in bheads:
421 continue
421 continue
422 minbhrev = self[min([self[bh].rev() for bh in bheads])].node()
422 minbhrev = self[min([self[bh].rev() for bh in bheads])].node()
423 reachable = self.changelog.reachable(latest, minbhrev)
423 reachable = self.changelog.reachable(latest, minbhrev)
424 bheads = [b for b in bheads if b not in reachable]
424 bheads = [b for b in bheads if b not in reachable]
425 newbheads.insert(0, latest)
425 newbheads.insert(0, latest)
426 bheads.extend(newbheads)
426 bheads.extend(newbheads)
427 partial[branch] = bheads
427 partial[branch] = bheads
428
428
429 def lookup(self, key):
429 def lookup(self, key):
430 if isinstance(key, int):
430 if isinstance(key, int):
431 return self.changelog.node(key)
431 return self.changelog.node(key)
432 elif key == '.':
432 elif key == '.':
433 return self.dirstate.parents()[0]
433 return self.dirstate.parents()[0]
434 elif key == 'null':
434 elif key == 'null':
435 return nullid
435 return nullid
436 elif key == 'tip':
436 elif key == 'tip':
437 return self.changelog.tip()
437 return self.changelog.tip()
438 n = self.changelog._match(key)
438 n = self.changelog._match(key)
439 if n:
439 if n:
440 return n
440 return n
441 if key in self.tags():
441 if key in self.tags():
442 return self.tags()[key]
442 return self.tags()[key]
443 if key in self.branchtags():
443 if key in self.branchtags():
444 return self.branchtags()[key]
444 return self.branchtags()[key]
445 n = self.changelog._partialmatch(key)
445 n = self.changelog._partialmatch(key)
446 if n:
446 if n:
447 return n
447 return n
448
448
449 # can't find key, check if it might have come from damaged dirstate
449 # can't find key, check if it might have come from damaged dirstate
450 if key in self.dirstate.parents():
450 if key in self.dirstate.parents():
451 raise error.Abort(_("working directory has unknown parent '%s'!")
451 raise error.Abort(_("working directory has unknown parent '%s'!")
452 % short(key))
452 % short(key))
453 try:
453 try:
454 if len(key) == 20:
454 if len(key) == 20:
455 key = hex(key)
455 key = hex(key)
456 except:
456 except:
457 pass
457 pass
458 raise error.RepoLookupError(_("unknown revision '%s'") % key)
458 raise error.RepoLookupError(_("unknown revision '%s'") % key)
459
459
460 def local(self):
460 def local(self):
461 return True
461 return True
462
462
463 def join(self, f):
463 def join(self, f):
464 return os.path.join(self.path, f)
464 return os.path.join(self.path, f)
465
465
466 def wjoin(self, f):
466 def wjoin(self, f):
467 return os.path.join(self.root, f)
467 return os.path.join(self.root, f)
468
468
469 def rjoin(self, f):
469 def rjoin(self, f):
470 return os.path.join(self.root, util.pconvert(f))
470 return os.path.join(self.root, util.pconvert(f))
471
471
472 def file(self, f):
472 def file(self, f):
473 if f[0] == '/':
473 if f[0] == '/':
474 f = f[1:]
474 f = f[1:]
475 return filelog.filelog(self.sopener, f)
475 return filelog.filelog(self.sopener, f)
476
476
477 def changectx(self, changeid):
477 def changectx(self, changeid):
478 return self[changeid]
478 return self[changeid]
479
479
480 def parents(self, changeid=None):
480 def parents(self, changeid=None):
481 '''get list of changectxs for parents of changeid'''
481 '''get list of changectxs for parents of changeid'''
482 return self[changeid].parents()
482 return self[changeid].parents()
483
483
484 def filectx(self, path, changeid=None, fileid=None):
484 def filectx(self, path, changeid=None, fileid=None):
485 """changeid can be a changeset revision, node, or tag.
485 """changeid can be a changeset revision, node, or tag.
486 fileid can be a file revision or node."""
486 fileid can be a file revision or node."""
487 return context.filectx(self, path, changeid, fileid)
487 return context.filectx(self, path, changeid, fileid)
488
488
489 def getcwd(self):
489 def getcwd(self):
490 return self.dirstate.getcwd()
490 return self.dirstate.getcwd()
491
491
492 def pathto(self, f, cwd=None):
492 def pathto(self, f, cwd=None):
493 return self.dirstate.pathto(f, cwd)
493 return self.dirstate.pathto(f, cwd)
494
494
495 def wfile(self, f, mode='r'):
495 def wfile(self, f, mode='r'):
496 return self.wopener(f, mode)
496 return self.wopener(f, mode)
497
497
498 def _link(self, f):
498 def _link(self, f):
499 return os.path.islink(self.wjoin(f))
499 return os.path.islink(self.wjoin(f))
500
500
501 def _filter(self, filter, filename, data):
501 def _filter(self, filter, filename, data):
502 if filter not in self.filterpats:
502 if filter not in self.filterpats:
503 l = []
503 l = []
504 for pat, cmd in self.ui.configitems(filter):
504 for pat, cmd in self.ui.configitems(filter):
505 if cmd == '!':
505 if cmd == '!':
506 continue
506 continue
507 mf = matchmod.match(self.root, '', [pat])
507 mf = matchmod.match(self.root, '', [pat])
508 fn = None
508 fn = None
509 params = cmd
509 params = cmd
510 for name, filterfn in self._datafilters.iteritems():
510 for name, filterfn in self._datafilters.iteritems():
511 if cmd.startswith(name):
511 if cmd.startswith(name):
512 fn = filterfn
512 fn = filterfn
513 params = cmd[len(name):].lstrip()
513 params = cmd[len(name):].lstrip()
514 break
514 break
515 if not fn:
515 if not fn:
516 fn = lambda s, c, **kwargs: util.filter(s, c)
516 fn = lambda s, c, **kwargs: util.filter(s, c)
517 # Wrap old filters not supporting keyword arguments
517 # Wrap old filters not supporting keyword arguments
518 if not inspect.getargspec(fn)[2]:
518 if not inspect.getargspec(fn)[2]:
519 oldfn = fn
519 oldfn = fn
520 fn = lambda s, c, **kwargs: oldfn(s, c)
520 fn = lambda s, c, **kwargs: oldfn(s, c)
521 l.append((mf, fn, params))
521 l.append((mf, fn, params))
522 self.filterpats[filter] = l
522 self.filterpats[filter] = l
523
523
524 for mf, fn, cmd in self.filterpats[filter]:
524 for mf, fn, cmd in self.filterpats[filter]:
525 if mf(filename):
525 if mf(filename):
526 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
526 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
527 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
527 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
528 break
528 break
529
529
530 return data
530 return data
531
531
532 def adddatafilter(self, name, filter):
532 def adddatafilter(self, name, filter):
533 self._datafilters[name] = filter
533 self._datafilters[name] = filter
534
534
535 def wread(self, filename):
535 def wread(self, filename):
536 if self._link(filename):
536 if self._link(filename):
537 data = os.readlink(self.wjoin(filename))
537 data = os.readlink(self.wjoin(filename))
538 else:
538 else:
539 data = self.wopener(filename, 'r').read()
539 data = self.wopener(filename, 'r').read()
540 return self._filter("encode", filename, data)
540 return self._filter("encode", filename, data)
541
541
542 def wwrite(self, filename, data, flags):
542 def wwrite(self, filename, data, flags):
543 data = self._filter("decode", filename, data)
543 data = self._filter("decode", filename, data)
544 try:
544 try:
545 os.unlink(self.wjoin(filename))
545 os.unlink(self.wjoin(filename))
546 except OSError:
546 except OSError:
547 pass
547 pass
548 if 'l' in flags:
548 if 'l' in flags:
549 self.wopener.symlink(data, filename)
549 self.wopener.symlink(data, filename)
550 else:
550 else:
551 self.wopener(filename, 'w').write(data)
551 self.wopener(filename, 'w').write(data)
552 if 'x' in flags:
552 if 'x' in flags:
553 util.set_flags(self.wjoin(filename), False, True)
553 util.set_flags(self.wjoin(filename), False, True)
554
554
555 def wwritedata(self, filename, data):
555 def wwritedata(self, filename, data):
556 return self._filter("decode", filename, data)
556 return self._filter("decode", filename, data)
557
557
558 def transaction(self, desc):
558 def transaction(self, desc):
559 tr = self._transref and self._transref() or None
559 tr = self._transref and self._transref() or None
560 if tr and tr.running():
560 if tr and tr.running():
561 return tr.nest()
561 return tr.nest()
562
562
563 # abort here if the journal already exists
563 # abort here if the journal already exists
564 if os.path.exists(self.sjoin("journal")):
564 if os.path.exists(self.sjoin("journal")):
565 raise error.RepoError(
565 raise error.RepoError(
566 _("abandoned transaction found - run hg recover"))
566 _("abandoned transaction found - run hg recover"))
567
567
568 # save dirstate for rollback
568 # save dirstate for rollback
569 try:
569 try:
570 ds = self.opener("dirstate").read()
570 ds = self.opener("dirstate").read()
571 except IOError:
571 except IOError:
572 ds = ""
572 ds = ""
573 self.opener("journal.dirstate", "w").write(ds)
573 self.opener("journal.dirstate", "w").write(ds)
574 self.opener("journal.branch", "w").write(self.dirstate.branch())
574 self.opener("journal.branch", "w").write(self.dirstate.branch())
575 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
575 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
576
576
577 renames = [(self.sjoin("journal"), self.sjoin("undo")),
577 renames = [(self.sjoin("journal"), self.sjoin("undo")),
578 (self.join("journal.dirstate"), self.join("undo.dirstate")),
578 (self.join("journal.dirstate"), self.join("undo.dirstate")),
579 (self.join("journal.branch"), self.join("undo.branch")),
579 (self.join("journal.branch"), self.join("undo.branch")),
580 (self.join("journal.desc"), self.join("undo.desc"))]
580 (self.join("journal.desc"), self.join("undo.desc"))]
581 tr = transaction.transaction(self.ui.warn, self.sopener,
581 tr = transaction.transaction(self.ui.warn, self.sopener,
582 self.sjoin("journal"),
582 self.sjoin("journal"),
583 aftertrans(renames),
583 aftertrans(renames),
584 self.store.createmode)
584 self.store.createmode)
585 self._transref = weakref.ref(tr)
585 self._transref = weakref.ref(tr)
586 return tr
586 return tr
587
587
588 def recover(self):
588 def recover(self):
589 lock = self.lock()
589 lock = self.lock()
590 try:
590 try:
591 if os.path.exists(self.sjoin("journal")):
591 if os.path.exists(self.sjoin("journal")):
592 self.ui.status(_("rolling back interrupted transaction\n"))
592 self.ui.status(_("rolling back interrupted transaction\n"))
593 transaction.rollback(self.sopener, self.sjoin("journal"),
593 transaction.rollback(self.sopener, self.sjoin("journal"),
594 self.ui.warn)
594 self.ui.warn)
595 self.invalidate()
595 self.invalidate()
596 return True
596 return True
597 else:
597 else:
598 self.ui.warn(_("no interrupted transaction available\n"))
598 self.ui.warn(_("no interrupted transaction available\n"))
599 return False
599 return False
600 finally:
600 finally:
601 lock.release()
601 lock.release()
602
602
603 def rollback(self, dryrun=False):
603 def rollback(self, dryrun=False):
604 wlock = lock = None
604 wlock = lock = None
605 try:
605 try:
606 wlock = self.wlock()
606 wlock = self.wlock()
607 lock = self.lock()
607 lock = self.lock()
608 if os.path.exists(self.sjoin("undo")):
608 if os.path.exists(self.sjoin("undo")):
609 try:
609 try:
610 args = self.opener("undo.desc", "r").read().splitlines()
610 args = self.opener("undo.desc", "r").read().splitlines()
611 if len(args) >= 3 and self.ui.verbose:
611 if len(args) >= 3 and self.ui.verbose:
612 desc = _("rolling back %s (%s) to revision %s\n") % (
612 desc = _("rolling back to revision %s"
613 args[1], args[2], args[0])
613 " (undo %s: %s)\n") % (
614 args[0], args[1], args[2])
614 elif len(args) >= 2:
615 elif len(args) >= 2:
615 desc = _("rolling back %s to revision %s\n") % (
616 desc = _("rolling back to revision %s (undo %s)\n") % (
616 args[1], args[0])
617 args[0], args[1])
617 except IOError:
618 except IOError:
618 desc = _("rolling back unknown transaction\n")
619 desc = _("rolling back unknown transaction\n")
619 self.ui.status(desc)
620 self.ui.status(desc)
620 if dryrun:
621 if dryrun:
621 return
622 return
622 transaction.rollback(self.sopener, self.sjoin("undo"),
623 transaction.rollback(self.sopener, self.sjoin("undo"),
623 self.ui.warn)
624 self.ui.warn)
624 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
625 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
625 try:
626 try:
626 branch = self.opener("undo.branch").read()
627 branch = self.opener("undo.branch").read()
627 self.dirstate.setbranch(branch)
628 self.dirstate.setbranch(branch)
628 except IOError:
629 except IOError:
629 self.ui.warn(_("Named branch could not be reset, "
630 self.ui.warn(_("Named branch could not be reset, "
630 "current branch still is: %s\n")
631 "current branch still is: %s\n")
631 % encoding.tolocal(self.dirstate.branch()))
632 % encoding.tolocal(self.dirstate.branch()))
632 self.invalidate()
633 self.invalidate()
633 self.dirstate.invalidate()
634 self.dirstate.invalidate()
634 self.destroyed()
635 self.destroyed()
635 else:
636 else:
636 self.ui.warn(_("no rollback information available\n"))
637 self.ui.warn(_("no rollback information available\n"))
637 finally:
638 finally:
638 release(lock, wlock)
639 release(lock, wlock)
639
640
640 def invalidatecaches(self):
641 def invalidatecaches(self):
641 self._tags = None
642 self._tags = None
642 self._tagtypes = None
643 self._tagtypes = None
643 self.nodetagscache = None
644 self.nodetagscache = None
644 self._branchcache = None # in UTF-8
645 self._branchcache = None # in UTF-8
645 self._branchcachetip = None
646 self._branchcachetip = None
646
647
647 def invalidate(self):
648 def invalidate(self):
648 for a in "changelog manifest".split():
649 for a in "changelog manifest".split():
649 if a in self.__dict__:
650 if a in self.__dict__:
650 delattr(self, a)
651 delattr(self, a)
651 self.invalidatecaches()
652 self.invalidatecaches()
652
653
653 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
654 def _lock(self, lockname, wait, releasefn, acquirefn, desc):
654 try:
655 try:
655 l = lock.lock(lockname, 0, releasefn, desc=desc)
656 l = lock.lock(lockname, 0, releasefn, desc=desc)
656 except error.LockHeld, inst:
657 except error.LockHeld, inst:
657 if not wait:
658 if not wait:
658 raise
659 raise
659 self.ui.warn(_("waiting for lock on %s held by %r\n") %
660 self.ui.warn(_("waiting for lock on %s held by %r\n") %
660 (desc, inst.locker))
661 (desc, inst.locker))
661 # default to 600 seconds timeout
662 # default to 600 seconds timeout
662 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
663 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
663 releasefn, desc=desc)
664 releasefn, desc=desc)
664 if acquirefn:
665 if acquirefn:
665 acquirefn()
666 acquirefn()
666 return l
667 return l
667
668
668 def lock(self, wait=True):
669 def lock(self, wait=True):
669 '''Lock the repository store (.hg/store) and return a weak reference
670 '''Lock the repository store (.hg/store) and return a weak reference
670 to the lock. Use this before modifying the store (e.g. committing or
671 to the lock. Use this before modifying the store (e.g. committing or
671 stripping). If you are opening a transaction, get a lock as well.)'''
672 stripping). If you are opening a transaction, get a lock as well.)'''
672 l = self._lockref and self._lockref()
673 l = self._lockref and self._lockref()
673 if l is not None and l.held:
674 if l is not None and l.held:
674 l.lock()
675 l.lock()
675 return l
676 return l
676
677
677 l = self._lock(self.sjoin("lock"), wait, None, self.invalidate,
678 l = self._lock(self.sjoin("lock"), wait, None, self.invalidate,
678 _('repository %s') % self.origroot)
679 _('repository %s') % self.origroot)
679 self._lockref = weakref.ref(l)
680 self._lockref = weakref.ref(l)
680 return l
681 return l
681
682
682 def wlock(self, wait=True):
683 def wlock(self, wait=True):
683 '''Lock the non-store parts of the repository (everything under
684 '''Lock the non-store parts of the repository (everything under
684 .hg except .hg/store) and return a weak reference to the lock.
685 .hg except .hg/store) and return a weak reference to the lock.
685 Use this before modifying files in .hg.'''
686 Use this before modifying files in .hg.'''
686 l = self._wlockref and self._wlockref()
687 l = self._wlockref and self._wlockref()
687 if l is not None and l.held:
688 if l is not None and l.held:
688 l.lock()
689 l.lock()
689 return l
690 return l
690
691
691 l = self._lock(self.join("wlock"), wait, self.dirstate.write,
692 l = self._lock(self.join("wlock"), wait, self.dirstate.write,
692 self.dirstate.invalidate, _('working directory of %s') %
693 self.dirstate.invalidate, _('working directory of %s') %
693 self.origroot)
694 self.origroot)
694 self._wlockref = weakref.ref(l)
695 self._wlockref = weakref.ref(l)
695 return l
696 return l
696
697
697 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
698 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist):
698 """
699 """
699 commit an individual file as part of a larger transaction
700 commit an individual file as part of a larger transaction
700 """
701 """
701
702
702 fname = fctx.path()
703 fname = fctx.path()
703 text = fctx.data()
704 text = fctx.data()
704 flog = self.file(fname)
705 flog = self.file(fname)
705 fparent1 = manifest1.get(fname, nullid)
706 fparent1 = manifest1.get(fname, nullid)
706 fparent2 = fparent2o = manifest2.get(fname, nullid)
707 fparent2 = fparent2o = manifest2.get(fname, nullid)
707
708
708 meta = {}
709 meta = {}
709 copy = fctx.renamed()
710 copy = fctx.renamed()
710 if copy and copy[0] != fname:
711 if copy and copy[0] != fname:
711 # Mark the new revision of this file as a copy of another
712 # Mark the new revision of this file as a copy of another
712 # file. This copy data will effectively act as a parent
713 # file. This copy data will effectively act as a parent
713 # of this new revision. If this is a merge, the first
714 # of this new revision. If this is a merge, the first
714 # parent will be the nullid (meaning "look up the copy data")
715 # parent will be the nullid (meaning "look up the copy data")
715 # and the second one will be the other parent. For example:
716 # and the second one will be the other parent. For example:
716 #
717 #
717 # 0 --- 1 --- 3 rev1 changes file foo
718 # 0 --- 1 --- 3 rev1 changes file foo
718 # \ / rev2 renames foo to bar and changes it
719 # \ / rev2 renames foo to bar and changes it
719 # \- 2 -/ rev3 should have bar with all changes and
720 # \- 2 -/ rev3 should have bar with all changes and
720 # should record that bar descends from
721 # should record that bar descends from
721 # bar in rev2 and foo in rev1
722 # bar in rev2 and foo in rev1
722 #
723 #
723 # this allows this merge to succeed:
724 # this allows this merge to succeed:
724 #
725 #
725 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
726 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
726 # \ / merging rev3 and rev4 should use bar@rev2
727 # \ / merging rev3 and rev4 should use bar@rev2
727 # \- 2 --- 4 as the merge base
728 # \- 2 --- 4 as the merge base
728 #
729 #
729
730
730 cfname = copy[0]
731 cfname = copy[0]
731 crev = manifest1.get(cfname)
732 crev = manifest1.get(cfname)
732 newfparent = fparent2
733 newfparent = fparent2
733
734
734 if manifest2: # branch merge
735 if manifest2: # branch merge
735 if fparent2 == nullid or crev is None: # copied on remote side
736 if fparent2 == nullid or crev is None: # copied on remote side
736 if cfname in manifest2:
737 if cfname in manifest2:
737 crev = manifest2[cfname]
738 crev = manifest2[cfname]
738 newfparent = fparent1
739 newfparent = fparent1
739
740
740 # find source in nearest ancestor if we've lost track
741 # find source in nearest ancestor if we've lost track
741 if not crev:
742 if not crev:
742 self.ui.debug(" %s: searching for copy revision for %s\n" %
743 self.ui.debug(" %s: searching for copy revision for %s\n" %
743 (fname, cfname))
744 (fname, cfname))
744 for ancestor in self['.'].ancestors():
745 for ancestor in self['.'].ancestors():
745 if cfname in ancestor:
746 if cfname in ancestor:
746 crev = ancestor[cfname].filenode()
747 crev = ancestor[cfname].filenode()
747 break
748 break
748
749
749 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
750 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(crev)))
750 meta["copy"] = cfname
751 meta["copy"] = cfname
751 meta["copyrev"] = hex(crev)
752 meta["copyrev"] = hex(crev)
752 fparent1, fparent2 = nullid, newfparent
753 fparent1, fparent2 = nullid, newfparent
753 elif fparent2 != nullid:
754 elif fparent2 != nullid:
754 # is one parent an ancestor of the other?
755 # is one parent an ancestor of the other?
755 fparentancestor = flog.ancestor(fparent1, fparent2)
756 fparentancestor = flog.ancestor(fparent1, fparent2)
756 if fparentancestor == fparent1:
757 if fparentancestor == fparent1:
757 fparent1, fparent2 = fparent2, nullid
758 fparent1, fparent2 = fparent2, nullid
758 elif fparentancestor == fparent2:
759 elif fparentancestor == fparent2:
759 fparent2 = nullid
760 fparent2 = nullid
760
761
761 # is the file changed?
762 # is the file changed?
762 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
763 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
763 changelist.append(fname)
764 changelist.append(fname)
764 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
765 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
765
766
766 # are just the flags changed during merge?
767 # are just the flags changed during merge?
767 if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
768 if fparent1 != fparent2o and manifest1.flags(fname) != fctx.flags():
768 changelist.append(fname)
769 changelist.append(fname)
769
770
770 return fparent1
771 return fparent1
771
772
772 def commit(self, text="", user=None, date=None, match=None, force=False,
773 def commit(self, text="", user=None, date=None, match=None, force=False,
773 editor=False, extra={}):
774 editor=False, extra={}):
774 """Add a new revision to current repository.
775 """Add a new revision to current repository.
775
776
776 Revision information is gathered from the working directory,
777 Revision information is gathered from the working directory,
777 match can be used to filter the committed files. If editor is
778 match can be used to filter the committed files. If editor is
778 supplied, it is called to get a commit message.
779 supplied, it is called to get a commit message.
779 """
780 """
780
781
781 def fail(f, msg):
782 def fail(f, msg):
782 raise util.Abort('%s: %s' % (f, msg))
783 raise util.Abort('%s: %s' % (f, msg))
783
784
784 if not match:
785 if not match:
785 match = matchmod.always(self.root, '')
786 match = matchmod.always(self.root, '')
786
787
787 if not force:
788 if not force:
788 vdirs = []
789 vdirs = []
789 match.dir = vdirs.append
790 match.dir = vdirs.append
790 match.bad = fail
791 match.bad = fail
791
792
792 wlock = self.wlock()
793 wlock = self.wlock()
793 try:
794 try:
794 p1, p2 = self.dirstate.parents()
795 p1, p2 = self.dirstate.parents()
795 wctx = self[None]
796 wctx = self[None]
796
797
797 if (not force and p2 != nullid and match and
798 if (not force and p2 != nullid and match and
798 (match.files() or match.anypats())):
799 (match.files() or match.anypats())):
799 raise util.Abort(_('cannot partially commit a merge '
800 raise util.Abort(_('cannot partially commit a merge '
800 '(do not specify files or patterns)'))
801 '(do not specify files or patterns)'))
801
802
802 changes = self.status(match=match, clean=force)
803 changes = self.status(match=match, clean=force)
803 if force:
804 if force:
804 changes[0].extend(changes[6]) # mq may commit unchanged files
805 changes[0].extend(changes[6]) # mq may commit unchanged files
805
806
806 # check subrepos
807 # check subrepos
807 subs = []
808 subs = []
808 removedsubs = set()
809 removedsubs = set()
809 for p in wctx.parents():
810 for p in wctx.parents():
810 removedsubs.update(s for s in p.substate if match(s))
811 removedsubs.update(s for s in p.substate if match(s))
811 for s in wctx.substate:
812 for s in wctx.substate:
812 removedsubs.discard(s)
813 removedsubs.discard(s)
813 if match(s) and wctx.sub(s).dirty():
814 if match(s) and wctx.sub(s).dirty():
814 subs.append(s)
815 subs.append(s)
815 if (subs or removedsubs) and '.hgsubstate' not in changes[0]:
816 if (subs or removedsubs) and '.hgsubstate' not in changes[0]:
816 changes[0].insert(0, '.hgsubstate')
817 changes[0].insert(0, '.hgsubstate')
817
818
818 # make sure all explicit patterns are matched
819 # make sure all explicit patterns are matched
819 if not force and match.files():
820 if not force and match.files():
820 matched = set(changes[0] + changes[1] + changes[2])
821 matched = set(changes[0] + changes[1] + changes[2])
821
822
822 for f in match.files():
823 for f in match.files():
823 if f == '.' or f in matched or f in wctx.substate:
824 if f == '.' or f in matched or f in wctx.substate:
824 continue
825 continue
825 if f in changes[3]: # missing
826 if f in changes[3]: # missing
826 fail(f, _('file not found!'))
827 fail(f, _('file not found!'))
827 if f in vdirs: # visited directory
828 if f in vdirs: # visited directory
828 d = f + '/'
829 d = f + '/'
829 for mf in matched:
830 for mf in matched:
830 if mf.startswith(d):
831 if mf.startswith(d):
831 break
832 break
832 else:
833 else:
833 fail(f, _("no match under directory!"))
834 fail(f, _("no match under directory!"))
834 elif f not in self.dirstate:
835 elif f not in self.dirstate:
835 fail(f, _("file not tracked!"))
836 fail(f, _("file not tracked!"))
836
837
837 if (not force and not extra.get("close") and p2 == nullid
838 if (not force and not extra.get("close") and p2 == nullid
838 and not (changes[0] or changes[1] or changes[2])
839 and not (changes[0] or changes[1] or changes[2])
839 and self[None].branch() == self['.'].branch()):
840 and self[None].branch() == self['.'].branch()):
840 return None
841 return None
841
842
842 ms = mergemod.mergestate(self)
843 ms = mergemod.mergestate(self)
843 for f in changes[0]:
844 for f in changes[0]:
844 if f in ms and ms[f] == 'u':
845 if f in ms and ms[f] == 'u':
845 raise util.Abort(_("unresolved merge conflicts "
846 raise util.Abort(_("unresolved merge conflicts "
846 "(see hg resolve)"))
847 "(see hg resolve)"))
847
848
848 cctx = context.workingctx(self, (p1, p2), text, user, date,
849 cctx = context.workingctx(self, (p1, p2), text, user, date,
849 extra, changes)
850 extra, changes)
850 if editor:
851 if editor:
851 cctx._text = editor(self, cctx, subs)
852 cctx._text = editor(self, cctx, subs)
852 edited = (text != cctx._text)
853 edited = (text != cctx._text)
853
854
854 # commit subs
855 # commit subs
855 if subs or removedsubs:
856 if subs or removedsubs:
856 state = wctx.substate.copy()
857 state = wctx.substate.copy()
857 for s in subs:
858 for s in subs:
858 self.ui.status(_('committing subrepository %s\n') % s)
859 self.ui.status(_('committing subrepository %s\n') % s)
859 sr = wctx.sub(s).commit(cctx._text, user, date)
860 sr = wctx.sub(s).commit(cctx._text, user, date)
860 state[s] = (state[s][0], sr)
861 state[s] = (state[s][0], sr)
861 subrepo.writestate(self, state)
862 subrepo.writestate(self, state)
862
863
863 # Save commit message in case this transaction gets rolled back
864 # Save commit message in case this transaction gets rolled back
864 # (e.g. by a pretxncommit hook). Leave the content alone on
865 # (e.g. by a pretxncommit hook). Leave the content alone on
865 # the assumption that the user will use the same editor again.
866 # the assumption that the user will use the same editor again.
866 msgfile = self.opener('last-message.txt', 'wb')
867 msgfile = self.opener('last-message.txt', 'wb')
867 msgfile.write(cctx._text)
868 msgfile.write(cctx._text)
868 msgfile.close()
869 msgfile.close()
869
870
870 try:
871 try:
871 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
872 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
872 self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2)
873 self.hook("precommit", throw=True, parent1=hookp1, parent2=hookp2)
873 ret = self.commitctx(cctx, True)
874 ret = self.commitctx(cctx, True)
874 except:
875 except:
875 if edited:
876 if edited:
876 msgfn = self.pathto(msgfile.name[len(self.root)+1:])
877 msgfn = self.pathto(msgfile.name[len(self.root)+1:])
877 self.ui.write(
878 self.ui.write(
878 _('note: commit message saved in %s\n') % msgfn)
879 _('note: commit message saved in %s\n') % msgfn)
879 raise
880 raise
880
881
881 # update dirstate and mergestate
882 # update dirstate and mergestate
882 for f in changes[0] + changes[1]:
883 for f in changes[0] + changes[1]:
883 self.dirstate.normal(f)
884 self.dirstate.normal(f)
884 for f in changes[2]:
885 for f in changes[2]:
885 self.dirstate.forget(f)
886 self.dirstate.forget(f)
886 self.dirstate.setparents(ret)
887 self.dirstate.setparents(ret)
887 ms.reset()
888 ms.reset()
888 finally:
889 finally:
889 wlock.release()
890 wlock.release()
890
891
891 self.hook("commit", node=hex(ret), parent1=hookp1, parent2=hookp2)
892 self.hook("commit", node=hex(ret), parent1=hookp1, parent2=hookp2)
892 return ret
893 return ret
893
894
894 def commitctx(self, ctx, error=False):
895 def commitctx(self, ctx, error=False):
895 """Add a new revision to current repository.
896 """Add a new revision to current repository.
896 Revision information is passed via the context argument.
897 Revision information is passed via the context argument.
897 """
898 """
898
899
899 tr = lock = None
900 tr = lock = None
900 removed = ctx.removed()
901 removed = ctx.removed()
901 p1, p2 = ctx.p1(), ctx.p2()
902 p1, p2 = ctx.p1(), ctx.p2()
902 m1 = p1.manifest().copy()
903 m1 = p1.manifest().copy()
903 m2 = p2.manifest()
904 m2 = p2.manifest()
904 user = ctx.user()
905 user = ctx.user()
905
906
906 lock = self.lock()
907 lock = self.lock()
907 try:
908 try:
908 tr = self.transaction("commit")
909 tr = self.transaction("commit")
909 trp = weakref.proxy(tr)
910 trp = weakref.proxy(tr)
910
911
911 # check in files
912 # check in files
912 new = {}
913 new = {}
913 changed = []
914 changed = []
914 linkrev = len(self)
915 linkrev = len(self)
915 for f in sorted(ctx.modified() + ctx.added()):
916 for f in sorted(ctx.modified() + ctx.added()):
916 self.ui.note(f + "\n")
917 self.ui.note(f + "\n")
917 try:
918 try:
918 fctx = ctx[f]
919 fctx = ctx[f]
919 new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
920 new[f] = self._filecommit(fctx, m1, m2, linkrev, trp,
920 changed)
921 changed)
921 m1.set(f, fctx.flags())
922 m1.set(f, fctx.flags())
922 except OSError, inst:
923 except OSError, inst:
923 self.ui.warn(_("trouble committing %s!\n") % f)
924 self.ui.warn(_("trouble committing %s!\n") % f)
924 raise
925 raise
925 except IOError, inst:
926 except IOError, inst:
926 errcode = getattr(inst, 'errno', errno.ENOENT)
927 errcode = getattr(inst, 'errno', errno.ENOENT)
927 if error or errcode and errcode != errno.ENOENT:
928 if error or errcode and errcode != errno.ENOENT:
928 self.ui.warn(_("trouble committing %s!\n") % f)
929 self.ui.warn(_("trouble committing %s!\n") % f)
929 raise
930 raise
930 else:
931 else:
931 removed.append(f)
932 removed.append(f)
932
933
933 # update manifest
934 # update manifest
934 m1.update(new)
935 m1.update(new)
935 removed = [f for f in sorted(removed) if f in m1 or f in m2]
936 removed = [f for f in sorted(removed) if f in m1 or f in m2]
936 drop = [f for f in removed if f in m1]
937 drop = [f for f in removed if f in m1]
937 for f in drop:
938 for f in drop:
938 del m1[f]
939 del m1[f]
939 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
940 mn = self.manifest.add(m1, trp, linkrev, p1.manifestnode(),
940 p2.manifestnode(), (new, drop))
941 p2.manifestnode(), (new, drop))
941
942
942 # update changelog
943 # update changelog
943 self.changelog.delayupdate()
944 self.changelog.delayupdate()
944 n = self.changelog.add(mn, changed + removed, ctx.description(),
945 n = self.changelog.add(mn, changed + removed, ctx.description(),
945 trp, p1.node(), p2.node(),
946 trp, p1.node(), p2.node(),
946 user, ctx.date(), ctx.extra().copy())
947 user, ctx.date(), ctx.extra().copy())
947 p = lambda: self.changelog.writepending() and self.root or ""
948 p = lambda: self.changelog.writepending() and self.root or ""
948 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
949 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
949 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
950 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
950 parent2=xp2, pending=p)
951 parent2=xp2, pending=p)
951 self.changelog.finalize(trp)
952 self.changelog.finalize(trp)
952 tr.close()
953 tr.close()
953
954
954 if self._branchcache:
955 if self._branchcache:
955 self.branchtags()
956 self.branchtags()
956 return n
957 return n
957 finally:
958 finally:
958 del tr
959 del tr
959 lock.release()
960 lock.release()
960
961
961 def destroyed(self):
962 def destroyed(self):
962 '''Inform the repository that nodes have been destroyed.
963 '''Inform the repository that nodes have been destroyed.
963 Intended for use by strip and rollback, so there's a common
964 Intended for use by strip and rollback, so there's a common
964 place for anything that has to be done after destroying history.'''
965 place for anything that has to be done after destroying history.'''
965 # XXX it might be nice if we could take the list of destroyed
966 # XXX it might be nice if we could take the list of destroyed
966 # nodes, but I don't see an easy way for rollback() to do that
967 # nodes, but I don't see an easy way for rollback() to do that
967
968
968 # Ensure the persistent tag cache is updated. Doing it now
969 # Ensure the persistent tag cache is updated. Doing it now
969 # means that the tag cache only has to worry about destroyed
970 # means that the tag cache only has to worry about destroyed
970 # heads immediately after a strip/rollback. That in turn
971 # heads immediately after a strip/rollback. That in turn
971 # guarantees that "cachetip == currenttip" (comparing both rev
972 # guarantees that "cachetip == currenttip" (comparing both rev
972 # and node) always means no nodes have been added or destroyed.
973 # and node) always means no nodes have been added or destroyed.
973
974
974 # XXX this is suboptimal when qrefresh'ing: we strip the current
975 # XXX this is suboptimal when qrefresh'ing: we strip the current
975 # head, refresh the tag cache, then immediately add a new head.
976 # head, refresh the tag cache, then immediately add a new head.
976 # But I think doing it this way is necessary for the "instant
977 # But I think doing it this way is necessary for the "instant
977 # tag cache retrieval" case to work.
978 # tag cache retrieval" case to work.
978 self.invalidatecaches()
979 self.invalidatecaches()
979
980
980 def walk(self, match, node=None):
981 def walk(self, match, node=None):
981 '''
982 '''
982 walk recursively through the directory tree or a given
983 walk recursively through the directory tree or a given
983 changeset, finding all files matched by the match
984 changeset, finding all files matched by the match
984 function
985 function
985 '''
986 '''
986 return self[node].walk(match)
987 return self[node].walk(match)
987
988
988 def status(self, node1='.', node2=None, match=None,
989 def status(self, node1='.', node2=None, match=None,
989 ignored=False, clean=False, unknown=False):
990 ignored=False, clean=False, unknown=False):
990 """return status of files between two nodes or node and working directory
991 """return status of files between two nodes or node and working directory
991
992
992 If node1 is None, use the first dirstate parent instead.
993 If node1 is None, use the first dirstate parent instead.
993 If node2 is None, compare node1 with working directory.
994 If node2 is None, compare node1 with working directory.
994 """
995 """
995
996
996 def mfmatches(ctx):
997 def mfmatches(ctx):
997 mf = ctx.manifest().copy()
998 mf = ctx.manifest().copy()
998 for fn in mf.keys():
999 for fn in mf.keys():
999 if not match(fn):
1000 if not match(fn):
1000 del mf[fn]
1001 del mf[fn]
1001 return mf
1002 return mf
1002
1003
1003 if isinstance(node1, context.changectx):
1004 if isinstance(node1, context.changectx):
1004 ctx1 = node1
1005 ctx1 = node1
1005 else:
1006 else:
1006 ctx1 = self[node1]
1007 ctx1 = self[node1]
1007 if isinstance(node2, context.changectx):
1008 if isinstance(node2, context.changectx):
1008 ctx2 = node2
1009 ctx2 = node2
1009 else:
1010 else:
1010 ctx2 = self[node2]
1011 ctx2 = self[node2]
1011
1012
1012 working = ctx2.rev() is None
1013 working = ctx2.rev() is None
1013 parentworking = working and ctx1 == self['.']
1014 parentworking = working and ctx1 == self['.']
1014 match = match or matchmod.always(self.root, self.getcwd())
1015 match = match or matchmod.always(self.root, self.getcwd())
1015 listignored, listclean, listunknown = ignored, clean, unknown
1016 listignored, listclean, listunknown = ignored, clean, unknown
1016
1017
1017 # load earliest manifest first for caching reasons
1018 # load earliest manifest first for caching reasons
1018 if not working and ctx2.rev() < ctx1.rev():
1019 if not working and ctx2.rev() < ctx1.rev():
1019 ctx2.manifest()
1020 ctx2.manifest()
1020
1021
1021 if not parentworking:
1022 if not parentworking:
1022 def bad(f, msg):
1023 def bad(f, msg):
1023 if f not in ctx1:
1024 if f not in ctx1:
1024 self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
1025 self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
1025 match.bad = bad
1026 match.bad = bad
1026
1027
1027 if working: # we need to scan the working dir
1028 if working: # we need to scan the working dir
1028 subrepos = ctx1.substate.keys()
1029 subrepos = ctx1.substate.keys()
1029 s = self.dirstate.status(match, subrepos, listignored,
1030 s = self.dirstate.status(match, subrepos, listignored,
1030 listclean, listunknown)
1031 listclean, listunknown)
1031 cmp, modified, added, removed, deleted, unknown, ignored, clean = s
1032 cmp, modified, added, removed, deleted, unknown, ignored, clean = s
1032
1033
1033 # check for any possibly clean files
1034 # check for any possibly clean files
1034 if parentworking and cmp:
1035 if parentworking and cmp:
1035 fixup = []
1036 fixup = []
1036 # do a full compare of any files that might have changed
1037 # do a full compare of any files that might have changed
1037 for f in sorted(cmp):
1038 for f in sorted(cmp):
1038 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
1039 if (f not in ctx1 or ctx2.flags(f) != ctx1.flags(f)
1039 or ctx1[f].cmp(ctx2[f].data())):
1040 or ctx1[f].cmp(ctx2[f].data())):
1040 modified.append(f)
1041 modified.append(f)
1041 else:
1042 else:
1042 fixup.append(f)
1043 fixup.append(f)
1043
1044
1044 if listclean:
1045 if listclean:
1045 clean += fixup
1046 clean += fixup
1046
1047
1047 # update dirstate for files that are actually clean
1048 # update dirstate for files that are actually clean
1048 if fixup:
1049 if fixup:
1049 try:
1050 try:
1050 # updating the dirstate is optional
1051 # updating the dirstate is optional
1051 # so we don't wait on the lock
1052 # so we don't wait on the lock
1052 wlock = self.wlock(False)
1053 wlock = self.wlock(False)
1053 try:
1054 try:
1054 for f in fixup:
1055 for f in fixup:
1055 self.dirstate.normal(f)
1056 self.dirstate.normal(f)
1056 finally:
1057 finally:
1057 wlock.release()
1058 wlock.release()
1058 except error.LockError:
1059 except error.LockError:
1059 pass
1060 pass
1060
1061
1061 if not parentworking:
1062 if not parentworking:
1062 mf1 = mfmatches(ctx1)
1063 mf1 = mfmatches(ctx1)
1063 if working:
1064 if working:
1064 # we are comparing working dir against non-parent
1065 # we are comparing working dir against non-parent
1065 # generate a pseudo-manifest for the working dir
1066 # generate a pseudo-manifest for the working dir
1066 mf2 = mfmatches(self['.'])
1067 mf2 = mfmatches(self['.'])
1067 for f in cmp + modified + added:
1068 for f in cmp + modified + added:
1068 mf2[f] = None
1069 mf2[f] = None
1069 mf2.set(f, ctx2.flags(f))
1070 mf2.set(f, ctx2.flags(f))
1070 for f in removed:
1071 for f in removed:
1071 if f in mf2:
1072 if f in mf2:
1072 del mf2[f]
1073 del mf2[f]
1073 else:
1074 else:
1074 # we are comparing two revisions
1075 # we are comparing two revisions
1075 deleted, unknown, ignored = [], [], []
1076 deleted, unknown, ignored = [], [], []
1076 mf2 = mfmatches(ctx2)
1077 mf2 = mfmatches(ctx2)
1077
1078
1078 modified, added, clean = [], [], []
1079 modified, added, clean = [], [], []
1079 for fn in mf2:
1080 for fn in mf2:
1080 if fn in mf1:
1081 if fn in mf1:
1081 if (mf1.flags(fn) != mf2.flags(fn) or
1082 if (mf1.flags(fn) != mf2.flags(fn) or
1082 (mf1[fn] != mf2[fn] and
1083 (mf1[fn] != mf2[fn] and
1083 (mf2[fn] or ctx1[fn].cmp(ctx2[fn].data())))):
1084 (mf2[fn] or ctx1[fn].cmp(ctx2[fn].data())))):
1084 modified.append(fn)
1085 modified.append(fn)
1085 elif listclean:
1086 elif listclean:
1086 clean.append(fn)
1087 clean.append(fn)
1087 del mf1[fn]
1088 del mf1[fn]
1088 else:
1089 else:
1089 added.append(fn)
1090 added.append(fn)
1090 removed = mf1.keys()
1091 removed = mf1.keys()
1091
1092
1092 r = modified, added, removed, deleted, unknown, ignored, clean
1093 r = modified, added, removed, deleted, unknown, ignored, clean
1093 [l.sort() for l in r]
1094 [l.sort() for l in r]
1094 return r
1095 return r
1095
1096
1096 def add(self, list):
1097 def add(self, list):
1097 wlock = self.wlock()
1098 wlock = self.wlock()
1098 try:
1099 try:
1099 rejected = []
1100 rejected = []
1100 for f in list:
1101 for f in list:
1101 p = self.wjoin(f)
1102 p = self.wjoin(f)
1102 try:
1103 try:
1103 st = os.lstat(p)
1104 st = os.lstat(p)
1104 except:
1105 except:
1105 self.ui.warn(_("%s does not exist!\n") % f)
1106 self.ui.warn(_("%s does not exist!\n") % f)
1106 rejected.append(f)
1107 rejected.append(f)
1107 continue
1108 continue
1108 if st.st_size > 10000000:
1109 if st.st_size > 10000000:
1109 self.ui.warn(_("%s: up to %d MB of RAM may be required "
1110 self.ui.warn(_("%s: up to %d MB of RAM may be required "
1110 "to manage this file\n"
1111 "to manage this file\n"
1111 "(use 'hg revert %s' to cancel the "
1112 "(use 'hg revert %s' to cancel the "
1112 "pending addition)\n")
1113 "pending addition)\n")
1113 % (f, 3 * st.st_size // 1000000, f))
1114 % (f, 3 * st.st_size // 1000000, f))
1114 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1115 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1115 self.ui.warn(_("%s not added: only files and symlinks "
1116 self.ui.warn(_("%s not added: only files and symlinks "
1116 "supported currently\n") % f)
1117 "supported currently\n") % f)
1117 rejected.append(p)
1118 rejected.append(p)
1118 elif self.dirstate[f] in 'amn':
1119 elif self.dirstate[f] in 'amn':
1119 self.ui.warn(_("%s already tracked!\n") % f)
1120 self.ui.warn(_("%s already tracked!\n") % f)
1120 elif self.dirstate[f] == 'r':
1121 elif self.dirstate[f] == 'r':
1121 self.dirstate.normallookup(f)
1122 self.dirstate.normallookup(f)
1122 else:
1123 else:
1123 self.dirstate.add(f)
1124 self.dirstate.add(f)
1124 return rejected
1125 return rejected
1125 finally:
1126 finally:
1126 wlock.release()
1127 wlock.release()
1127
1128
1128 def forget(self, list):
1129 def forget(self, list):
1129 wlock = self.wlock()
1130 wlock = self.wlock()
1130 try:
1131 try:
1131 for f in list:
1132 for f in list:
1132 if self.dirstate[f] != 'a':
1133 if self.dirstate[f] != 'a':
1133 self.ui.warn(_("%s not added!\n") % f)
1134 self.ui.warn(_("%s not added!\n") % f)
1134 else:
1135 else:
1135 self.dirstate.forget(f)
1136 self.dirstate.forget(f)
1136 finally:
1137 finally:
1137 wlock.release()
1138 wlock.release()
1138
1139
1139 def remove(self, list, unlink=False):
1140 def remove(self, list, unlink=False):
1140 if unlink:
1141 if unlink:
1141 for f in list:
1142 for f in list:
1142 try:
1143 try:
1143 util.unlink(self.wjoin(f))
1144 util.unlink(self.wjoin(f))
1144 except OSError, inst:
1145 except OSError, inst:
1145 if inst.errno != errno.ENOENT:
1146 if inst.errno != errno.ENOENT:
1146 raise
1147 raise
1147 wlock = self.wlock()
1148 wlock = self.wlock()
1148 try:
1149 try:
1149 for f in list:
1150 for f in list:
1150 if unlink and os.path.exists(self.wjoin(f)):
1151 if unlink and os.path.exists(self.wjoin(f)):
1151 self.ui.warn(_("%s still exists!\n") % f)
1152 self.ui.warn(_("%s still exists!\n") % f)
1152 elif self.dirstate[f] == 'a':
1153 elif self.dirstate[f] == 'a':
1153 self.dirstate.forget(f)
1154 self.dirstate.forget(f)
1154 elif f not in self.dirstate:
1155 elif f not in self.dirstate:
1155 self.ui.warn(_("%s not tracked!\n") % f)
1156 self.ui.warn(_("%s not tracked!\n") % f)
1156 else:
1157 else:
1157 self.dirstate.remove(f)
1158 self.dirstate.remove(f)
1158 finally:
1159 finally:
1159 wlock.release()
1160 wlock.release()
1160
1161
1161 def undelete(self, list):
1162 def undelete(self, list):
1162 manifests = [self.manifest.read(self.changelog.read(p)[0])
1163 manifests = [self.manifest.read(self.changelog.read(p)[0])
1163 for p in self.dirstate.parents() if p != nullid]
1164 for p in self.dirstate.parents() if p != nullid]
1164 wlock = self.wlock()
1165 wlock = self.wlock()
1165 try:
1166 try:
1166 for f in list:
1167 for f in list:
1167 if self.dirstate[f] != 'r':
1168 if self.dirstate[f] != 'r':
1168 self.ui.warn(_("%s not removed!\n") % f)
1169 self.ui.warn(_("%s not removed!\n") % f)
1169 else:
1170 else:
1170 m = f in manifests[0] and manifests[0] or manifests[1]
1171 m = f in manifests[0] and manifests[0] or manifests[1]
1171 t = self.file(f).read(m[f])
1172 t = self.file(f).read(m[f])
1172 self.wwrite(f, t, m.flags(f))
1173 self.wwrite(f, t, m.flags(f))
1173 self.dirstate.normal(f)
1174 self.dirstate.normal(f)
1174 finally:
1175 finally:
1175 wlock.release()
1176 wlock.release()
1176
1177
1177 def copy(self, source, dest):
1178 def copy(self, source, dest):
1178 p = self.wjoin(dest)
1179 p = self.wjoin(dest)
1179 if not (os.path.exists(p) or os.path.islink(p)):
1180 if not (os.path.exists(p) or os.path.islink(p)):
1180 self.ui.warn(_("%s does not exist!\n") % dest)
1181 self.ui.warn(_("%s does not exist!\n") % dest)
1181 elif not (os.path.isfile(p) or os.path.islink(p)):
1182 elif not (os.path.isfile(p) or os.path.islink(p)):
1182 self.ui.warn(_("copy failed: %s is not a file or a "
1183 self.ui.warn(_("copy failed: %s is not a file or a "
1183 "symbolic link\n") % dest)
1184 "symbolic link\n") % dest)
1184 else:
1185 else:
1185 wlock = self.wlock()
1186 wlock = self.wlock()
1186 try:
1187 try:
1187 if self.dirstate[dest] in '?r':
1188 if self.dirstate[dest] in '?r':
1188 self.dirstate.add(dest)
1189 self.dirstate.add(dest)
1189 self.dirstate.copy(source, dest)
1190 self.dirstate.copy(source, dest)
1190 finally:
1191 finally:
1191 wlock.release()
1192 wlock.release()
1192
1193
1193 def heads(self, start=None):
1194 def heads(self, start=None):
1194 heads = self.changelog.heads(start)
1195 heads = self.changelog.heads(start)
1195 # sort the output in rev descending order
1196 # sort the output in rev descending order
1196 heads = [(-self.changelog.rev(h), h) for h in heads]
1197 heads = [(-self.changelog.rev(h), h) for h in heads]
1197 return [n for (r, n) in sorted(heads)]
1198 return [n for (r, n) in sorted(heads)]
1198
1199
1199 def branchheads(self, branch=None, start=None, closed=False):
1200 def branchheads(self, branch=None, start=None, closed=False):
1200 '''return a (possibly filtered) list of heads for the given branch
1201 '''return a (possibly filtered) list of heads for the given branch
1201
1202
1202 Heads are returned in topological order, from newest to oldest.
1203 Heads are returned in topological order, from newest to oldest.
1203 If branch is None, use the dirstate branch.
1204 If branch is None, use the dirstate branch.
1204 If start is not None, return only heads reachable from start.
1205 If start is not None, return only heads reachable from start.
1205 If closed is True, return heads that are marked as closed as well.
1206 If closed is True, return heads that are marked as closed as well.
1206 '''
1207 '''
1207 if branch is None:
1208 if branch is None:
1208 branch = self[None].branch()
1209 branch = self[None].branch()
1209 branches = self.branchmap()
1210 branches = self.branchmap()
1210 if branch not in branches:
1211 if branch not in branches:
1211 return []
1212 return []
1212 # the cache returns heads ordered lowest to highest
1213 # the cache returns heads ordered lowest to highest
1213 bheads = list(reversed(branches[branch]))
1214 bheads = list(reversed(branches[branch]))
1214 if start is not None:
1215 if start is not None:
1215 # filter out the heads that cannot be reached from startrev
1216 # filter out the heads that cannot be reached from startrev
1216 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
1217 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
1217 bheads = [h for h in bheads if h in fbheads]
1218 bheads = [h for h in bheads if h in fbheads]
1218 if not closed:
1219 if not closed:
1219 bheads = [h for h in bheads if
1220 bheads = [h for h in bheads if
1220 ('close' not in self.changelog.read(h)[5])]
1221 ('close' not in self.changelog.read(h)[5])]
1221 return bheads
1222 return bheads
1222
1223
1223 def branches(self, nodes):
1224 def branches(self, nodes):
1224 if not nodes:
1225 if not nodes:
1225 nodes = [self.changelog.tip()]
1226 nodes = [self.changelog.tip()]
1226 b = []
1227 b = []
1227 for n in nodes:
1228 for n in nodes:
1228 t = n
1229 t = n
1229 while 1:
1230 while 1:
1230 p = self.changelog.parents(n)
1231 p = self.changelog.parents(n)
1231 if p[1] != nullid or p[0] == nullid:
1232 if p[1] != nullid or p[0] == nullid:
1232 b.append((t, n, p[0], p[1]))
1233 b.append((t, n, p[0], p[1]))
1233 break
1234 break
1234 n = p[0]
1235 n = p[0]
1235 return b
1236 return b
1236
1237
1237 def between(self, pairs):
1238 def between(self, pairs):
1238 r = []
1239 r = []
1239
1240
1240 for top, bottom in pairs:
1241 for top, bottom in pairs:
1241 n, l, i = top, [], 0
1242 n, l, i = top, [], 0
1242 f = 1
1243 f = 1
1243
1244
1244 while n != bottom and n != nullid:
1245 while n != bottom and n != nullid:
1245 p = self.changelog.parents(n)[0]
1246 p = self.changelog.parents(n)[0]
1246 if i == f:
1247 if i == f:
1247 l.append(n)
1248 l.append(n)
1248 f = f * 2
1249 f = f * 2
1249 n = p
1250 n = p
1250 i += 1
1251 i += 1
1251
1252
1252 r.append(l)
1253 r.append(l)
1253
1254
1254 return r
1255 return r
1255
1256
1256 def findincoming(self, remote, base=None, heads=None, force=False):
1257 def findincoming(self, remote, base=None, heads=None, force=False):
1257 """Return list of roots of the subsets of missing nodes from remote
1258 """Return list of roots of the subsets of missing nodes from remote
1258
1259
1259 If base dict is specified, assume that these nodes and their parents
1260 If base dict is specified, assume that these nodes and their parents
1260 exist on the remote side and that no child of a node of base exists
1261 exist on the remote side and that no child of a node of base exists
1261 in both remote and self.
1262 in both remote and self.
1262 Furthermore base will be updated to include the nodes that exists
1263 Furthermore base will be updated to include the nodes that exists
1263 in self and remote but no children exists in self and remote.
1264 in self and remote but no children exists in self and remote.
1264 If a list of heads is specified, return only nodes which are heads
1265 If a list of heads is specified, return only nodes which are heads
1265 or ancestors of these heads.
1266 or ancestors of these heads.
1266
1267
1267 All the ancestors of base are in self and in remote.
1268 All the ancestors of base are in self and in remote.
1268 All the descendants of the list returned are missing in self.
1269 All the descendants of the list returned are missing in self.
1269 (and so we know that the rest of the nodes are missing in remote, see
1270 (and so we know that the rest of the nodes are missing in remote, see
1270 outgoing)
1271 outgoing)
1271 """
1272 """
1272 return self.findcommonincoming(remote, base, heads, force)[1]
1273 return self.findcommonincoming(remote, base, heads, force)[1]
1273
1274
1274 def findcommonincoming(self, remote, base=None, heads=None, force=False):
1275 def findcommonincoming(self, remote, base=None, heads=None, force=False):
1275 """Return a tuple (common, missing roots, heads) used to identify
1276 """Return a tuple (common, missing roots, heads) used to identify
1276 missing nodes from remote.
1277 missing nodes from remote.
1277
1278
1278 If base dict is specified, assume that these nodes and their parents
1279 If base dict is specified, assume that these nodes and their parents
1279 exist on the remote side and that no child of a node of base exists
1280 exist on the remote side and that no child of a node of base exists
1280 in both remote and self.
1281 in both remote and self.
1281 Furthermore base will be updated to include the nodes that exists
1282 Furthermore base will be updated to include the nodes that exists
1282 in self and remote but no children exists in self and remote.
1283 in self and remote but no children exists in self and remote.
1283 If a list of heads is specified, return only nodes which are heads
1284 If a list of heads is specified, return only nodes which are heads
1284 or ancestors of these heads.
1285 or ancestors of these heads.
1285
1286
1286 All the ancestors of base are in self and in remote.
1287 All the ancestors of base are in self and in remote.
1287 """
1288 """
1288 m = self.changelog.nodemap
1289 m = self.changelog.nodemap
1289 search = []
1290 search = []
1290 fetch = set()
1291 fetch = set()
1291 seen = set()
1292 seen = set()
1292 seenbranch = set()
1293 seenbranch = set()
1293 if base is None:
1294 if base is None:
1294 base = {}
1295 base = {}
1295
1296
1296 if not heads:
1297 if not heads:
1297 heads = remote.heads()
1298 heads = remote.heads()
1298
1299
1299 if self.changelog.tip() == nullid:
1300 if self.changelog.tip() == nullid:
1300 base[nullid] = 1
1301 base[nullid] = 1
1301 if heads != [nullid]:
1302 if heads != [nullid]:
1302 return [nullid], [nullid], list(heads)
1303 return [nullid], [nullid], list(heads)
1303 return [nullid], [], []
1304 return [nullid], [], []
1304
1305
1305 # assume we're closer to the tip than the root
1306 # assume we're closer to the tip than the root
1306 # and start by examining the heads
1307 # and start by examining the heads
1307 self.ui.status(_("searching for changes\n"))
1308 self.ui.status(_("searching for changes\n"))
1308
1309
1309 unknown = []
1310 unknown = []
1310 for h in heads:
1311 for h in heads:
1311 if h not in m:
1312 if h not in m:
1312 unknown.append(h)
1313 unknown.append(h)
1313 else:
1314 else:
1314 base[h] = 1
1315 base[h] = 1
1315
1316
1316 heads = unknown
1317 heads = unknown
1317 if not unknown:
1318 if not unknown:
1318 return base.keys(), [], []
1319 return base.keys(), [], []
1319
1320
1320 req = set(unknown)
1321 req = set(unknown)
1321 reqcnt = 0
1322 reqcnt = 0
1322
1323
1323 # search through remote branches
1324 # search through remote branches
1324 # a 'branch' here is a linear segment of history, with four parts:
1325 # a 'branch' here is a linear segment of history, with four parts:
1325 # head, root, first parent, second parent
1326 # head, root, first parent, second parent
1326 # (a branch always has two parents (or none) by definition)
1327 # (a branch always has two parents (or none) by definition)
1327 unknown = remote.branches(unknown)
1328 unknown = remote.branches(unknown)
1328 while unknown:
1329 while unknown:
1329 r = []
1330 r = []
1330 while unknown:
1331 while unknown:
1331 n = unknown.pop(0)
1332 n = unknown.pop(0)
1332 if n[0] in seen:
1333 if n[0] in seen:
1333 continue
1334 continue
1334
1335
1335 self.ui.debug("examining %s:%s\n"
1336 self.ui.debug("examining %s:%s\n"
1336 % (short(n[0]), short(n[1])))
1337 % (short(n[0]), short(n[1])))
1337 if n[0] == nullid: # found the end of the branch
1338 if n[0] == nullid: # found the end of the branch
1338 pass
1339 pass
1339 elif n in seenbranch:
1340 elif n in seenbranch:
1340 self.ui.debug("branch already found\n")
1341 self.ui.debug("branch already found\n")
1341 continue
1342 continue
1342 elif n[1] and n[1] in m: # do we know the base?
1343 elif n[1] and n[1] in m: # do we know the base?
1343 self.ui.debug("found incomplete branch %s:%s\n"
1344 self.ui.debug("found incomplete branch %s:%s\n"
1344 % (short(n[0]), short(n[1])))
1345 % (short(n[0]), short(n[1])))
1345 search.append(n[0:2]) # schedule branch range for scanning
1346 search.append(n[0:2]) # schedule branch range for scanning
1346 seenbranch.add(n)
1347 seenbranch.add(n)
1347 else:
1348 else:
1348 if n[1] not in seen and n[1] not in fetch:
1349 if n[1] not in seen and n[1] not in fetch:
1349 if n[2] in m and n[3] in m:
1350 if n[2] in m and n[3] in m:
1350 self.ui.debug("found new changeset %s\n" %
1351 self.ui.debug("found new changeset %s\n" %
1351 short(n[1]))
1352 short(n[1]))
1352 fetch.add(n[1]) # earliest unknown
1353 fetch.add(n[1]) # earliest unknown
1353 for p in n[2:4]:
1354 for p in n[2:4]:
1354 if p in m:
1355 if p in m:
1355 base[p] = 1 # latest known
1356 base[p] = 1 # latest known
1356
1357
1357 for p in n[2:4]:
1358 for p in n[2:4]:
1358 if p not in req and p not in m:
1359 if p not in req and p not in m:
1359 r.append(p)
1360 r.append(p)
1360 req.add(p)
1361 req.add(p)
1361 seen.add(n[0])
1362 seen.add(n[0])
1362
1363
1363 if r:
1364 if r:
1364 reqcnt += 1
1365 reqcnt += 1
1365 self.ui.progress(_('searching'), reqcnt, unit=_('queries'))
1366 self.ui.progress(_('searching'), reqcnt, unit=_('queries'))
1366 self.ui.debug("request %d: %s\n" %
1367 self.ui.debug("request %d: %s\n" %
1367 (reqcnt, " ".join(map(short, r))))
1368 (reqcnt, " ".join(map(short, r))))
1368 for p in xrange(0, len(r), 10):
1369 for p in xrange(0, len(r), 10):
1369 for b in remote.branches(r[p:p + 10]):
1370 for b in remote.branches(r[p:p + 10]):
1370 self.ui.debug("received %s:%s\n" %
1371 self.ui.debug("received %s:%s\n" %
1371 (short(b[0]), short(b[1])))
1372 (short(b[0]), short(b[1])))
1372 unknown.append(b)
1373 unknown.append(b)
1373
1374
1374 # do binary search on the branches we found
1375 # do binary search on the branches we found
1375 while search:
1376 while search:
1376 newsearch = []
1377 newsearch = []
1377 reqcnt += 1
1378 reqcnt += 1
1378 self.ui.progress(_('searching'), reqcnt, unit=_('queries'))
1379 self.ui.progress(_('searching'), reqcnt, unit=_('queries'))
1379 for n, l in zip(search, remote.between(search)):
1380 for n, l in zip(search, remote.between(search)):
1380 l.append(n[1])
1381 l.append(n[1])
1381 p = n[0]
1382 p = n[0]
1382 f = 1
1383 f = 1
1383 for i in l:
1384 for i in l:
1384 self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
1385 self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
1385 if i in m:
1386 if i in m:
1386 if f <= 2:
1387 if f <= 2:
1387 self.ui.debug("found new branch changeset %s\n" %
1388 self.ui.debug("found new branch changeset %s\n" %
1388 short(p))
1389 short(p))
1389 fetch.add(p)
1390 fetch.add(p)
1390 base[i] = 1
1391 base[i] = 1
1391 else:
1392 else:
1392 self.ui.debug("narrowed branch search to %s:%s\n"
1393 self.ui.debug("narrowed branch search to %s:%s\n"
1393 % (short(p), short(i)))
1394 % (short(p), short(i)))
1394 newsearch.append((p, i))
1395 newsearch.append((p, i))
1395 break
1396 break
1396 p, f = i, f * 2
1397 p, f = i, f * 2
1397 search = newsearch
1398 search = newsearch
1398
1399
1399 # sanity check our fetch list
1400 # sanity check our fetch list
1400 for f in fetch:
1401 for f in fetch:
1401 if f in m:
1402 if f in m:
1402 raise error.RepoError(_("already have changeset ")
1403 raise error.RepoError(_("already have changeset ")
1403 + short(f[:4]))
1404 + short(f[:4]))
1404
1405
1405 if base.keys() == [nullid]:
1406 if base.keys() == [nullid]:
1406 if force:
1407 if force:
1407 self.ui.warn(_("warning: repository is unrelated\n"))
1408 self.ui.warn(_("warning: repository is unrelated\n"))
1408 else:
1409 else:
1409 raise util.Abort(_("repository is unrelated"))
1410 raise util.Abort(_("repository is unrelated"))
1410
1411
1411 self.ui.debug("found new changesets starting at " +
1412 self.ui.debug("found new changesets starting at " +
1412 " ".join([short(f) for f in fetch]) + "\n")
1413 " ".join([short(f) for f in fetch]) + "\n")
1413
1414
1414 self.ui.progress(_('searching'), None)
1415 self.ui.progress(_('searching'), None)
1415 self.ui.debug("%d total queries\n" % reqcnt)
1416 self.ui.debug("%d total queries\n" % reqcnt)
1416
1417
1417 return base.keys(), list(fetch), heads
1418 return base.keys(), list(fetch), heads
1418
1419
1419 def findoutgoing(self, remote, base=None, heads=None, force=False):
1420 def findoutgoing(self, remote, base=None, heads=None, force=False):
1420 """Return list of nodes that are roots of subsets not in remote
1421 """Return list of nodes that are roots of subsets not in remote
1421
1422
1422 If base dict is specified, assume that these nodes and their parents
1423 If base dict is specified, assume that these nodes and their parents
1423 exist on the remote side.
1424 exist on the remote side.
1424 If a list of heads is specified, return only nodes which are heads
1425 If a list of heads is specified, return only nodes which are heads
1425 or ancestors of these heads, and return a second element which
1426 or ancestors of these heads, and return a second element which
1426 contains all remote heads which get new children.
1427 contains all remote heads which get new children.
1427 """
1428 """
1428 if base is None:
1429 if base is None:
1429 base = {}
1430 base = {}
1430 self.findincoming(remote, base, heads, force=force)
1431 self.findincoming(remote, base, heads, force=force)
1431
1432
1432 self.ui.debug("common changesets up to "
1433 self.ui.debug("common changesets up to "
1433 + " ".join(map(short, base.keys())) + "\n")
1434 + " ".join(map(short, base.keys())) + "\n")
1434
1435
1435 remain = set(self.changelog.nodemap)
1436 remain = set(self.changelog.nodemap)
1436
1437
1437 # prune everything remote has from the tree
1438 # prune everything remote has from the tree
1438 remain.remove(nullid)
1439 remain.remove(nullid)
1439 remove = base.keys()
1440 remove = base.keys()
1440 while remove:
1441 while remove:
1441 n = remove.pop(0)
1442 n = remove.pop(0)
1442 if n in remain:
1443 if n in remain:
1443 remain.remove(n)
1444 remain.remove(n)
1444 for p in self.changelog.parents(n):
1445 for p in self.changelog.parents(n):
1445 remove.append(p)
1446 remove.append(p)
1446
1447
1447 # find every node whose parents have been pruned
1448 # find every node whose parents have been pruned
1448 subset = []
1449 subset = []
1449 # find every remote head that will get new children
1450 # find every remote head that will get new children
1450 updated_heads = set()
1451 updated_heads = set()
1451 for n in remain:
1452 for n in remain:
1452 p1, p2 = self.changelog.parents(n)
1453 p1, p2 = self.changelog.parents(n)
1453 if p1 not in remain and p2 not in remain:
1454 if p1 not in remain and p2 not in remain:
1454 subset.append(n)
1455 subset.append(n)
1455 if heads:
1456 if heads:
1456 if p1 in heads:
1457 if p1 in heads:
1457 updated_heads.add(p1)
1458 updated_heads.add(p1)
1458 if p2 in heads:
1459 if p2 in heads:
1459 updated_heads.add(p2)
1460 updated_heads.add(p2)
1460
1461
1461 # this is the set of all roots we have to push
1462 # this is the set of all roots we have to push
1462 if heads:
1463 if heads:
1463 return subset, list(updated_heads)
1464 return subset, list(updated_heads)
1464 else:
1465 else:
1465 return subset
1466 return subset
1466
1467
1467 def pull(self, remote, heads=None, force=False):
1468 def pull(self, remote, heads=None, force=False):
1468 lock = self.lock()
1469 lock = self.lock()
1469 try:
1470 try:
1470 common, fetch, rheads = self.findcommonincoming(remote, heads=heads,
1471 common, fetch, rheads = self.findcommonincoming(remote, heads=heads,
1471 force=force)
1472 force=force)
1472 if not fetch:
1473 if not fetch:
1473 self.ui.status(_("no changes found\n"))
1474 self.ui.status(_("no changes found\n"))
1474 return 0
1475 return 0
1475
1476
1476 if fetch == [nullid]:
1477 if fetch == [nullid]:
1477 self.ui.status(_("requesting all changes\n"))
1478 self.ui.status(_("requesting all changes\n"))
1478 elif heads is None and remote.capable('changegroupsubset'):
1479 elif heads is None and remote.capable('changegroupsubset'):
1479 # issue1320, avoid a race if remote changed after discovery
1480 # issue1320, avoid a race if remote changed after discovery
1480 heads = rheads
1481 heads = rheads
1481
1482
1482 if heads is None:
1483 if heads is None:
1483 cg = remote.changegroup(fetch, 'pull')
1484 cg = remote.changegroup(fetch, 'pull')
1484 else:
1485 else:
1485 if not remote.capable('changegroupsubset'):
1486 if not remote.capable('changegroupsubset'):
1486 raise util.Abort(_("Partial pull cannot be done because "
1487 raise util.Abort(_("Partial pull cannot be done because "
1487 "other repository doesn't support "
1488 "other repository doesn't support "
1488 "changegroupsubset."))
1489 "changegroupsubset."))
1489 cg = remote.changegroupsubset(fetch, heads, 'pull')
1490 cg = remote.changegroupsubset(fetch, heads, 'pull')
1490 return self.addchangegroup(cg, 'pull', remote.url())
1491 return self.addchangegroup(cg, 'pull', remote.url())
1491 finally:
1492 finally:
1492 lock.release()
1493 lock.release()
1493
1494
1494 def push(self, remote, force=False, revs=None):
1495 def push(self, remote, force=False, revs=None):
1495 # there are two ways to push to remote repo:
1496 # there are two ways to push to remote repo:
1496 #
1497 #
1497 # addchangegroup assumes local user can lock remote
1498 # addchangegroup assumes local user can lock remote
1498 # repo (local filesystem, old ssh servers).
1499 # repo (local filesystem, old ssh servers).
1499 #
1500 #
1500 # unbundle assumes local user cannot lock remote repo (new ssh
1501 # unbundle assumes local user cannot lock remote repo (new ssh
1501 # servers, http servers).
1502 # servers, http servers).
1502
1503
1503 if remote.capable('unbundle'):
1504 if remote.capable('unbundle'):
1504 return self.push_unbundle(remote, force, revs)
1505 return self.push_unbundle(remote, force, revs)
1505 return self.push_addchangegroup(remote, force, revs)
1506 return self.push_addchangegroup(remote, force, revs)
1506
1507
1507 def prepush(self, remote, force, revs):
1508 def prepush(self, remote, force, revs):
1508 '''Analyze the local and remote repositories and determine which
1509 '''Analyze the local and remote repositories and determine which
1509 changesets need to be pushed to the remote. Return a tuple
1510 changesets need to be pushed to the remote. Return a tuple
1510 (changegroup, remoteheads). changegroup is a readable file-like
1511 (changegroup, remoteheads). changegroup is a readable file-like
1511 object whose read() returns successive changegroup chunks ready to
1512 object whose read() returns successive changegroup chunks ready to
1512 be sent over the wire. remoteheads is the list of remote heads.
1513 be sent over the wire. remoteheads is the list of remote heads.
1513 '''
1514 '''
1514 common = {}
1515 common = {}
1515 remote_heads = remote.heads()
1516 remote_heads = remote.heads()
1516 inc = self.findincoming(remote, common, remote_heads, force=force)
1517 inc = self.findincoming(remote, common, remote_heads, force=force)
1517
1518
1518 cl = self.changelog
1519 cl = self.changelog
1519 update, updated_heads = self.findoutgoing(remote, common, remote_heads)
1520 update, updated_heads = self.findoutgoing(remote, common, remote_heads)
1520 msng_cl, bases, heads = cl.nodesbetween(update, revs)
1521 msng_cl, bases, heads = cl.nodesbetween(update, revs)
1521
1522
1522 outgoingnodeset = set(msng_cl)
1523 outgoingnodeset = set(msng_cl)
1523 # compute set of nodes which, if they were a head before, no longer are
1524 # compute set of nodes which, if they were a head before, no longer are
1524 nolongeraheadnodeset = set(p for n in msng_cl for p in cl.parents(n))
1525 nolongeraheadnodeset = set(p for n in msng_cl for p in cl.parents(n))
1525
1526
1526 def checkbranch(lheads, rheads, branchname=None):
1527 def checkbranch(lheads, rheads, branchname=None):
1527 '''
1528 '''
1528 check whether there are more local heads than remote heads on
1529 check whether there are more local heads than remote heads on
1529 a specific branch.
1530 a specific branch.
1530
1531
1531 lheads: local branch heads
1532 lheads: local branch heads
1532 rheads: remote branch heads
1533 rheads: remote branch heads
1533 '''
1534 '''
1534 newlheads = [n for n in lheads if n in outgoingnodeset]
1535 newlheads = [n for n in lheads if n in outgoingnodeset]
1535 formerrheads = [n for n in rheads if n in nolongeraheadnodeset]
1536 formerrheads = [n for n in rheads if n in nolongeraheadnodeset]
1536 if len(newlheads) > len(formerrheads):
1537 if len(newlheads) > len(formerrheads):
1537 # we add more new heads than we demote former heads to non-head
1538 # we add more new heads than we demote former heads to non-head
1538 if branchname is not None:
1539 if branchname is not None:
1539 msg = _("abort: push creates new remote heads"
1540 msg = _("abort: push creates new remote heads"
1540 " on branch '%s'!\n") % branchname
1541 " on branch '%s'!\n") % branchname
1541 else:
1542 else:
1542 msg = _("abort: push creates new remote heads!\n")
1543 msg = _("abort: push creates new remote heads!\n")
1543 self.ui.warn(msg)
1544 self.ui.warn(msg)
1544 if len(lheads) > len(rheads):
1545 if len(lheads) > len(rheads):
1545 self.ui.status(_("(did you forget to merge?"
1546 self.ui.status(_("(did you forget to merge?"
1546 " use push -f to force)\n"))
1547 " use push -f to force)\n"))
1547 else:
1548 else:
1548 self.ui.status(_("(you should pull and merge or"
1549 self.ui.status(_("(you should pull and merge or"
1549 " use push -f to force)\n"))
1550 " use push -f to force)\n"))
1550 return False
1551 return False
1551 return True
1552 return True
1552
1553
1553 if not bases:
1554 if not bases:
1554 self.ui.status(_("no changes found\n"))
1555 self.ui.status(_("no changes found\n"))
1555 return None, 1
1556 return None, 1
1556 elif not force:
1557 elif not force:
1557 # Check for each named branch if we're creating new remote heads.
1558 # Check for each named branch if we're creating new remote heads.
1558 # To be a remote head after push, node must be either:
1559 # To be a remote head after push, node must be either:
1559 # - unknown locally
1560 # - unknown locally
1560 # - a local outgoing head descended from update
1561 # - a local outgoing head descended from update
1561 # - a remote head that's known locally and not
1562 # - a remote head that's known locally and not
1562 # ancestral to an outgoing head
1563 # ancestral to an outgoing head
1563 #
1564 #
1564 # New named branches cannot be created without --force.
1565 # New named branches cannot be created without --force.
1565
1566
1566 if remote_heads != [nullid]:
1567 if remote_heads != [nullid]:
1567 if remote.capable('branchmap'):
1568 if remote.capable('branchmap'):
1568 remotebrheads = remote.branchmap()
1569 remotebrheads = remote.branchmap()
1569
1570
1570 if not revs:
1571 if not revs:
1571 localbrheads = self.branchmap()
1572 localbrheads = self.branchmap()
1572 else:
1573 else:
1573 localbrheads = {}
1574 localbrheads = {}
1574 ctxgen = (self[n] for n in msng_cl)
1575 ctxgen = (self[n] for n in msng_cl)
1575 self._updatebranchcache(localbrheads, ctxgen)
1576 self._updatebranchcache(localbrheads, ctxgen)
1576
1577
1577 newbranches = list(set(localbrheads) - set(remotebrheads))
1578 newbranches = list(set(localbrheads) - set(remotebrheads))
1578 if newbranches: # new branch requires --force
1579 if newbranches: # new branch requires --force
1579 branchnames = ', '.join("%s" % b for b in newbranches)
1580 branchnames = ', '.join("%s" % b for b in newbranches)
1580 self.ui.warn(_("abort: push creates "
1581 self.ui.warn(_("abort: push creates "
1581 "new remote branches: %s!\n")
1582 "new remote branches: %s!\n")
1582 % branchnames)
1583 % branchnames)
1583 # propose 'push -b .' in the msg too?
1584 # propose 'push -b .' in the msg too?
1584 self.ui.status(_("(use 'hg push -f' to force)\n"))
1585 self.ui.status(_("(use 'hg push -f' to force)\n"))
1585 return None, 0
1586 return None, 0
1586 for branch, lheads in localbrheads.iteritems():
1587 for branch, lheads in localbrheads.iteritems():
1587 if branch in remotebrheads:
1588 if branch in remotebrheads:
1588 rheads = remotebrheads[branch]
1589 rheads = remotebrheads[branch]
1589 if not checkbranch(lheads, rheads, branch):
1590 if not checkbranch(lheads, rheads, branch):
1590 return None, 0
1591 return None, 0
1591 else:
1592 else:
1592 if not checkbranch(heads, remote_heads):
1593 if not checkbranch(heads, remote_heads):
1593 return None, 0
1594 return None, 0
1594
1595
1595 if inc:
1596 if inc:
1596 self.ui.warn(_("note: unsynced remote changes!\n"))
1597 self.ui.warn(_("note: unsynced remote changes!\n"))
1597
1598
1598
1599
1599 if revs is None:
1600 if revs is None:
1600 # use the fast path, no race possible on push
1601 # use the fast path, no race possible on push
1601 nodes = cl.findmissing(common.keys())
1602 nodes = cl.findmissing(common.keys())
1602 cg = self._changegroup(nodes, 'push')
1603 cg = self._changegroup(nodes, 'push')
1603 else:
1604 else:
1604 cg = self.changegroupsubset(update, revs, 'push')
1605 cg = self.changegroupsubset(update, revs, 'push')
1605 return cg, remote_heads
1606 return cg, remote_heads
1606
1607
1607 def push_addchangegroup(self, remote, force, revs):
1608 def push_addchangegroup(self, remote, force, revs):
1608 lock = remote.lock()
1609 lock = remote.lock()
1609 try:
1610 try:
1610 ret = self.prepush(remote, force, revs)
1611 ret = self.prepush(remote, force, revs)
1611 if ret[0] is not None:
1612 if ret[0] is not None:
1612 cg, remote_heads = ret
1613 cg, remote_heads = ret
1613 return remote.addchangegroup(cg, 'push', self.url())
1614 return remote.addchangegroup(cg, 'push', self.url())
1614 return ret[1]
1615 return ret[1]
1615 finally:
1616 finally:
1616 lock.release()
1617 lock.release()
1617
1618
1618 def push_unbundle(self, remote, force, revs):
1619 def push_unbundle(self, remote, force, revs):
1619 # local repo finds heads on server, finds out what revs it
1620 # local repo finds heads on server, finds out what revs it
1620 # must push. once revs transferred, if server finds it has
1621 # must push. once revs transferred, if server finds it has
1621 # different heads (someone else won commit/push race), server
1622 # different heads (someone else won commit/push race), server
1622 # aborts.
1623 # aborts.
1623
1624
1624 ret = self.prepush(remote, force, revs)
1625 ret = self.prepush(remote, force, revs)
1625 if ret[0] is not None:
1626 if ret[0] is not None:
1626 cg, remote_heads = ret
1627 cg, remote_heads = ret
1627 if force:
1628 if force:
1628 remote_heads = ['force']
1629 remote_heads = ['force']
1629 return remote.unbundle(cg, remote_heads, 'push')
1630 return remote.unbundle(cg, remote_heads, 'push')
1630 return ret[1]
1631 return ret[1]
1631
1632
1632 def changegroupinfo(self, nodes, source):
1633 def changegroupinfo(self, nodes, source):
1633 if self.ui.verbose or source == 'bundle':
1634 if self.ui.verbose or source == 'bundle':
1634 self.ui.status(_("%d changesets found\n") % len(nodes))
1635 self.ui.status(_("%d changesets found\n") % len(nodes))
1635 if self.ui.debugflag:
1636 if self.ui.debugflag:
1636 self.ui.debug("list of changesets:\n")
1637 self.ui.debug("list of changesets:\n")
1637 for node in nodes:
1638 for node in nodes:
1638 self.ui.debug("%s\n" % hex(node))
1639 self.ui.debug("%s\n" % hex(node))
1639
1640
1640 def changegroupsubset(self, bases, heads, source, extranodes=None):
1641 def changegroupsubset(self, bases, heads, source, extranodes=None):
1641 """Compute a changegroup consisting of all the nodes that are
1642 """Compute a changegroup consisting of all the nodes that are
1642 descendents of any of the bases and ancestors of any of the heads.
1643 descendents of any of the bases and ancestors of any of the heads.
1643 Return a chunkbuffer object whose read() method will return
1644 Return a chunkbuffer object whose read() method will return
1644 successive changegroup chunks.
1645 successive changegroup chunks.
1645
1646
1646 It is fairly complex as determining which filenodes and which
1647 It is fairly complex as determining which filenodes and which
1647 manifest nodes need to be included for the changeset to be complete
1648 manifest nodes need to be included for the changeset to be complete
1648 is non-trivial.
1649 is non-trivial.
1649
1650
1650 Another wrinkle is doing the reverse, figuring out which changeset in
1651 Another wrinkle is doing the reverse, figuring out which changeset in
1651 the changegroup a particular filenode or manifestnode belongs to.
1652 the changegroup a particular filenode or manifestnode belongs to.
1652
1653
1653 The caller can specify some nodes that must be included in the
1654 The caller can specify some nodes that must be included in the
1654 changegroup using the extranodes argument. It should be a dict
1655 changegroup using the extranodes argument. It should be a dict
1655 where the keys are the filenames (or 1 for the manifest), and the
1656 where the keys are the filenames (or 1 for the manifest), and the
1656 values are lists of (node, linknode) tuples, where node is a wanted
1657 values are lists of (node, linknode) tuples, where node is a wanted
1657 node and linknode is the changelog node that should be transmitted as
1658 node and linknode is the changelog node that should be transmitted as
1658 the linkrev.
1659 the linkrev.
1659 """
1660 """
1660
1661
1661 # Set up some initial variables
1662 # Set up some initial variables
1662 # Make it easy to refer to self.changelog
1663 # Make it easy to refer to self.changelog
1663 cl = self.changelog
1664 cl = self.changelog
1664 # msng is short for missing - compute the list of changesets in this
1665 # msng is short for missing - compute the list of changesets in this
1665 # changegroup.
1666 # changegroup.
1666 if not bases:
1667 if not bases:
1667 bases = [nullid]
1668 bases = [nullid]
1668 msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
1669 msng_cl_lst, bases, heads = cl.nodesbetween(bases, heads)
1669
1670
1670 if extranodes is None:
1671 if extranodes is None:
1671 # can we go through the fast path ?
1672 # can we go through the fast path ?
1672 heads.sort()
1673 heads.sort()
1673 allheads = self.heads()
1674 allheads = self.heads()
1674 allheads.sort()
1675 allheads.sort()
1675 if heads == allheads:
1676 if heads == allheads:
1676 return self._changegroup(msng_cl_lst, source)
1677 return self._changegroup(msng_cl_lst, source)
1677
1678
1678 # slow path
1679 # slow path
1679 self.hook('preoutgoing', throw=True, source=source)
1680 self.hook('preoutgoing', throw=True, source=source)
1680
1681
1681 self.changegroupinfo(msng_cl_lst, source)
1682 self.changegroupinfo(msng_cl_lst, source)
1682 # Some bases may turn out to be superfluous, and some heads may be
1683 # Some bases may turn out to be superfluous, and some heads may be
1683 # too. nodesbetween will return the minimal set of bases and heads
1684 # too. nodesbetween will return the minimal set of bases and heads
1684 # necessary to re-create the changegroup.
1685 # necessary to re-create the changegroup.
1685
1686
1686 # Known heads are the list of heads that it is assumed the recipient
1687 # Known heads are the list of heads that it is assumed the recipient
1687 # of this changegroup will know about.
1688 # of this changegroup will know about.
1688 knownheads = set()
1689 knownheads = set()
1689 # We assume that all parents of bases are known heads.
1690 # We assume that all parents of bases are known heads.
1690 for n in bases:
1691 for n in bases:
1691 knownheads.update(cl.parents(n))
1692 knownheads.update(cl.parents(n))
1692 knownheads.discard(nullid)
1693 knownheads.discard(nullid)
1693 knownheads = list(knownheads)
1694 knownheads = list(knownheads)
1694 if knownheads:
1695 if knownheads:
1695 # Now that we know what heads are known, we can compute which
1696 # Now that we know what heads are known, we can compute which
1696 # changesets are known. The recipient must know about all
1697 # changesets are known. The recipient must know about all
1697 # changesets required to reach the known heads from the null
1698 # changesets required to reach the known heads from the null
1698 # changeset.
1699 # changeset.
1699 has_cl_set, junk, junk = cl.nodesbetween(None, knownheads)
1700 has_cl_set, junk, junk = cl.nodesbetween(None, knownheads)
1700 junk = None
1701 junk = None
1701 # Transform the list into a set.
1702 # Transform the list into a set.
1702 has_cl_set = set(has_cl_set)
1703 has_cl_set = set(has_cl_set)
1703 else:
1704 else:
1704 # If there were no known heads, the recipient cannot be assumed to
1705 # If there were no known heads, the recipient cannot be assumed to
1705 # know about any changesets.
1706 # know about any changesets.
1706 has_cl_set = set()
1707 has_cl_set = set()
1707
1708
1708 # Make it easy to refer to self.manifest
1709 # Make it easy to refer to self.manifest
1709 mnfst = self.manifest
1710 mnfst = self.manifest
1710 # We don't know which manifests are missing yet
1711 # We don't know which manifests are missing yet
1711 msng_mnfst_set = {}
1712 msng_mnfst_set = {}
1712 # Nor do we know which filenodes are missing.
1713 # Nor do we know which filenodes are missing.
1713 msng_filenode_set = {}
1714 msng_filenode_set = {}
1714
1715
1715 junk = mnfst.index[len(mnfst) - 1] # Get around a bug in lazyindex
1716 junk = mnfst.index[len(mnfst) - 1] # Get around a bug in lazyindex
1716 junk = None
1717 junk = None
1717
1718
1718 # A changeset always belongs to itself, so the changenode lookup
1719 # A changeset always belongs to itself, so the changenode lookup
1719 # function for a changenode is identity.
1720 # function for a changenode is identity.
1720 def identity(x):
1721 def identity(x):
1721 return x
1722 return x
1722
1723
1723 # If we determine that a particular file or manifest node must be a
1724 # If we determine that a particular file or manifest node must be a
1724 # node that the recipient of the changegroup will already have, we can
1725 # node that the recipient of the changegroup will already have, we can
1725 # also assume the recipient will have all the parents. This function
1726 # also assume the recipient will have all the parents. This function
1726 # prunes them from the set of missing nodes.
1727 # prunes them from the set of missing nodes.
1727 def prune_parents(revlog, hasset, msngset):
1728 def prune_parents(revlog, hasset, msngset):
1728 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
1729 for r in revlog.ancestors(*[revlog.rev(n) for n in hasset]):
1729 msngset.pop(revlog.node(r), None)
1730 msngset.pop(revlog.node(r), None)
1730
1731
1731 # Use the information collected in collect_manifests_and_files to say
1732 # Use the information collected in collect_manifests_and_files to say
1732 # which changenode any manifestnode belongs to.
1733 # which changenode any manifestnode belongs to.
1733 def lookup_manifest_link(mnfstnode):
1734 def lookup_manifest_link(mnfstnode):
1734 return msng_mnfst_set[mnfstnode]
1735 return msng_mnfst_set[mnfstnode]
1735
1736
1736 # A function generating function that sets up the initial environment
1737 # A function generating function that sets up the initial environment
1737 # the inner function.
1738 # the inner function.
1738 def filenode_collector(changedfiles):
1739 def filenode_collector(changedfiles):
1739 # This gathers information from each manifestnode included in the
1740 # This gathers information from each manifestnode included in the
1740 # changegroup about which filenodes the manifest node references
1741 # changegroup about which filenodes the manifest node references
1741 # so we can include those in the changegroup too.
1742 # so we can include those in the changegroup too.
1742 #
1743 #
1743 # It also remembers which changenode each filenode belongs to. It
1744 # It also remembers which changenode each filenode belongs to. It
1744 # does this by assuming the a filenode belongs to the changenode
1745 # does this by assuming the a filenode belongs to the changenode
1745 # the first manifest that references it belongs to.
1746 # the first manifest that references it belongs to.
1746 def collect_msng_filenodes(mnfstnode):
1747 def collect_msng_filenodes(mnfstnode):
1747 r = mnfst.rev(mnfstnode)
1748 r = mnfst.rev(mnfstnode)
1748 if r - 1 in mnfst.parentrevs(r):
1749 if r - 1 in mnfst.parentrevs(r):
1749 # If the previous rev is one of the parents,
1750 # If the previous rev is one of the parents,
1750 # we only need to see a diff.
1751 # we only need to see a diff.
1751 deltamf = mnfst.readdelta(mnfstnode)
1752 deltamf = mnfst.readdelta(mnfstnode)
1752 # For each line in the delta
1753 # For each line in the delta
1753 for f, fnode in deltamf.iteritems():
1754 for f, fnode in deltamf.iteritems():
1754 f = changedfiles.get(f, None)
1755 f = changedfiles.get(f, None)
1755 # And if the file is in the list of files we care
1756 # And if the file is in the list of files we care
1756 # about.
1757 # about.
1757 if f is not None:
1758 if f is not None:
1758 # Get the changenode this manifest belongs to
1759 # Get the changenode this manifest belongs to
1759 clnode = msng_mnfst_set[mnfstnode]
1760 clnode = msng_mnfst_set[mnfstnode]
1760 # Create the set of filenodes for the file if
1761 # Create the set of filenodes for the file if
1761 # there isn't one already.
1762 # there isn't one already.
1762 ndset = msng_filenode_set.setdefault(f, {})
1763 ndset = msng_filenode_set.setdefault(f, {})
1763 # And set the filenode's changelog node to the
1764 # And set the filenode's changelog node to the
1764 # manifest's if it hasn't been set already.
1765 # manifest's if it hasn't been set already.
1765 ndset.setdefault(fnode, clnode)
1766 ndset.setdefault(fnode, clnode)
1766 else:
1767 else:
1767 # Otherwise we need a full manifest.
1768 # Otherwise we need a full manifest.
1768 m = mnfst.read(mnfstnode)
1769 m = mnfst.read(mnfstnode)
1769 # For every file in we care about.
1770 # For every file in we care about.
1770 for f in changedfiles:
1771 for f in changedfiles:
1771 fnode = m.get(f, None)
1772 fnode = m.get(f, None)
1772 # If it's in the manifest
1773 # If it's in the manifest
1773 if fnode is not None:
1774 if fnode is not None:
1774 # See comments above.
1775 # See comments above.
1775 clnode = msng_mnfst_set[mnfstnode]
1776 clnode = msng_mnfst_set[mnfstnode]
1776 ndset = msng_filenode_set.setdefault(f, {})
1777 ndset = msng_filenode_set.setdefault(f, {})
1777 ndset.setdefault(fnode, clnode)
1778 ndset.setdefault(fnode, clnode)
1778 return collect_msng_filenodes
1779 return collect_msng_filenodes
1779
1780
1780 # We have a list of filenodes we think we need for a file, lets remove
1781 # We have a list of filenodes we think we need for a file, lets remove
1781 # all those we know the recipient must have.
1782 # all those we know the recipient must have.
1782 def prune_filenodes(f, filerevlog):
1783 def prune_filenodes(f, filerevlog):
1783 msngset = msng_filenode_set[f]
1784 msngset = msng_filenode_set[f]
1784 hasset = set()
1785 hasset = set()
1785 # If a 'missing' filenode thinks it belongs to a changenode we
1786 # If a 'missing' filenode thinks it belongs to a changenode we
1786 # assume the recipient must have, then the recipient must have
1787 # assume the recipient must have, then the recipient must have
1787 # that filenode.
1788 # that filenode.
1788 for n in msngset:
1789 for n in msngset:
1789 clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n)))
1790 clnode = cl.node(filerevlog.linkrev(filerevlog.rev(n)))
1790 if clnode in has_cl_set:
1791 if clnode in has_cl_set:
1791 hasset.add(n)
1792 hasset.add(n)
1792 prune_parents(filerevlog, hasset, msngset)
1793 prune_parents(filerevlog, hasset, msngset)
1793
1794
1794 # A function generator function that sets up the a context for the
1795 # A function generator function that sets up the a context for the
1795 # inner function.
1796 # inner function.
1796 def lookup_filenode_link_func(fname):
1797 def lookup_filenode_link_func(fname):
1797 msngset = msng_filenode_set[fname]
1798 msngset = msng_filenode_set[fname]
1798 # Lookup the changenode the filenode belongs to.
1799 # Lookup the changenode the filenode belongs to.
1799 def lookup_filenode_link(fnode):
1800 def lookup_filenode_link(fnode):
1800 return msngset[fnode]
1801 return msngset[fnode]
1801 return lookup_filenode_link
1802 return lookup_filenode_link
1802
1803
1803 # Add the nodes that were explicitly requested.
1804 # Add the nodes that were explicitly requested.
1804 def add_extra_nodes(name, nodes):
1805 def add_extra_nodes(name, nodes):
1805 if not extranodes or name not in extranodes:
1806 if not extranodes or name not in extranodes:
1806 return
1807 return
1807
1808
1808 for node, linknode in extranodes[name]:
1809 for node, linknode in extranodes[name]:
1809 if node not in nodes:
1810 if node not in nodes:
1810 nodes[node] = linknode
1811 nodes[node] = linknode
1811
1812
1812 # Now that we have all theses utility functions to help out and
1813 # Now that we have all theses utility functions to help out and
1813 # logically divide up the task, generate the group.
1814 # logically divide up the task, generate the group.
1814 def gengroup():
1815 def gengroup():
1815 # The set of changed files starts empty.
1816 # The set of changed files starts empty.
1816 changedfiles = {}
1817 changedfiles = {}
1817 collect = changegroup.collector(cl, msng_mnfst_set, changedfiles)
1818 collect = changegroup.collector(cl, msng_mnfst_set, changedfiles)
1818
1819
1819 # Create a changenode group generator that will call our functions
1820 # Create a changenode group generator that will call our functions
1820 # back to lookup the owning changenode and collect information.
1821 # back to lookup the owning changenode and collect information.
1821 group = cl.group(msng_cl_lst, identity, collect)
1822 group = cl.group(msng_cl_lst, identity, collect)
1822 cnt = 0
1823 cnt = 0
1823 for chnk in group:
1824 for chnk in group:
1824 yield chnk
1825 yield chnk
1825 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
1826 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
1826 cnt += 1
1827 cnt += 1
1827 self.ui.progress(_('bundling changes'), None)
1828 self.ui.progress(_('bundling changes'), None)
1828
1829
1829
1830
1830 # Figure out which manifest nodes (of the ones we think might be
1831 # Figure out which manifest nodes (of the ones we think might be
1831 # part of the changegroup) the recipient must know about and
1832 # part of the changegroup) the recipient must know about and
1832 # remove them from the changegroup.
1833 # remove them from the changegroup.
1833 has_mnfst_set = set()
1834 has_mnfst_set = set()
1834 for n in msng_mnfst_set:
1835 for n in msng_mnfst_set:
1835 # If a 'missing' manifest thinks it belongs to a changenode
1836 # If a 'missing' manifest thinks it belongs to a changenode
1836 # the recipient is assumed to have, obviously the recipient
1837 # the recipient is assumed to have, obviously the recipient
1837 # must have that manifest.
1838 # must have that manifest.
1838 linknode = cl.node(mnfst.linkrev(mnfst.rev(n)))
1839 linknode = cl.node(mnfst.linkrev(mnfst.rev(n)))
1839 if linknode in has_cl_set:
1840 if linknode in has_cl_set:
1840 has_mnfst_set.add(n)
1841 has_mnfst_set.add(n)
1841 prune_parents(mnfst, has_mnfst_set, msng_mnfst_set)
1842 prune_parents(mnfst, has_mnfst_set, msng_mnfst_set)
1842 add_extra_nodes(1, msng_mnfst_set)
1843 add_extra_nodes(1, msng_mnfst_set)
1843 msng_mnfst_lst = msng_mnfst_set.keys()
1844 msng_mnfst_lst = msng_mnfst_set.keys()
1844 # Sort the manifestnodes by revision number.
1845 # Sort the manifestnodes by revision number.
1845 msng_mnfst_lst.sort(key=mnfst.rev)
1846 msng_mnfst_lst.sort(key=mnfst.rev)
1846 # Create a generator for the manifestnodes that calls our lookup
1847 # Create a generator for the manifestnodes that calls our lookup
1847 # and data collection functions back.
1848 # and data collection functions back.
1848 group = mnfst.group(msng_mnfst_lst, lookup_manifest_link,
1849 group = mnfst.group(msng_mnfst_lst, lookup_manifest_link,
1849 filenode_collector(changedfiles))
1850 filenode_collector(changedfiles))
1850 cnt = 0
1851 cnt = 0
1851 for chnk in group:
1852 for chnk in group:
1852 yield chnk
1853 yield chnk
1853 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
1854 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
1854 cnt += 1
1855 cnt += 1
1855 self.ui.progress(_('bundling manifests'), None)
1856 self.ui.progress(_('bundling manifests'), None)
1856
1857
1857 # These are no longer needed, dereference and toss the memory for
1858 # These are no longer needed, dereference and toss the memory for
1858 # them.
1859 # them.
1859 msng_mnfst_lst = None
1860 msng_mnfst_lst = None
1860 msng_mnfst_set.clear()
1861 msng_mnfst_set.clear()
1861
1862
1862 if extranodes:
1863 if extranodes:
1863 for fname in extranodes:
1864 for fname in extranodes:
1864 if isinstance(fname, int):
1865 if isinstance(fname, int):
1865 continue
1866 continue
1866 msng_filenode_set.setdefault(fname, {})
1867 msng_filenode_set.setdefault(fname, {})
1867 changedfiles[fname] = 1
1868 changedfiles[fname] = 1
1868 # Go through all our files in order sorted by name.
1869 # Go through all our files in order sorted by name.
1869 cnt = 0
1870 cnt = 0
1870 for fname in sorted(changedfiles):
1871 for fname in sorted(changedfiles):
1871 filerevlog = self.file(fname)
1872 filerevlog = self.file(fname)
1872 if not len(filerevlog):
1873 if not len(filerevlog):
1873 raise util.Abort(_("empty or missing revlog for %s") % fname)
1874 raise util.Abort(_("empty or missing revlog for %s") % fname)
1874 # Toss out the filenodes that the recipient isn't really
1875 # Toss out the filenodes that the recipient isn't really
1875 # missing.
1876 # missing.
1876 if fname in msng_filenode_set:
1877 if fname in msng_filenode_set:
1877 prune_filenodes(fname, filerevlog)
1878 prune_filenodes(fname, filerevlog)
1878 add_extra_nodes(fname, msng_filenode_set[fname])
1879 add_extra_nodes(fname, msng_filenode_set[fname])
1879 msng_filenode_lst = msng_filenode_set[fname].keys()
1880 msng_filenode_lst = msng_filenode_set[fname].keys()
1880 else:
1881 else:
1881 msng_filenode_lst = []
1882 msng_filenode_lst = []
1882 # If any filenodes are left, generate the group for them,
1883 # If any filenodes are left, generate the group for them,
1883 # otherwise don't bother.
1884 # otherwise don't bother.
1884 if len(msng_filenode_lst) > 0:
1885 if len(msng_filenode_lst) > 0:
1885 yield changegroup.chunkheader(len(fname))
1886 yield changegroup.chunkheader(len(fname))
1886 yield fname
1887 yield fname
1887 # Sort the filenodes by their revision #
1888 # Sort the filenodes by their revision #
1888 msng_filenode_lst.sort(key=filerevlog.rev)
1889 msng_filenode_lst.sort(key=filerevlog.rev)
1889 # Create a group generator and only pass in a changenode
1890 # Create a group generator and only pass in a changenode
1890 # lookup function as we need to collect no information
1891 # lookup function as we need to collect no information
1891 # from filenodes.
1892 # from filenodes.
1892 group = filerevlog.group(msng_filenode_lst,
1893 group = filerevlog.group(msng_filenode_lst,
1893 lookup_filenode_link_func(fname))
1894 lookup_filenode_link_func(fname))
1894 for chnk in group:
1895 for chnk in group:
1895 self.ui.progress(
1896 self.ui.progress(
1896 _('bundling files'), cnt, item=fname, unit=_('chunks'))
1897 _('bundling files'), cnt, item=fname, unit=_('chunks'))
1897 cnt += 1
1898 cnt += 1
1898 yield chnk
1899 yield chnk
1899 if fname in msng_filenode_set:
1900 if fname in msng_filenode_set:
1900 # Don't need this anymore, toss it to free memory.
1901 # Don't need this anymore, toss it to free memory.
1901 del msng_filenode_set[fname]
1902 del msng_filenode_set[fname]
1902 # Signal that no more groups are left.
1903 # Signal that no more groups are left.
1903 yield changegroup.closechunk()
1904 yield changegroup.closechunk()
1904 self.ui.progress(_('bundling files'), None)
1905 self.ui.progress(_('bundling files'), None)
1905
1906
1906 if msng_cl_lst:
1907 if msng_cl_lst:
1907 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
1908 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
1908
1909
1909 return util.chunkbuffer(gengroup())
1910 return util.chunkbuffer(gengroup())
1910
1911
1911 def changegroup(self, basenodes, source):
1912 def changegroup(self, basenodes, source):
1912 # to avoid a race we use changegroupsubset() (issue1320)
1913 # to avoid a race we use changegroupsubset() (issue1320)
1913 return self.changegroupsubset(basenodes, self.heads(), source)
1914 return self.changegroupsubset(basenodes, self.heads(), source)
1914
1915
1915 def _changegroup(self, nodes, source):
1916 def _changegroup(self, nodes, source):
1916 """Compute the changegroup of all nodes that we have that a recipient
1917 """Compute the changegroup of all nodes that we have that a recipient
1917 doesn't. Return a chunkbuffer object whose read() method will return
1918 doesn't. Return a chunkbuffer object whose read() method will return
1918 successive changegroup chunks.
1919 successive changegroup chunks.
1919
1920
1920 This is much easier than the previous function as we can assume that
1921 This is much easier than the previous function as we can assume that
1921 the recipient has any changenode we aren't sending them.
1922 the recipient has any changenode we aren't sending them.
1922
1923
1923 nodes is the set of nodes to send"""
1924 nodes is the set of nodes to send"""
1924
1925
1925 self.hook('preoutgoing', throw=True, source=source)
1926 self.hook('preoutgoing', throw=True, source=source)
1926
1927
1927 cl = self.changelog
1928 cl = self.changelog
1928 revset = set([cl.rev(n) for n in nodes])
1929 revset = set([cl.rev(n) for n in nodes])
1929 self.changegroupinfo(nodes, source)
1930 self.changegroupinfo(nodes, source)
1930
1931
1931 def identity(x):
1932 def identity(x):
1932 return x
1933 return x
1933
1934
1934 def gennodelst(log):
1935 def gennodelst(log):
1935 for r in log:
1936 for r in log:
1936 if log.linkrev(r) in revset:
1937 if log.linkrev(r) in revset:
1937 yield log.node(r)
1938 yield log.node(r)
1938
1939
1939 def lookuprevlink_func(revlog):
1940 def lookuprevlink_func(revlog):
1940 def lookuprevlink(n):
1941 def lookuprevlink(n):
1941 return cl.node(revlog.linkrev(revlog.rev(n)))
1942 return cl.node(revlog.linkrev(revlog.rev(n)))
1942 return lookuprevlink
1943 return lookuprevlink
1943
1944
1944 def gengroup():
1945 def gengroup():
1945 '''yield a sequence of changegroup chunks (strings)'''
1946 '''yield a sequence of changegroup chunks (strings)'''
1946 # construct a list of all changed files
1947 # construct a list of all changed files
1947 changedfiles = {}
1948 changedfiles = {}
1948 mmfs = {}
1949 mmfs = {}
1949 collect = changegroup.collector(cl, mmfs, changedfiles)
1950 collect = changegroup.collector(cl, mmfs, changedfiles)
1950
1951
1951 cnt = 0
1952 cnt = 0
1952 for chnk in cl.group(nodes, identity, collect):
1953 for chnk in cl.group(nodes, identity, collect):
1953 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
1954 self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
1954 cnt += 1
1955 cnt += 1
1955 yield chnk
1956 yield chnk
1956 self.ui.progress(_('bundling changes'), None)
1957 self.ui.progress(_('bundling changes'), None)
1957
1958
1958 mnfst = self.manifest
1959 mnfst = self.manifest
1959 nodeiter = gennodelst(mnfst)
1960 nodeiter = gennodelst(mnfst)
1960 cnt = 0
1961 cnt = 0
1961 for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)):
1962 for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)):
1962 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
1963 self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
1963 cnt += 1
1964 cnt += 1
1964 yield chnk
1965 yield chnk
1965 self.ui.progress(_('bundling manifests'), None)
1966 self.ui.progress(_('bundling manifests'), None)
1966
1967
1967 cnt = 0
1968 cnt = 0
1968 for fname in sorted(changedfiles):
1969 for fname in sorted(changedfiles):
1969 filerevlog = self.file(fname)
1970 filerevlog = self.file(fname)
1970 if not len(filerevlog):
1971 if not len(filerevlog):
1971 raise util.Abort(_("empty or missing revlog for %s") % fname)
1972 raise util.Abort(_("empty or missing revlog for %s") % fname)
1972 nodeiter = gennodelst(filerevlog)
1973 nodeiter = gennodelst(filerevlog)
1973 nodeiter = list(nodeiter)
1974 nodeiter = list(nodeiter)
1974 if nodeiter:
1975 if nodeiter:
1975 yield changegroup.chunkheader(len(fname))
1976 yield changegroup.chunkheader(len(fname))
1976 yield fname
1977 yield fname
1977 lookup = lookuprevlink_func(filerevlog)
1978 lookup = lookuprevlink_func(filerevlog)
1978 for chnk in filerevlog.group(nodeiter, lookup):
1979 for chnk in filerevlog.group(nodeiter, lookup):
1979 self.ui.progress(
1980 self.ui.progress(
1980 _('bundling files'), cnt, item=fname, unit=_('chunks'))
1981 _('bundling files'), cnt, item=fname, unit=_('chunks'))
1981 cnt += 1
1982 cnt += 1
1982 yield chnk
1983 yield chnk
1983 self.ui.progress(_('bundling files'), None)
1984 self.ui.progress(_('bundling files'), None)
1984
1985
1985 yield changegroup.closechunk()
1986 yield changegroup.closechunk()
1986
1987
1987 if nodes:
1988 if nodes:
1988 self.hook('outgoing', node=hex(nodes[0]), source=source)
1989 self.hook('outgoing', node=hex(nodes[0]), source=source)
1989
1990
1990 return util.chunkbuffer(gengroup())
1991 return util.chunkbuffer(gengroup())
1991
1992
1992 def addchangegroup(self, source, srctype, url, emptyok=False):
1993 def addchangegroup(self, source, srctype, url, emptyok=False):
1993 """add changegroup to repo.
1994 """add changegroup to repo.
1994
1995
1995 return values:
1996 return values:
1996 - nothing changed or no source: 0
1997 - nothing changed or no source: 0
1997 - more heads than before: 1+added heads (2..n)
1998 - more heads than before: 1+added heads (2..n)
1998 - less heads than before: -1-removed heads (-2..-n)
1999 - less heads than before: -1-removed heads (-2..-n)
1999 - number of heads stays the same: 1
2000 - number of heads stays the same: 1
2000 """
2001 """
2001 def csmap(x):
2002 def csmap(x):
2002 self.ui.debug("add changeset %s\n" % short(x))
2003 self.ui.debug("add changeset %s\n" % short(x))
2003 return len(cl)
2004 return len(cl)
2004
2005
2005 def revmap(x):
2006 def revmap(x):
2006 return cl.rev(x)
2007 return cl.rev(x)
2007
2008
2008 if not source:
2009 if not source:
2009 return 0
2010 return 0
2010
2011
2011 self.hook('prechangegroup', throw=True, source=srctype, url=url)
2012 self.hook('prechangegroup', throw=True, source=srctype, url=url)
2012
2013
2013 changesets = files = revisions = 0
2014 changesets = files = revisions = 0
2014 efiles = set()
2015 efiles = set()
2015
2016
2016 # write changelog data to temp files so concurrent readers will not see
2017 # write changelog data to temp files so concurrent readers will not see
2017 # inconsistent view
2018 # inconsistent view
2018 cl = self.changelog
2019 cl = self.changelog
2019 cl.delayupdate()
2020 cl.delayupdate()
2020 oldheads = len(cl.heads())
2021 oldheads = len(cl.heads())
2021
2022
2022 tr = self.transaction("\n".join([srctype, urlmod.hidepassword(url)]))
2023 tr = self.transaction("\n".join([srctype, urlmod.hidepassword(url)]))
2023 try:
2024 try:
2024 trp = weakref.proxy(tr)
2025 trp = weakref.proxy(tr)
2025 # pull off the changeset group
2026 # pull off the changeset group
2026 self.ui.status(_("adding changesets\n"))
2027 self.ui.status(_("adding changesets\n"))
2027 clstart = len(cl)
2028 clstart = len(cl)
2028 class prog(object):
2029 class prog(object):
2029 step = _('changesets')
2030 step = _('changesets')
2030 count = 1
2031 count = 1
2031 ui = self.ui
2032 ui = self.ui
2032 total = None
2033 total = None
2033 def __call__(self):
2034 def __call__(self):
2034 self.ui.progress(self.step, self.count, unit=_('chunks'),
2035 self.ui.progress(self.step, self.count, unit=_('chunks'),
2035 total=self.total)
2036 total=self.total)
2036 self.count += 1
2037 self.count += 1
2037 pr = prog()
2038 pr = prog()
2038 chunkiter = changegroup.chunkiter(source, progress=pr)
2039 chunkiter = changegroup.chunkiter(source, progress=pr)
2039 if cl.addgroup(chunkiter, csmap, trp) is None and not emptyok:
2040 if cl.addgroup(chunkiter, csmap, trp) is None and not emptyok:
2040 raise util.Abort(_("received changelog group is empty"))
2041 raise util.Abort(_("received changelog group is empty"))
2041 clend = len(cl)
2042 clend = len(cl)
2042 changesets = clend - clstart
2043 changesets = clend - clstart
2043 for c in xrange(clstart, clend):
2044 for c in xrange(clstart, clend):
2044 efiles.update(self[c].files())
2045 efiles.update(self[c].files())
2045 efiles = len(efiles)
2046 efiles = len(efiles)
2046 self.ui.progress(_('changesets'), None)
2047 self.ui.progress(_('changesets'), None)
2047
2048
2048 # pull off the manifest group
2049 # pull off the manifest group
2049 self.ui.status(_("adding manifests\n"))
2050 self.ui.status(_("adding manifests\n"))
2050 pr.step = _('manifests')
2051 pr.step = _('manifests')
2051 pr.count = 1
2052 pr.count = 1
2052 pr.total = changesets # manifests <= changesets
2053 pr.total = changesets # manifests <= changesets
2053 chunkiter = changegroup.chunkiter(source, progress=pr)
2054 chunkiter = changegroup.chunkiter(source, progress=pr)
2054 # no need to check for empty manifest group here:
2055 # no need to check for empty manifest group here:
2055 # if the result of the merge of 1 and 2 is the same in 3 and 4,
2056 # if the result of the merge of 1 and 2 is the same in 3 and 4,
2056 # no new manifest will be created and the manifest group will
2057 # no new manifest will be created and the manifest group will
2057 # be empty during the pull
2058 # be empty during the pull
2058 self.manifest.addgroup(chunkiter, revmap, trp)
2059 self.manifest.addgroup(chunkiter, revmap, trp)
2059 self.ui.progress(_('manifests'), None)
2060 self.ui.progress(_('manifests'), None)
2060
2061
2061 needfiles = {}
2062 needfiles = {}
2062 if self.ui.configbool('server', 'validate', default=False):
2063 if self.ui.configbool('server', 'validate', default=False):
2063 # validate incoming csets have their manifests
2064 # validate incoming csets have their manifests
2064 for cset in xrange(clstart, clend):
2065 for cset in xrange(clstart, clend):
2065 mfest = self.changelog.read(self.changelog.node(cset))[0]
2066 mfest = self.changelog.read(self.changelog.node(cset))[0]
2066 mfest = self.manifest.readdelta(mfest)
2067 mfest = self.manifest.readdelta(mfest)
2067 # store file nodes we must see
2068 # store file nodes we must see
2068 for f, n in mfest.iteritems():
2069 for f, n in mfest.iteritems():
2069 needfiles.setdefault(f, set()).add(n)
2070 needfiles.setdefault(f, set()).add(n)
2070
2071
2071 # process the files
2072 # process the files
2072 self.ui.status(_("adding file changes\n"))
2073 self.ui.status(_("adding file changes\n"))
2073 pr.step = 'files'
2074 pr.step = 'files'
2074 pr.count = 1
2075 pr.count = 1
2075 pr.total = efiles
2076 pr.total = efiles
2076 while 1:
2077 while 1:
2077 f = changegroup.getchunk(source)
2078 f = changegroup.getchunk(source)
2078 if not f:
2079 if not f:
2079 break
2080 break
2080 self.ui.debug("adding %s revisions\n" % f)
2081 self.ui.debug("adding %s revisions\n" % f)
2081 pr()
2082 pr()
2082 fl = self.file(f)
2083 fl = self.file(f)
2083 o = len(fl)
2084 o = len(fl)
2084 chunkiter = changegroup.chunkiter(source)
2085 chunkiter = changegroup.chunkiter(source)
2085 if fl.addgroup(chunkiter, revmap, trp) is None:
2086 if fl.addgroup(chunkiter, revmap, trp) is None:
2086 raise util.Abort(_("received file revlog group is empty"))
2087 raise util.Abort(_("received file revlog group is empty"))
2087 revisions += len(fl) - o
2088 revisions += len(fl) - o
2088 files += 1
2089 files += 1
2089 if f in needfiles:
2090 if f in needfiles:
2090 needs = needfiles[f]
2091 needs = needfiles[f]
2091 for new in xrange(o, len(fl)):
2092 for new in xrange(o, len(fl)):
2092 n = fl.node(new)
2093 n = fl.node(new)
2093 if n in needs:
2094 if n in needs:
2094 needs.remove(n)
2095 needs.remove(n)
2095 if not needs:
2096 if not needs:
2096 del needfiles[f]
2097 del needfiles[f]
2097 self.ui.progress(_('files'), None)
2098 self.ui.progress(_('files'), None)
2098
2099
2099 for f, needs in needfiles.iteritems():
2100 for f, needs in needfiles.iteritems():
2100 fl = self.file(f)
2101 fl = self.file(f)
2101 for n in needs:
2102 for n in needs:
2102 try:
2103 try:
2103 fl.rev(n)
2104 fl.rev(n)
2104 except error.LookupError:
2105 except error.LookupError:
2105 raise util.Abort(
2106 raise util.Abort(
2106 _('missing file data for %s:%s - run hg verify') %
2107 _('missing file data for %s:%s - run hg verify') %
2107 (f, hex(n)))
2108 (f, hex(n)))
2108
2109
2109 newheads = len(cl.heads())
2110 newheads = len(cl.heads())
2110 heads = ""
2111 heads = ""
2111 if oldheads and newheads != oldheads:
2112 if oldheads and newheads != oldheads:
2112 heads = _(" (%+d heads)") % (newheads - oldheads)
2113 heads = _(" (%+d heads)") % (newheads - oldheads)
2113
2114
2114 self.ui.status(_("added %d changesets"
2115 self.ui.status(_("added %d changesets"
2115 " with %d changes to %d files%s\n")
2116 " with %d changes to %d files%s\n")
2116 % (changesets, revisions, files, heads))
2117 % (changesets, revisions, files, heads))
2117
2118
2118 if changesets > 0:
2119 if changesets > 0:
2119 p = lambda: cl.writepending() and self.root or ""
2120 p = lambda: cl.writepending() and self.root or ""
2120 self.hook('pretxnchangegroup', throw=True,
2121 self.hook('pretxnchangegroup', throw=True,
2121 node=hex(cl.node(clstart)), source=srctype,
2122 node=hex(cl.node(clstart)), source=srctype,
2122 url=url, pending=p)
2123 url=url, pending=p)
2123
2124
2124 # make changelog see real files again
2125 # make changelog see real files again
2125 cl.finalize(trp)
2126 cl.finalize(trp)
2126
2127
2127 tr.close()
2128 tr.close()
2128 finally:
2129 finally:
2129 del tr
2130 del tr
2130
2131
2131 if changesets > 0:
2132 if changesets > 0:
2132 # forcefully update the on-disk branch cache
2133 # forcefully update the on-disk branch cache
2133 self.ui.debug("updating the branch cache\n")
2134 self.ui.debug("updating the branch cache\n")
2134 self.branchtags()
2135 self.branchtags()
2135 self.hook("changegroup", node=hex(cl.node(clstart)),
2136 self.hook("changegroup", node=hex(cl.node(clstart)),
2136 source=srctype, url=url)
2137 source=srctype, url=url)
2137
2138
2138 for i in xrange(clstart, clend):
2139 for i in xrange(clstart, clend):
2139 self.hook("incoming", node=hex(cl.node(i)),
2140 self.hook("incoming", node=hex(cl.node(i)),
2140 source=srctype, url=url)
2141 source=srctype, url=url)
2141
2142
2142 # never return 0 here:
2143 # never return 0 here:
2143 if newheads < oldheads:
2144 if newheads < oldheads:
2144 return newheads - oldheads - 1
2145 return newheads - oldheads - 1
2145 else:
2146 else:
2146 return newheads - oldheads + 1
2147 return newheads - oldheads + 1
2147
2148
2148
2149
2149 def stream_in(self, remote):
2150 def stream_in(self, remote):
2150 fp = remote.stream_out()
2151 fp = remote.stream_out()
2151 l = fp.readline()
2152 l = fp.readline()
2152 try:
2153 try:
2153 resp = int(l)
2154 resp = int(l)
2154 except ValueError:
2155 except ValueError:
2155 raise error.ResponseError(
2156 raise error.ResponseError(
2156 _('Unexpected response from remote server:'), l)
2157 _('Unexpected response from remote server:'), l)
2157 if resp == 1:
2158 if resp == 1:
2158 raise util.Abort(_('operation forbidden by server'))
2159 raise util.Abort(_('operation forbidden by server'))
2159 elif resp == 2:
2160 elif resp == 2:
2160 raise util.Abort(_('locking the remote repository failed'))
2161 raise util.Abort(_('locking the remote repository failed'))
2161 elif resp != 0:
2162 elif resp != 0:
2162 raise util.Abort(_('the server sent an unknown error code'))
2163 raise util.Abort(_('the server sent an unknown error code'))
2163 self.ui.status(_('streaming all changes\n'))
2164 self.ui.status(_('streaming all changes\n'))
2164 l = fp.readline()
2165 l = fp.readline()
2165 try:
2166 try:
2166 total_files, total_bytes = map(int, l.split(' ', 1))
2167 total_files, total_bytes = map(int, l.split(' ', 1))
2167 except (ValueError, TypeError):
2168 except (ValueError, TypeError):
2168 raise error.ResponseError(
2169 raise error.ResponseError(
2169 _('Unexpected response from remote server:'), l)
2170 _('Unexpected response from remote server:'), l)
2170 self.ui.status(_('%d files to transfer, %s of data\n') %
2171 self.ui.status(_('%d files to transfer, %s of data\n') %
2171 (total_files, util.bytecount(total_bytes)))
2172 (total_files, util.bytecount(total_bytes)))
2172 start = time.time()
2173 start = time.time()
2173 for i in xrange(total_files):
2174 for i in xrange(total_files):
2174 # XXX doesn't support '\n' or '\r' in filenames
2175 # XXX doesn't support '\n' or '\r' in filenames
2175 l = fp.readline()
2176 l = fp.readline()
2176 try:
2177 try:
2177 name, size = l.split('\0', 1)
2178 name, size = l.split('\0', 1)
2178 size = int(size)
2179 size = int(size)
2179 except (ValueError, TypeError):
2180 except (ValueError, TypeError):
2180 raise error.ResponseError(
2181 raise error.ResponseError(
2181 _('Unexpected response from remote server:'), l)
2182 _('Unexpected response from remote server:'), l)
2182 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
2183 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
2183 # for backwards compat, name was partially encoded
2184 # for backwards compat, name was partially encoded
2184 ofp = self.sopener(store.decodedir(name), 'w')
2185 ofp = self.sopener(store.decodedir(name), 'w')
2185 for chunk in util.filechunkiter(fp, limit=size):
2186 for chunk in util.filechunkiter(fp, limit=size):
2186 ofp.write(chunk)
2187 ofp.write(chunk)
2187 ofp.close()
2188 ofp.close()
2188 elapsed = time.time() - start
2189 elapsed = time.time() - start
2189 if elapsed <= 0:
2190 if elapsed <= 0:
2190 elapsed = 0.001
2191 elapsed = 0.001
2191 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
2192 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
2192 (util.bytecount(total_bytes), elapsed,
2193 (util.bytecount(total_bytes), elapsed,
2193 util.bytecount(total_bytes / elapsed)))
2194 util.bytecount(total_bytes / elapsed)))
2194 self.invalidate()
2195 self.invalidate()
2195 return len(self.heads()) + 1
2196 return len(self.heads()) + 1
2196
2197
2197 def clone(self, remote, heads=[], stream=False):
2198 def clone(self, remote, heads=[], stream=False):
2198 '''clone remote repository.
2199 '''clone remote repository.
2199
2200
2200 keyword arguments:
2201 keyword arguments:
2201 heads: list of revs to clone (forces use of pull)
2202 heads: list of revs to clone (forces use of pull)
2202 stream: use streaming clone if possible'''
2203 stream: use streaming clone if possible'''
2203
2204
2204 # now, all clients that can request uncompressed clones can
2205 # now, all clients that can request uncompressed clones can
2205 # read repo formats supported by all servers that can serve
2206 # read repo formats supported by all servers that can serve
2206 # them.
2207 # them.
2207
2208
2208 # if revlog format changes, client will have to check version
2209 # if revlog format changes, client will have to check version
2209 # and format flags on "stream" capability, and use
2210 # and format flags on "stream" capability, and use
2210 # uncompressed only if compatible.
2211 # uncompressed only if compatible.
2211
2212
2212 if stream and not heads and remote.capable('stream'):
2213 if stream and not heads and remote.capable('stream'):
2213 return self.stream_in(remote)
2214 return self.stream_in(remote)
2214 return self.pull(remote, heads)
2215 return self.pull(remote, heads)
2215
2216
2216 # used to avoid circular references so destructors work
2217 # used to avoid circular references so destructors work
2217 def aftertrans(files):
2218 def aftertrans(files):
2218 renamefiles = [tuple(t) for t in files]
2219 renamefiles = [tuple(t) for t in files]
2219 def a():
2220 def a():
2220 for src, dest in renamefiles:
2221 for src, dest in renamefiles:
2221 util.rename(src, dest)
2222 util.rename(src, dest)
2222 return a
2223 return a
2223
2224
2224 def instance(ui, path, create):
2225 def instance(ui, path, create):
2225 return localrepository(ui, util.drop_scheme('file', path), create)
2226 return localrepository(ui, util.drop_scheme('file', path), create)
2226
2227
2227 def islocal(path):
2228 def islocal(path):
2228 return True
2229 return True
@@ -1,1165 +1,1165 b''
1 3:911600dab2ae
1 3:911600dab2ae
2 requesting all changes
2 requesting all changes
3 adding changesets
3 adding changesets
4 adding manifests
4 adding manifests
5 adding file changes
5 adding file changes
6 added 1 changesets with 3 changes to 3 files
6 added 1 changesets with 3 changes to 3 files
7 updating to branch default
7 updating to branch default
8 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
8 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
9
9
10 Extension disabled for lack of a hook
10 Extension disabled for lack of a hook
11 Pushing as user fred
11 Pushing as user fred
12 hgrc = """
12 hgrc = """
13 """
13 """
14 pushing to ../b
14 pushing to ../b
15 searching for changes
15 searching for changes
16 common changesets up to 6675d58eff77
16 common changesets up to 6675d58eff77
17 3 changesets found
17 3 changesets found
18 list of changesets:
18 list of changesets:
19 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
19 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
20 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
20 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
21 911600dab2ae7a9baff75958b84fe606851ce955
21 911600dab2ae7a9baff75958b84fe606851ce955
22 adding changesets
22 adding changesets
23 bundling changes: 0 chunks
23 bundling changes: 0 chunks
24 bundling changes: 1 chunks
24 bundling changes: 1 chunks
25 bundling changes: 2 chunks
25 bundling changes: 2 chunks
26 bundling changes: 3 chunks
26 bundling changes: 3 chunks
27 bundling changes: 4 chunks
27 bundling changes: 4 chunks
28 bundling changes: 5 chunks
28 bundling changes: 5 chunks
29 bundling changes: 6 chunks
29 bundling changes: 6 chunks
30 bundling changes: 7 chunks
30 bundling changes: 7 chunks
31 bundling changes: 8 chunks
31 bundling changes: 8 chunks
32 bundling changes: 9 chunks
32 bundling changes: 9 chunks
33 bundling manifests: 0 chunks
33 bundling manifests: 0 chunks
34 bundling manifests: 1 chunks
34 bundling manifests: 1 chunks
35 bundling manifests: 2 chunks
35 bundling manifests: 2 chunks
36 bundling manifests: 3 chunks
36 bundling manifests: 3 chunks
37 bundling manifests: 4 chunks
37 bundling manifests: 4 chunks
38 bundling manifests: 5 chunks
38 bundling manifests: 5 chunks
39 bundling manifests: 6 chunks
39 bundling manifests: 6 chunks
40 bundling manifests: 7 chunks
40 bundling manifests: 7 chunks
41 bundling manifests: 8 chunks
41 bundling manifests: 8 chunks
42 bundling manifests: 9 chunks
42 bundling manifests: 9 chunks
43 bundling files: foo/Bar/file.txt 0 chunks
43 bundling files: foo/Bar/file.txt 0 chunks
44 bundling files: foo/Bar/file.txt 1 chunks
44 bundling files: foo/Bar/file.txt 1 chunks
45 bundling files: foo/Bar/file.txt 2 chunks
45 bundling files: foo/Bar/file.txt 2 chunks
46 bundling files: foo/Bar/file.txt 3 chunks
46 bundling files: foo/Bar/file.txt 3 chunks
47 bundling files: foo/file.txt 4 chunks
47 bundling files: foo/file.txt 4 chunks
48 bundling files: foo/file.txt 5 chunks
48 bundling files: foo/file.txt 5 chunks
49 bundling files: foo/file.txt 6 chunks
49 bundling files: foo/file.txt 6 chunks
50 bundling files: foo/file.txt 7 chunks
50 bundling files: foo/file.txt 7 chunks
51 bundling files: quux/file.py 8 chunks
51 bundling files: quux/file.py 8 chunks
52 bundling files: quux/file.py 9 chunks
52 bundling files: quux/file.py 9 chunks
53 bundling files: quux/file.py 10 chunks
53 bundling files: quux/file.py 10 chunks
54 bundling files: quux/file.py 11 chunks
54 bundling files: quux/file.py 11 chunks
55 changesets: 1 chunks
55 changesets: 1 chunks
56 add changeset ef1ea85a6374
56 add changeset ef1ea85a6374
57 changesets: 2 chunks
57 changesets: 2 chunks
58 add changeset f9cafe1212c8
58 add changeset f9cafe1212c8
59 changesets: 3 chunks
59 changesets: 3 chunks
60 add changeset 911600dab2ae
60 add changeset 911600dab2ae
61 adding manifests
61 adding manifests
62 manifests: 1/3 chunks (33.33%)
62 manifests: 1/3 chunks (33.33%)
63 manifests: 2/3 chunks (66.67%)
63 manifests: 2/3 chunks (66.67%)
64 manifests: 3/3 chunks (100.00%)
64 manifests: 3/3 chunks (100.00%)
65 adding file changes
65 adding file changes
66 adding foo/Bar/file.txt revisions
66 adding foo/Bar/file.txt revisions
67 files: 1/3 chunks (33.33%)
67 files: 1/3 chunks (33.33%)
68 adding foo/file.txt revisions
68 adding foo/file.txt revisions
69 files: 2/3 chunks (66.67%)
69 files: 2/3 chunks (66.67%)
70 adding quux/file.py revisions
70 adding quux/file.py revisions
71 files: 3/3 chunks (100.00%)
71 files: 3/3 chunks (100.00%)
72 added 3 changesets with 3 changes to 3 files
72 added 3 changesets with 3 changes to 3 files
73 updating the branch cache
73 updating the branch cache
74 rolling back push to revision 1
74 rolling back to revision 1 (undo push)
75 0:6675d58eff77
75 0:6675d58eff77
76
76
77 Extension disabled for lack of acl.sources
77 Extension disabled for lack of acl.sources
78 Pushing as user fred
78 Pushing as user fred
79 hgrc = """
79 hgrc = """
80 [hooks]
80 [hooks]
81 pretxnchangegroup.acl = python:hgext.acl.hook
81 pretxnchangegroup.acl = python:hgext.acl.hook
82 """
82 """
83 pushing to ../b
83 pushing to ../b
84 searching for changes
84 searching for changes
85 common changesets up to 6675d58eff77
85 common changesets up to 6675d58eff77
86 invalidating branch cache (tip differs)
86 invalidating branch cache (tip differs)
87 3 changesets found
87 3 changesets found
88 list of changesets:
88 list of changesets:
89 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
89 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
90 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
90 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
91 911600dab2ae7a9baff75958b84fe606851ce955
91 911600dab2ae7a9baff75958b84fe606851ce955
92 adding changesets
92 adding changesets
93 bundling changes: 0 chunks
93 bundling changes: 0 chunks
94 bundling changes: 1 chunks
94 bundling changes: 1 chunks
95 bundling changes: 2 chunks
95 bundling changes: 2 chunks
96 bundling changes: 3 chunks
96 bundling changes: 3 chunks
97 bundling changes: 4 chunks
97 bundling changes: 4 chunks
98 bundling changes: 5 chunks
98 bundling changes: 5 chunks
99 bundling changes: 6 chunks
99 bundling changes: 6 chunks
100 bundling changes: 7 chunks
100 bundling changes: 7 chunks
101 bundling changes: 8 chunks
101 bundling changes: 8 chunks
102 bundling changes: 9 chunks
102 bundling changes: 9 chunks
103 bundling manifests: 0 chunks
103 bundling manifests: 0 chunks
104 bundling manifests: 1 chunks
104 bundling manifests: 1 chunks
105 bundling manifests: 2 chunks
105 bundling manifests: 2 chunks
106 bundling manifests: 3 chunks
106 bundling manifests: 3 chunks
107 bundling manifests: 4 chunks
107 bundling manifests: 4 chunks
108 bundling manifests: 5 chunks
108 bundling manifests: 5 chunks
109 bundling manifests: 6 chunks
109 bundling manifests: 6 chunks
110 bundling manifests: 7 chunks
110 bundling manifests: 7 chunks
111 bundling manifests: 8 chunks
111 bundling manifests: 8 chunks
112 bundling manifests: 9 chunks
112 bundling manifests: 9 chunks
113 bundling files: foo/Bar/file.txt 0 chunks
113 bundling files: foo/Bar/file.txt 0 chunks
114 bundling files: foo/Bar/file.txt 1 chunks
114 bundling files: foo/Bar/file.txt 1 chunks
115 bundling files: foo/Bar/file.txt 2 chunks
115 bundling files: foo/Bar/file.txt 2 chunks
116 bundling files: foo/Bar/file.txt 3 chunks
116 bundling files: foo/Bar/file.txt 3 chunks
117 bundling files: foo/file.txt 4 chunks
117 bundling files: foo/file.txt 4 chunks
118 bundling files: foo/file.txt 5 chunks
118 bundling files: foo/file.txt 5 chunks
119 bundling files: foo/file.txt 6 chunks
119 bundling files: foo/file.txt 6 chunks
120 bundling files: foo/file.txt 7 chunks
120 bundling files: foo/file.txt 7 chunks
121 bundling files: quux/file.py 8 chunks
121 bundling files: quux/file.py 8 chunks
122 bundling files: quux/file.py 9 chunks
122 bundling files: quux/file.py 9 chunks
123 bundling files: quux/file.py 10 chunks
123 bundling files: quux/file.py 10 chunks
124 bundling files: quux/file.py 11 chunks
124 bundling files: quux/file.py 11 chunks
125 changesets: 1 chunks
125 changesets: 1 chunks
126 add changeset ef1ea85a6374
126 add changeset ef1ea85a6374
127 changesets: 2 chunks
127 changesets: 2 chunks
128 add changeset f9cafe1212c8
128 add changeset f9cafe1212c8
129 changesets: 3 chunks
129 changesets: 3 chunks
130 add changeset 911600dab2ae
130 add changeset 911600dab2ae
131 adding manifests
131 adding manifests
132 manifests: 1/3 chunks (33.33%)
132 manifests: 1/3 chunks (33.33%)
133 manifests: 2/3 chunks (66.67%)
133 manifests: 2/3 chunks (66.67%)
134 manifests: 3/3 chunks (100.00%)
134 manifests: 3/3 chunks (100.00%)
135 adding file changes
135 adding file changes
136 adding foo/Bar/file.txt revisions
136 adding foo/Bar/file.txt revisions
137 files: 1/3 chunks (33.33%)
137 files: 1/3 chunks (33.33%)
138 adding foo/file.txt revisions
138 adding foo/file.txt revisions
139 files: 2/3 chunks (66.67%)
139 files: 2/3 chunks (66.67%)
140 adding quux/file.py revisions
140 adding quux/file.py revisions
141 files: 3/3 chunks (100.00%)
141 files: 3/3 chunks (100.00%)
142 added 3 changesets with 3 changes to 3 files
142 added 3 changesets with 3 changes to 3 files
143 calling hook pretxnchangegroup.acl: hgext.acl.hook
143 calling hook pretxnchangegroup.acl: hgext.acl.hook
144 acl: changes have source "push" - skipping
144 acl: changes have source "push" - skipping
145 updating the branch cache
145 updating the branch cache
146 rolling back push to revision 1
146 rolling back to revision 1 (undo push)
147 0:6675d58eff77
147 0:6675d58eff77
148
148
149 No [acl.allow]/[acl.deny]
149 No [acl.allow]/[acl.deny]
150 Pushing as user fred
150 Pushing as user fred
151 hgrc = """
151 hgrc = """
152 [hooks]
152 [hooks]
153 pretxnchangegroup.acl = python:hgext.acl.hook
153 pretxnchangegroup.acl = python:hgext.acl.hook
154 [acl]
154 [acl]
155 sources = push
155 sources = push
156 """
156 """
157 pushing to ../b
157 pushing to ../b
158 searching for changes
158 searching for changes
159 common changesets up to 6675d58eff77
159 common changesets up to 6675d58eff77
160 invalidating branch cache (tip differs)
160 invalidating branch cache (tip differs)
161 3 changesets found
161 3 changesets found
162 list of changesets:
162 list of changesets:
163 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
163 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
164 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
164 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
165 911600dab2ae7a9baff75958b84fe606851ce955
165 911600dab2ae7a9baff75958b84fe606851ce955
166 adding changesets
166 adding changesets
167 bundling changes: 0 chunks
167 bundling changes: 0 chunks
168 bundling changes: 1 chunks
168 bundling changes: 1 chunks
169 bundling changes: 2 chunks
169 bundling changes: 2 chunks
170 bundling changes: 3 chunks
170 bundling changes: 3 chunks
171 bundling changes: 4 chunks
171 bundling changes: 4 chunks
172 bundling changes: 5 chunks
172 bundling changes: 5 chunks
173 bundling changes: 6 chunks
173 bundling changes: 6 chunks
174 bundling changes: 7 chunks
174 bundling changes: 7 chunks
175 bundling changes: 8 chunks
175 bundling changes: 8 chunks
176 bundling changes: 9 chunks
176 bundling changes: 9 chunks
177 bundling manifests: 0 chunks
177 bundling manifests: 0 chunks
178 bundling manifests: 1 chunks
178 bundling manifests: 1 chunks
179 bundling manifests: 2 chunks
179 bundling manifests: 2 chunks
180 bundling manifests: 3 chunks
180 bundling manifests: 3 chunks
181 bundling manifests: 4 chunks
181 bundling manifests: 4 chunks
182 bundling manifests: 5 chunks
182 bundling manifests: 5 chunks
183 bundling manifests: 6 chunks
183 bundling manifests: 6 chunks
184 bundling manifests: 7 chunks
184 bundling manifests: 7 chunks
185 bundling manifests: 8 chunks
185 bundling manifests: 8 chunks
186 bundling manifests: 9 chunks
186 bundling manifests: 9 chunks
187 bundling files: foo/Bar/file.txt 0 chunks
187 bundling files: foo/Bar/file.txt 0 chunks
188 bundling files: foo/Bar/file.txt 1 chunks
188 bundling files: foo/Bar/file.txt 1 chunks
189 bundling files: foo/Bar/file.txt 2 chunks
189 bundling files: foo/Bar/file.txt 2 chunks
190 bundling files: foo/Bar/file.txt 3 chunks
190 bundling files: foo/Bar/file.txt 3 chunks
191 bundling files: foo/file.txt 4 chunks
191 bundling files: foo/file.txt 4 chunks
192 bundling files: foo/file.txt 5 chunks
192 bundling files: foo/file.txt 5 chunks
193 bundling files: foo/file.txt 6 chunks
193 bundling files: foo/file.txt 6 chunks
194 bundling files: foo/file.txt 7 chunks
194 bundling files: foo/file.txt 7 chunks
195 bundling files: quux/file.py 8 chunks
195 bundling files: quux/file.py 8 chunks
196 bundling files: quux/file.py 9 chunks
196 bundling files: quux/file.py 9 chunks
197 bundling files: quux/file.py 10 chunks
197 bundling files: quux/file.py 10 chunks
198 bundling files: quux/file.py 11 chunks
198 bundling files: quux/file.py 11 chunks
199 changesets: 1 chunks
199 changesets: 1 chunks
200 add changeset ef1ea85a6374
200 add changeset ef1ea85a6374
201 changesets: 2 chunks
201 changesets: 2 chunks
202 add changeset f9cafe1212c8
202 add changeset f9cafe1212c8
203 changesets: 3 chunks
203 changesets: 3 chunks
204 add changeset 911600dab2ae
204 add changeset 911600dab2ae
205 adding manifests
205 adding manifests
206 manifests: 1/3 chunks (33.33%)
206 manifests: 1/3 chunks (33.33%)
207 manifests: 2/3 chunks (66.67%)
207 manifests: 2/3 chunks (66.67%)
208 manifests: 3/3 chunks (100.00%)
208 manifests: 3/3 chunks (100.00%)
209 adding file changes
209 adding file changes
210 adding foo/Bar/file.txt revisions
210 adding foo/Bar/file.txt revisions
211 files: 1/3 chunks (33.33%)
211 files: 1/3 chunks (33.33%)
212 adding foo/file.txt revisions
212 adding foo/file.txt revisions
213 files: 2/3 chunks (66.67%)
213 files: 2/3 chunks (66.67%)
214 adding quux/file.py revisions
214 adding quux/file.py revisions
215 files: 3/3 chunks (100.00%)
215 files: 3/3 chunks (100.00%)
216 added 3 changesets with 3 changes to 3 files
216 added 3 changesets with 3 changes to 3 files
217 calling hook pretxnchangegroup.acl: hgext.acl.hook
217 calling hook pretxnchangegroup.acl: hgext.acl.hook
218 acl: acl.allow not enabled
218 acl: acl.allow not enabled
219 acl: acl.deny not enabled
219 acl: acl.deny not enabled
220 acl: allowing changeset ef1ea85a6374
220 acl: allowing changeset ef1ea85a6374
221 acl: allowing changeset f9cafe1212c8
221 acl: allowing changeset f9cafe1212c8
222 acl: allowing changeset 911600dab2ae
222 acl: allowing changeset 911600dab2ae
223 updating the branch cache
223 updating the branch cache
224 rolling back push to revision 1
224 rolling back to revision 1 (undo push)
225 0:6675d58eff77
225 0:6675d58eff77
226
226
227 Empty [acl.allow]
227 Empty [acl.allow]
228 Pushing as user fred
228 Pushing as user fred
229 hgrc = """
229 hgrc = """
230 [hooks]
230 [hooks]
231 pretxnchangegroup.acl = python:hgext.acl.hook
231 pretxnchangegroup.acl = python:hgext.acl.hook
232 [acl]
232 [acl]
233 sources = push
233 sources = push
234 [acl.allow]
234 [acl.allow]
235 """
235 """
236 pushing to ../b
236 pushing to ../b
237 searching for changes
237 searching for changes
238 common changesets up to 6675d58eff77
238 common changesets up to 6675d58eff77
239 invalidating branch cache (tip differs)
239 invalidating branch cache (tip differs)
240 3 changesets found
240 3 changesets found
241 list of changesets:
241 list of changesets:
242 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
242 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
243 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
243 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
244 911600dab2ae7a9baff75958b84fe606851ce955
244 911600dab2ae7a9baff75958b84fe606851ce955
245 adding changesets
245 adding changesets
246 bundling changes: 0 chunks
246 bundling changes: 0 chunks
247 bundling changes: 1 chunks
247 bundling changes: 1 chunks
248 bundling changes: 2 chunks
248 bundling changes: 2 chunks
249 bundling changes: 3 chunks
249 bundling changes: 3 chunks
250 bundling changes: 4 chunks
250 bundling changes: 4 chunks
251 bundling changes: 5 chunks
251 bundling changes: 5 chunks
252 bundling changes: 6 chunks
252 bundling changes: 6 chunks
253 bundling changes: 7 chunks
253 bundling changes: 7 chunks
254 bundling changes: 8 chunks
254 bundling changes: 8 chunks
255 bundling changes: 9 chunks
255 bundling changes: 9 chunks
256 bundling manifests: 0 chunks
256 bundling manifests: 0 chunks
257 bundling manifests: 1 chunks
257 bundling manifests: 1 chunks
258 bundling manifests: 2 chunks
258 bundling manifests: 2 chunks
259 bundling manifests: 3 chunks
259 bundling manifests: 3 chunks
260 bundling manifests: 4 chunks
260 bundling manifests: 4 chunks
261 bundling manifests: 5 chunks
261 bundling manifests: 5 chunks
262 bundling manifests: 6 chunks
262 bundling manifests: 6 chunks
263 bundling manifests: 7 chunks
263 bundling manifests: 7 chunks
264 bundling manifests: 8 chunks
264 bundling manifests: 8 chunks
265 bundling manifests: 9 chunks
265 bundling manifests: 9 chunks
266 bundling files: foo/Bar/file.txt 0 chunks
266 bundling files: foo/Bar/file.txt 0 chunks
267 bundling files: foo/Bar/file.txt 1 chunks
267 bundling files: foo/Bar/file.txt 1 chunks
268 bundling files: foo/Bar/file.txt 2 chunks
268 bundling files: foo/Bar/file.txt 2 chunks
269 bundling files: foo/Bar/file.txt 3 chunks
269 bundling files: foo/Bar/file.txt 3 chunks
270 bundling files: foo/file.txt 4 chunks
270 bundling files: foo/file.txt 4 chunks
271 bundling files: foo/file.txt 5 chunks
271 bundling files: foo/file.txt 5 chunks
272 bundling files: foo/file.txt 6 chunks
272 bundling files: foo/file.txt 6 chunks
273 bundling files: foo/file.txt 7 chunks
273 bundling files: foo/file.txt 7 chunks
274 bundling files: quux/file.py 8 chunks
274 bundling files: quux/file.py 8 chunks
275 bundling files: quux/file.py 9 chunks
275 bundling files: quux/file.py 9 chunks
276 bundling files: quux/file.py 10 chunks
276 bundling files: quux/file.py 10 chunks
277 bundling files: quux/file.py 11 chunks
277 bundling files: quux/file.py 11 chunks
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 enabled, 0 entries for user fred
297 acl: acl.allow enabled, 0 entries for user fred
298 acl: acl.deny not enabled
298 acl: acl.deny not enabled
299 acl: user fred not allowed on foo/file.txt
299 acl: user fred not allowed on foo/file.txt
300 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
300 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
301 transaction abort!
301 transaction abort!
302 rollback completed
302 rollback completed
303 abort: acl: access denied for changeset ef1ea85a6374
303 abort: acl: access denied for changeset ef1ea85a6374
304 no rollback information available
304 no rollback information available
305 0:6675d58eff77
305 0:6675d58eff77
306
306
307 fred is allowed inside foo/
307 fred is allowed inside foo/
308 Pushing as user fred
308 Pushing as user fred
309 hgrc = """
309 hgrc = """
310 [hooks]
310 [hooks]
311 pretxnchangegroup.acl = python:hgext.acl.hook
311 pretxnchangegroup.acl = python:hgext.acl.hook
312 [acl]
312 [acl]
313 sources = push
313 sources = push
314 [acl.allow]
314 [acl.allow]
315 foo/** = fred
315 foo/** = fred
316 """
316 """
317 pushing to ../b
317 pushing to ../b
318 searching for changes
318 searching for changes
319 common changesets up to 6675d58eff77
319 common changesets up to 6675d58eff77
320 3 changesets found
320 3 changesets found
321 list of changesets:
321 list of changesets:
322 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
322 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
323 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
323 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
324 911600dab2ae7a9baff75958b84fe606851ce955
324 911600dab2ae7a9baff75958b84fe606851ce955
325 adding changesets
325 adding changesets
326 bundling changes: 0 chunks
326 bundling changes: 0 chunks
327 bundling changes: 1 chunks
327 bundling changes: 1 chunks
328 bundling changes: 2 chunks
328 bundling changes: 2 chunks
329 bundling changes: 3 chunks
329 bundling changes: 3 chunks
330 bundling changes: 4 chunks
330 bundling changes: 4 chunks
331 bundling changes: 5 chunks
331 bundling changes: 5 chunks
332 bundling changes: 6 chunks
332 bundling changes: 6 chunks
333 bundling changes: 7 chunks
333 bundling changes: 7 chunks
334 bundling changes: 8 chunks
334 bundling changes: 8 chunks
335 bundling changes: 9 chunks
335 bundling changes: 9 chunks
336 bundling manifests: 0 chunks
336 bundling manifests: 0 chunks
337 bundling manifests: 1 chunks
337 bundling manifests: 1 chunks
338 bundling manifests: 2 chunks
338 bundling manifests: 2 chunks
339 bundling manifests: 3 chunks
339 bundling manifests: 3 chunks
340 bundling manifests: 4 chunks
340 bundling manifests: 4 chunks
341 bundling manifests: 5 chunks
341 bundling manifests: 5 chunks
342 bundling manifests: 6 chunks
342 bundling manifests: 6 chunks
343 bundling manifests: 7 chunks
343 bundling manifests: 7 chunks
344 bundling manifests: 8 chunks
344 bundling manifests: 8 chunks
345 bundling manifests: 9 chunks
345 bundling manifests: 9 chunks
346 bundling files: foo/Bar/file.txt 0 chunks
346 bundling files: foo/Bar/file.txt 0 chunks
347 bundling files: foo/Bar/file.txt 1 chunks
347 bundling files: foo/Bar/file.txt 1 chunks
348 bundling files: foo/Bar/file.txt 2 chunks
348 bundling files: foo/Bar/file.txt 2 chunks
349 bundling files: foo/Bar/file.txt 3 chunks
349 bundling files: foo/Bar/file.txt 3 chunks
350 bundling files: foo/file.txt 4 chunks
350 bundling files: foo/file.txt 4 chunks
351 bundling files: foo/file.txt 5 chunks
351 bundling files: foo/file.txt 5 chunks
352 bundling files: foo/file.txt 6 chunks
352 bundling files: foo/file.txt 6 chunks
353 bundling files: foo/file.txt 7 chunks
353 bundling files: foo/file.txt 7 chunks
354 bundling files: quux/file.py 8 chunks
354 bundling files: quux/file.py 8 chunks
355 bundling files: quux/file.py 9 chunks
355 bundling files: quux/file.py 9 chunks
356 bundling files: quux/file.py 10 chunks
356 bundling files: quux/file.py 10 chunks
357 bundling files: quux/file.py 11 chunks
357 bundling files: quux/file.py 11 chunks
358 changesets: 1 chunks
358 changesets: 1 chunks
359 add changeset ef1ea85a6374
359 add changeset ef1ea85a6374
360 changesets: 2 chunks
360 changesets: 2 chunks
361 add changeset f9cafe1212c8
361 add changeset f9cafe1212c8
362 changesets: 3 chunks
362 changesets: 3 chunks
363 add changeset 911600dab2ae
363 add changeset 911600dab2ae
364 adding manifests
364 adding manifests
365 manifests: 1/3 chunks (33.33%)
365 manifests: 1/3 chunks (33.33%)
366 manifests: 2/3 chunks (66.67%)
366 manifests: 2/3 chunks (66.67%)
367 manifests: 3/3 chunks (100.00%)
367 manifests: 3/3 chunks (100.00%)
368 adding file changes
368 adding file changes
369 adding foo/Bar/file.txt revisions
369 adding foo/Bar/file.txt revisions
370 files: 1/3 chunks (33.33%)
370 files: 1/3 chunks (33.33%)
371 adding foo/file.txt revisions
371 adding foo/file.txt revisions
372 files: 2/3 chunks (66.67%)
372 files: 2/3 chunks (66.67%)
373 adding quux/file.py revisions
373 adding quux/file.py revisions
374 files: 3/3 chunks (100.00%)
374 files: 3/3 chunks (100.00%)
375 added 3 changesets with 3 changes to 3 files
375 added 3 changesets with 3 changes to 3 files
376 calling hook pretxnchangegroup.acl: hgext.acl.hook
376 calling hook pretxnchangegroup.acl: hgext.acl.hook
377 acl: acl.allow enabled, 1 entries for user fred
377 acl: acl.allow enabled, 1 entries for user fred
378 acl: acl.deny not enabled
378 acl: acl.deny not enabled
379 acl: allowing changeset ef1ea85a6374
379 acl: allowing changeset ef1ea85a6374
380 acl: allowing changeset f9cafe1212c8
380 acl: allowing changeset f9cafe1212c8
381 acl: user fred not allowed on quux/file.py
381 acl: user fred not allowed on quux/file.py
382 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
382 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
383 transaction abort!
383 transaction abort!
384 rollback completed
384 rollback completed
385 abort: acl: access denied for changeset 911600dab2ae
385 abort: acl: access denied for changeset 911600dab2ae
386 no rollback information available
386 no rollback information available
387 0:6675d58eff77
387 0:6675d58eff77
388
388
389 Empty [acl.deny]
389 Empty [acl.deny]
390 Pushing as user barney
390 Pushing as user barney
391 hgrc = """
391 hgrc = """
392 [hooks]
392 [hooks]
393 pretxnchangegroup.acl = python:hgext.acl.hook
393 pretxnchangegroup.acl = python:hgext.acl.hook
394 [acl]
394 [acl]
395 sources = push
395 sources = push
396 [acl.allow]
396 [acl.allow]
397 foo/** = fred
397 foo/** = fred
398 [acl.deny]
398 [acl.deny]
399 """
399 """
400 pushing to ../b
400 pushing to ../b
401 searching for changes
401 searching for changes
402 common changesets up to 6675d58eff77
402 common changesets up to 6675d58eff77
403 3 changesets found
403 3 changesets found
404 list of changesets:
404 list of changesets:
405 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
405 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
406 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
406 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
407 911600dab2ae7a9baff75958b84fe606851ce955
407 911600dab2ae7a9baff75958b84fe606851ce955
408 adding changesets
408 adding changesets
409 bundling changes: 0 chunks
409 bundling changes: 0 chunks
410 bundling changes: 1 chunks
410 bundling changes: 1 chunks
411 bundling changes: 2 chunks
411 bundling changes: 2 chunks
412 bundling changes: 3 chunks
412 bundling changes: 3 chunks
413 bundling changes: 4 chunks
413 bundling changes: 4 chunks
414 bundling changes: 5 chunks
414 bundling changes: 5 chunks
415 bundling changes: 6 chunks
415 bundling changes: 6 chunks
416 bundling changes: 7 chunks
416 bundling changes: 7 chunks
417 bundling changes: 8 chunks
417 bundling changes: 8 chunks
418 bundling changes: 9 chunks
418 bundling changes: 9 chunks
419 bundling manifests: 0 chunks
419 bundling manifests: 0 chunks
420 bundling manifests: 1 chunks
420 bundling manifests: 1 chunks
421 bundling manifests: 2 chunks
421 bundling manifests: 2 chunks
422 bundling manifests: 3 chunks
422 bundling manifests: 3 chunks
423 bundling manifests: 4 chunks
423 bundling manifests: 4 chunks
424 bundling manifests: 5 chunks
424 bundling manifests: 5 chunks
425 bundling manifests: 6 chunks
425 bundling manifests: 6 chunks
426 bundling manifests: 7 chunks
426 bundling manifests: 7 chunks
427 bundling manifests: 8 chunks
427 bundling manifests: 8 chunks
428 bundling manifests: 9 chunks
428 bundling manifests: 9 chunks
429 bundling files: foo/Bar/file.txt 0 chunks
429 bundling files: foo/Bar/file.txt 0 chunks
430 bundling files: foo/Bar/file.txt 1 chunks
430 bundling files: foo/Bar/file.txt 1 chunks
431 bundling files: foo/Bar/file.txt 2 chunks
431 bundling files: foo/Bar/file.txt 2 chunks
432 bundling files: foo/Bar/file.txt 3 chunks
432 bundling files: foo/Bar/file.txt 3 chunks
433 bundling files: foo/file.txt 4 chunks
433 bundling files: foo/file.txt 4 chunks
434 bundling files: foo/file.txt 5 chunks
434 bundling files: foo/file.txt 5 chunks
435 bundling files: foo/file.txt 6 chunks
435 bundling files: foo/file.txt 6 chunks
436 bundling files: foo/file.txt 7 chunks
436 bundling files: foo/file.txt 7 chunks
437 bundling files: quux/file.py 8 chunks
437 bundling files: quux/file.py 8 chunks
438 bundling files: quux/file.py 9 chunks
438 bundling files: quux/file.py 9 chunks
439 bundling files: quux/file.py 10 chunks
439 bundling files: quux/file.py 10 chunks
440 bundling files: quux/file.py 11 chunks
440 bundling files: quux/file.py 11 chunks
441 changesets: 1 chunks
441 changesets: 1 chunks
442 add changeset ef1ea85a6374
442 add changeset ef1ea85a6374
443 changesets: 2 chunks
443 changesets: 2 chunks
444 add changeset f9cafe1212c8
444 add changeset f9cafe1212c8
445 changesets: 3 chunks
445 changesets: 3 chunks
446 add changeset 911600dab2ae
446 add changeset 911600dab2ae
447 adding manifests
447 adding manifests
448 manifests: 1/3 chunks (33.33%)
448 manifests: 1/3 chunks (33.33%)
449 manifests: 2/3 chunks (66.67%)
449 manifests: 2/3 chunks (66.67%)
450 manifests: 3/3 chunks (100.00%)
450 manifests: 3/3 chunks (100.00%)
451 adding file changes
451 adding file changes
452 adding foo/Bar/file.txt revisions
452 adding foo/Bar/file.txt revisions
453 files: 1/3 chunks (33.33%)
453 files: 1/3 chunks (33.33%)
454 adding foo/file.txt revisions
454 adding foo/file.txt revisions
455 files: 2/3 chunks (66.67%)
455 files: 2/3 chunks (66.67%)
456 adding quux/file.py revisions
456 adding quux/file.py revisions
457 files: 3/3 chunks (100.00%)
457 files: 3/3 chunks (100.00%)
458 added 3 changesets with 3 changes to 3 files
458 added 3 changesets with 3 changes to 3 files
459 calling hook pretxnchangegroup.acl: hgext.acl.hook
459 calling hook pretxnchangegroup.acl: hgext.acl.hook
460 acl: acl.allow enabled, 0 entries for user barney
460 acl: acl.allow enabled, 0 entries for user barney
461 acl: acl.deny enabled, 0 entries for user barney
461 acl: acl.deny enabled, 0 entries for user barney
462 acl: user barney not allowed on foo/file.txt
462 acl: user barney not allowed on foo/file.txt
463 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
463 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
464 transaction abort!
464 transaction abort!
465 rollback completed
465 rollback completed
466 abort: acl: access denied for changeset ef1ea85a6374
466 abort: acl: access denied for changeset ef1ea85a6374
467 no rollback information available
467 no rollback information available
468 0:6675d58eff77
468 0:6675d58eff77
469
469
470 fred is allowed inside foo/, but not foo/bar/ (case matters)
470 fred is allowed inside foo/, but not foo/bar/ (case matters)
471 Pushing as user fred
471 Pushing as user fred
472 hgrc = """
472 hgrc = """
473 [hooks]
473 [hooks]
474 pretxnchangegroup.acl = python:hgext.acl.hook
474 pretxnchangegroup.acl = python:hgext.acl.hook
475 [acl]
475 [acl]
476 sources = push
476 sources = push
477 [acl.allow]
477 [acl.allow]
478 foo/** = fred
478 foo/** = fred
479 [acl.deny]
479 [acl.deny]
480 foo/bar/** = fred
480 foo/bar/** = fred
481 """
481 """
482 pushing to ../b
482 pushing to ../b
483 searching for changes
483 searching for changes
484 common changesets up to 6675d58eff77
484 common changesets up to 6675d58eff77
485 3 changesets found
485 3 changesets found
486 list of changesets:
486 list of changesets:
487 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
487 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
488 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
488 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
489 911600dab2ae7a9baff75958b84fe606851ce955
489 911600dab2ae7a9baff75958b84fe606851ce955
490 adding changesets
490 adding changesets
491 bundling changes: 0 chunks
491 bundling changes: 0 chunks
492 bundling changes: 1 chunks
492 bundling changes: 1 chunks
493 bundling changes: 2 chunks
493 bundling changes: 2 chunks
494 bundling changes: 3 chunks
494 bundling changes: 3 chunks
495 bundling changes: 4 chunks
495 bundling changes: 4 chunks
496 bundling changes: 5 chunks
496 bundling changes: 5 chunks
497 bundling changes: 6 chunks
497 bundling changes: 6 chunks
498 bundling changes: 7 chunks
498 bundling changes: 7 chunks
499 bundling changes: 8 chunks
499 bundling changes: 8 chunks
500 bundling changes: 9 chunks
500 bundling changes: 9 chunks
501 bundling manifests: 0 chunks
501 bundling manifests: 0 chunks
502 bundling manifests: 1 chunks
502 bundling manifests: 1 chunks
503 bundling manifests: 2 chunks
503 bundling manifests: 2 chunks
504 bundling manifests: 3 chunks
504 bundling manifests: 3 chunks
505 bundling manifests: 4 chunks
505 bundling manifests: 4 chunks
506 bundling manifests: 5 chunks
506 bundling manifests: 5 chunks
507 bundling manifests: 6 chunks
507 bundling manifests: 6 chunks
508 bundling manifests: 7 chunks
508 bundling manifests: 7 chunks
509 bundling manifests: 8 chunks
509 bundling manifests: 8 chunks
510 bundling manifests: 9 chunks
510 bundling manifests: 9 chunks
511 bundling files: foo/Bar/file.txt 0 chunks
511 bundling files: foo/Bar/file.txt 0 chunks
512 bundling files: foo/Bar/file.txt 1 chunks
512 bundling files: foo/Bar/file.txt 1 chunks
513 bundling files: foo/Bar/file.txt 2 chunks
513 bundling files: foo/Bar/file.txt 2 chunks
514 bundling files: foo/Bar/file.txt 3 chunks
514 bundling files: foo/Bar/file.txt 3 chunks
515 bundling files: foo/file.txt 4 chunks
515 bundling files: foo/file.txt 4 chunks
516 bundling files: foo/file.txt 5 chunks
516 bundling files: foo/file.txt 5 chunks
517 bundling files: foo/file.txt 6 chunks
517 bundling files: foo/file.txt 6 chunks
518 bundling files: foo/file.txt 7 chunks
518 bundling files: foo/file.txt 7 chunks
519 bundling files: quux/file.py 8 chunks
519 bundling files: quux/file.py 8 chunks
520 bundling files: quux/file.py 9 chunks
520 bundling files: quux/file.py 9 chunks
521 bundling files: quux/file.py 10 chunks
521 bundling files: quux/file.py 10 chunks
522 bundling files: quux/file.py 11 chunks
522 bundling files: quux/file.py 11 chunks
523 changesets: 1 chunks
523 changesets: 1 chunks
524 add changeset ef1ea85a6374
524 add changeset ef1ea85a6374
525 changesets: 2 chunks
525 changesets: 2 chunks
526 add changeset f9cafe1212c8
526 add changeset f9cafe1212c8
527 changesets: 3 chunks
527 changesets: 3 chunks
528 add changeset 911600dab2ae
528 add changeset 911600dab2ae
529 adding manifests
529 adding manifests
530 manifests: 1/3 chunks (33.33%)
530 manifests: 1/3 chunks (33.33%)
531 manifests: 2/3 chunks (66.67%)
531 manifests: 2/3 chunks (66.67%)
532 manifests: 3/3 chunks (100.00%)
532 manifests: 3/3 chunks (100.00%)
533 adding file changes
533 adding file changes
534 adding foo/Bar/file.txt revisions
534 adding foo/Bar/file.txt revisions
535 files: 1/3 chunks (33.33%)
535 files: 1/3 chunks (33.33%)
536 adding foo/file.txt revisions
536 adding foo/file.txt revisions
537 files: 2/3 chunks (66.67%)
537 files: 2/3 chunks (66.67%)
538 adding quux/file.py revisions
538 adding quux/file.py revisions
539 files: 3/3 chunks (100.00%)
539 files: 3/3 chunks (100.00%)
540 added 3 changesets with 3 changes to 3 files
540 added 3 changesets with 3 changes to 3 files
541 calling hook pretxnchangegroup.acl: hgext.acl.hook
541 calling hook pretxnchangegroup.acl: hgext.acl.hook
542 acl: acl.allow enabled, 1 entries for user fred
542 acl: acl.allow enabled, 1 entries for user fred
543 acl: acl.deny enabled, 1 entries for user fred
543 acl: acl.deny enabled, 1 entries for user fred
544 acl: allowing changeset ef1ea85a6374
544 acl: allowing changeset ef1ea85a6374
545 acl: allowing changeset f9cafe1212c8
545 acl: allowing changeset f9cafe1212c8
546 acl: user fred not allowed on quux/file.py
546 acl: user fred not allowed on quux/file.py
547 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
547 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
548 transaction abort!
548 transaction abort!
549 rollback completed
549 rollback completed
550 abort: acl: access denied for changeset 911600dab2ae
550 abort: acl: access denied for changeset 911600dab2ae
551 no rollback information available
551 no rollback information available
552 0:6675d58eff77
552 0:6675d58eff77
553
553
554 fred is allowed inside foo/, but not foo/Bar/
554 fred is allowed inside foo/, but not foo/Bar/
555 Pushing as user fred
555 Pushing as user fred
556 hgrc = """
556 hgrc = """
557 [hooks]
557 [hooks]
558 pretxnchangegroup.acl = python:hgext.acl.hook
558 pretxnchangegroup.acl = python:hgext.acl.hook
559 [acl]
559 [acl]
560 sources = push
560 sources = push
561 [acl.allow]
561 [acl.allow]
562 foo/** = fred
562 foo/** = fred
563 [acl.deny]
563 [acl.deny]
564 foo/bar/** = fred
564 foo/bar/** = fred
565 foo/Bar/** = fred
565 foo/Bar/** = fred
566 """
566 """
567 pushing to ../b
567 pushing to ../b
568 searching for changes
568 searching for changes
569 common changesets up to 6675d58eff77
569 common changesets up to 6675d58eff77
570 3 changesets found
570 3 changesets found
571 list of changesets:
571 list of changesets:
572 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
572 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
573 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
573 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
574 911600dab2ae7a9baff75958b84fe606851ce955
574 911600dab2ae7a9baff75958b84fe606851ce955
575 adding changesets
575 adding changesets
576 bundling changes: 0 chunks
576 bundling changes: 0 chunks
577 bundling changes: 1 chunks
577 bundling changes: 1 chunks
578 bundling changes: 2 chunks
578 bundling changes: 2 chunks
579 bundling changes: 3 chunks
579 bundling changes: 3 chunks
580 bundling changes: 4 chunks
580 bundling changes: 4 chunks
581 bundling changes: 5 chunks
581 bundling changes: 5 chunks
582 bundling changes: 6 chunks
582 bundling changes: 6 chunks
583 bundling changes: 7 chunks
583 bundling changes: 7 chunks
584 bundling changes: 8 chunks
584 bundling changes: 8 chunks
585 bundling changes: 9 chunks
585 bundling changes: 9 chunks
586 bundling manifests: 0 chunks
586 bundling manifests: 0 chunks
587 bundling manifests: 1 chunks
587 bundling manifests: 1 chunks
588 bundling manifests: 2 chunks
588 bundling manifests: 2 chunks
589 bundling manifests: 3 chunks
589 bundling manifests: 3 chunks
590 bundling manifests: 4 chunks
590 bundling manifests: 4 chunks
591 bundling manifests: 5 chunks
591 bundling manifests: 5 chunks
592 bundling manifests: 6 chunks
592 bundling manifests: 6 chunks
593 bundling manifests: 7 chunks
593 bundling manifests: 7 chunks
594 bundling manifests: 8 chunks
594 bundling manifests: 8 chunks
595 bundling manifests: 9 chunks
595 bundling manifests: 9 chunks
596 bundling files: foo/Bar/file.txt 0 chunks
596 bundling files: foo/Bar/file.txt 0 chunks
597 bundling files: foo/Bar/file.txt 1 chunks
597 bundling files: foo/Bar/file.txt 1 chunks
598 bundling files: foo/Bar/file.txt 2 chunks
598 bundling files: foo/Bar/file.txt 2 chunks
599 bundling files: foo/Bar/file.txt 3 chunks
599 bundling files: foo/Bar/file.txt 3 chunks
600 bundling files: foo/file.txt 4 chunks
600 bundling files: foo/file.txt 4 chunks
601 bundling files: foo/file.txt 5 chunks
601 bundling files: foo/file.txt 5 chunks
602 bundling files: foo/file.txt 6 chunks
602 bundling files: foo/file.txt 6 chunks
603 bundling files: foo/file.txt 7 chunks
603 bundling files: foo/file.txt 7 chunks
604 bundling files: quux/file.py 8 chunks
604 bundling files: quux/file.py 8 chunks
605 bundling files: quux/file.py 9 chunks
605 bundling files: quux/file.py 9 chunks
606 bundling files: quux/file.py 10 chunks
606 bundling files: quux/file.py 10 chunks
607 bundling files: quux/file.py 11 chunks
607 bundling files: quux/file.py 11 chunks
608 changesets: 1 chunks
608 changesets: 1 chunks
609 add changeset ef1ea85a6374
609 add changeset ef1ea85a6374
610 changesets: 2 chunks
610 changesets: 2 chunks
611 add changeset f9cafe1212c8
611 add changeset f9cafe1212c8
612 changesets: 3 chunks
612 changesets: 3 chunks
613 add changeset 911600dab2ae
613 add changeset 911600dab2ae
614 adding manifests
614 adding manifests
615 manifests: 1/3 chunks (33.33%)
615 manifests: 1/3 chunks (33.33%)
616 manifests: 2/3 chunks (66.67%)
616 manifests: 2/3 chunks (66.67%)
617 manifests: 3/3 chunks (100.00%)
617 manifests: 3/3 chunks (100.00%)
618 adding file changes
618 adding file changes
619 adding foo/Bar/file.txt revisions
619 adding foo/Bar/file.txt revisions
620 files: 1/3 chunks (33.33%)
620 files: 1/3 chunks (33.33%)
621 adding foo/file.txt revisions
621 adding foo/file.txt revisions
622 files: 2/3 chunks (66.67%)
622 files: 2/3 chunks (66.67%)
623 adding quux/file.py revisions
623 adding quux/file.py revisions
624 files: 3/3 chunks (100.00%)
624 files: 3/3 chunks (100.00%)
625 added 3 changesets with 3 changes to 3 files
625 added 3 changesets with 3 changes to 3 files
626 calling hook pretxnchangegroup.acl: hgext.acl.hook
626 calling hook pretxnchangegroup.acl: hgext.acl.hook
627 acl: acl.allow enabled, 1 entries for user fred
627 acl: acl.allow enabled, 1 entries for user fred
628 acl: acl.deny enabled, 2 entries for user fred
628 acl: acl.deny enabled, 2 entries for user fred
629 acl: allowing changeset ef1ea85a6374
629 acl: allowing changeset ef1ea85a6374
630 acl: user fred denied on foo/Bar/file.txt
630 acl: user fred denied on foo/Bar/file.txt
631 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
631 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset f9cafe1212c8
632 transaction abort!
632 transaction abort!
633 rollback completed
633 rollback completed
634 abort: acl: access denied for changeset f9cafe1212c8
634 abort: acl: access denied for changeset f9cafe1212c8
635 no rollback information available
635 no rollback information available
636 0:6675d58eff77
636 0:6675d58eff77
637
637
638 barney is not mentioned => not allowed anywhere
638 barney is not mentioned => not allowed anywhere
639 Pushing as user barney
639 Pushing as user barney
640 hgrc = """
640 hgrc = """
641 [hooks]
641 [hooks]
642 pretxnchangegroup.acl = python:hgext.acl.hook
642 pretxnchangegroup.acl = python:hgext.acl.hook
643 [acl]
643 [acl]
644 sources = push
644 sources = push
645 [acl.allow]
645 [acl.allow]
646 foo/** = fred
646 foo/** = fred
647 [acl.deny]
647 [acl.deny]
648 foo/bar/** = fred
648 foo/bar/** = fred
649 foo/Bar/** = fred
649 foo/Bar/** = fred
650 """
650 """
651 pushing to ../b
651 pushing to ../b
652 searching for changes
652 searching for changes
653 common changesets up to 6675d58eff77
653 common changesets up to 6675d58eff77
654 3 changesets found
654 3 changesets found
655 list of changesets:
655 list of changesets:
656 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
656 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
657 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
657 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
658 911600dab2ae7a9baff75958b84fe606851ce955
658 911600dab2ae7a9baff75958b84fe606851ce955
659 adding changesets
659 adding changesets
660 bundling changes: 0 chunks
660 bundling changes: 0 chunks
661 bundling changes: 1 chunks
661 bundling changes: 1 chunks
662 bundling changes: 2 chunks
662 bundling changes: 2 chunks
663 bundling changes: 3 chunks
663 bundling changes: 3 chunks
664 bundling changes: 4 chunks
664 bundling changes: 4 chunks
665 bundling changes: 5 chunks
665 bundling changes: 5 chunks
666 bundling changes: 6 chunks
666 bundling changes: 6 chunks
667 bundling changes: 7 chunks
667 bundling changes: 7 chunks
668 bundling changes: 8 chunks
668 bundling changes: 8 chunks
669 bundling changes: 9 chunks
669 bundling changes: 9 chunks
670 bundling manifests: 0 chunks
670 bundling manifests: 0 chunks
671 bundling manifests: 1 chunks
671 bundling manifests: 1 chunks
672 bundling manifests: 2 chunks
672 bundling manifests: 2 chunks
673 bundling manifests: 3 chunks
673 bundling manifests: 3 chunks
674 bundling manifests: 4 chunks
674 bundling manifests: 4 chunks
675 bundling manifests: 5 chunks
675 bundling manifests: 5 chunks
676 bundling manifests: 6 chunks
676 bundling manifests: 6 chunks
677 bundling manifests: 7 chunks
677 bundling manifests: 7 chunks
678 bundling manifests: 8 chunks
678 bundling manifests: 8 chunks
679 bundling manifests: 9 chunks
679 bundling manifests: 9 chunks
680 bundling files: foo/Bar/file.txt 0 chunks
680 bundling files: foo/Bar/file.txt 0 chunks
681 bundling files: foo/Bar/file.txt 1 chunks
681 bundling files: foo/Bar/file.txt 1 chunks
682 bundling files: foo/Bar/file.txt 2 chunks
682 bundling files: foo/Bar/file.txt 2 chunks
683 bundling files: foo/Bar/file.txt 3 chunks
683 bundling files: foo/Bar/file.txt 3 chunks
684 bundling files: foo/file.txt 4 chunks
684 bundling files: foo/file.txt 4 chunks
685 bundling files: foo/file.txt 5 chunks
685 bundling files: foo/file.txt 5 chunks
686 bundling files: foo/file.txt 6 chunks
686 bundling files: foo/file.txt 6 chunks
687 bundling files: foo/file.txt 7 chunks
687 bundling files: foo/file.txt 7 chunks
688 bundling files: quux/file.py 8 chunks
688 bundling files: quux/file.py 8 chunks
689 bundling files: quux/file.py 9 chunks
689 bundling files: quux/file.py 9 chunks
690 bundling files: quux/file.py 10 chunks
690 bundling files: quux/file.py 10 chunks
691 bundling files: quux/file.py 11 chunks
691 bundling files: quux/file.py 11 chunks
692 changesets: 1 chunks
692 changesets: 1 chunks
693 add changeset ef1ea85a6374
693 add changeset ef1ea85a6374
694 changesets: 2 chunks
694 changesets: 2 chunks
695 add changeset f9cafe1212c8
695 add changeset f9cafe1212c8
696 changesets: 3 chunks
696 changesets: 3 chunks
697 add changeset 911600dab2ae
697 add changeset 911600dab2ae
698 adding manifests
698 adding manifests
699 manifests: 1/3 chunks (33.33%)
699 manifests: 1/3 chunks (33.33%)
700 manifests: 2/3 chunks (66.67%)
700 manifests: 2/3 chunks (66.67%)
701 manifests: 3/3 chunks (100.00%)
701 manifests: 3/3 chunks (100.00%)
702 adding file changes
702 adding file changes
703 adding foo/Bar/file.txt revisions
703 adding foo/Bar/file.txt revisions
704 files: 1/3 chunks (33.33%)
704 files: 1/3 chunks (33.33%)
705 adding foo/file.txt revisions
705 adding foo/file.txt revisions
706 files: 2/3 chunks (66.67%)
706 files: 2/3 chunks (66.67%)
707 adding quux/file.py revisions
707 adding quux/file.py revisions
708 files: 3/3 chunks (100.00%)
708 files: 3/3 chunks (100.00%)
709 added 3 changesets with 3 changes to 3 files
709 added 3 changesets with 3 changes to 3 files
710 calling hook pretxnchangegroup.acl: hgext.acl.hook
710 calling hook pretxnchangegroup.acl: hgext.acl.hook
711 acl: acl.allow enabled, 0 entries for user barney
711 acl: acl.allow enabled, 0 entries for user barney
712 acl: acl.deny enabled, 0 entries for user barney
712 acl: acl.deny enabled, 0 entries for user barney
713 acl: user barney not allowed on foo/file.txt
713 acl: user barney not allowed on foo/file.txt
714 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
714 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset ef1ea85a6374
715 transaction abort!
715 transaction abort!
716 rollback completed
716 rollback completed
717 abort: acl: access denied for changeset ef1ea85a6374
717 abort: acl: access denied for changeset ef1ea85a6374
718 no rollback information available
718 no rollback information available
719 0:6675d58eff77
719 0:6675d58eff77
720
720
721 barney is allowed everywhere
721 barney is allowed everywhere
722 Pushing as user barney
722 Pushing as user barney
723 hgrc = """
723 hgrc = """
724 [hooks]
724 [hooks]
725 pretxnchangegroup.acl = python:hgext.acl.hook
725 pretxnchangegroup.acl = python:hgext.acl.hook
726 [acl]
726 [acl]
727 sources = push
727 sources = push
728 [acl.allow]
728 [acl.allow]
729 foo/** = fred
729 foo/** = fred
730 [acl.deny]
730 [acl.deny]
731 foo/bar/** = fred
731 foo/bar/** = fred
732 foo/Bar/** = fred
732 foo/Bar/** = fred
733 [acl.allow]
733 [acl.allow]
734 ** = barney
734 ** = barney
735 """
735 """
736 pushing to ../b
736 pushing to ../b
737 searching for changes
737 searching for changes
738 common changesets up to 6675d58eff77
738 common changesets up to 6675d58eff77
739 3 changesets found
739 3 changesets found
740 list of changesets:
740 list of changesets:
741 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
741 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
742 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
742 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
743 911600dab2ae7a9baff75958b84fe606851ce955
743 911600dab2ae7a9baff75958b84fe606851ce955
744 adding changesets
744 adding changesets
745 bundling changes: 0 chunks
745 bundling changes: 0 chunks
746 bundling changes: 1 chunks
746 bundling changes: 1 chunks
747 bundling changes: 2 chunks
747 bundling changes: 2 chunks
748 bundling changes: 3 chunks
748 bundling changes: 3 chunks
749 bundling changes: 4 chunks
749 bundling changes: 4 chunks
750 bundling changes: 5 chunks
750 bundling changes: 5 chunks
751 bundling changes: 6 chunks
751 bundling changes: 6 chunks
752 bundling changes: 7 chunks
752 bundling changes: 7 chunks
753 bundling changes: 8 chunks
753 bundling changes: 8 chunks
754 bundling changes: 9 chunks
754 bundling changes: 9 chunks
755 bundling manifests: 0 chunks
755 bundling manifests: 0 chunks
756 bundling manifests: 1 chunks
756 bundling manifests: 1 chunks
757 bundling manifests: 2 chunks
757 bundling manifests: 2 chunks
758 bundling manifests: 3 chunks
758 bundling manifests: 3 chunks
759 bundling manifests: 4 chunks
759 bundling manifests: 4 chunks
760 bundling manifests: 5 chunks
760 bundling manifests: 5 chunks
761 bundling manifests: 6 chunks
761 bundling manifests: 6 chunks
762 bundling manifests: 7 chunks
762 bundling manifests: 7 chunks
763 bundling manifests: 8 chunks
763 bundling manifests: 8 chunks
764 bundling manifests: 9 chunks
764 bundling manifests: 9 chunks
765 bundling files: foo/Bar/file.txt 0 chunks
765 bundling files: foo/Bar/file.txt 0 chunks
766 bundling files: foo/Bar/file.txt 1 chunks
766 bundling files: foo/Bar/file.txt 1 chunks
767 bundling files: foo/Bar/file.txt 2 chunks
767 bundling files: foo/Bar/file.txt 2 chunks
768 bundling files: foo/Bar/file.txt 3 chunks
768 bundling files: foo/Bar/file.txt 3 chunks
769 bundling files: foo/file.txt 4 chunks
769 bundling files: foo/file.txt 4 chunks
770 bundling files: foo/file.txt 5 chunks
770 bundling files: foo/file.txt 5 chunks
771 bundling files: foo/file.txt 6 chunks
771 bundling files: foo/file.txt 6 chunks
772 bundling files: foo/file.txt 7 chunks
772 bundling files: foo/file.txt 7 chunks
773 bundling files: quux/file.py 8 chunks
773 bundling files: quux/file.py 8 chunks
774 bundling files: quux/file.py 9 chunks
774 bundling files: quux/file.py 9 chunks
775 bundling files: quux/file.py 10 chunks
775 bundling files: quux/file.py 10 chunks
776 bundling files: quux/file.py 11 chunks
776 bundling files: quux/file.py 11 chunks
777 changesets: 1 chunks
777 changesets: 1 chunks
778 add changeset ef1ea85a6374
778 add changeset ef1ea85a6374
779 changesets: 2 chunks
779 changesets: 2 chunks
780 add changeset f9cafe1212c8
780 add changeset f9cafe1212c8
781 changesets: 3 chunks
781 changesets: 3 chunks
782 add changeset 911600dab2ae
782 add changeset 911600dab2ae
783 adding manifests
783 adding manifests
784 manifests: 1/3 chunks (33.33%)
784 manifests: 1/3 chunks (33.33%)
785 manifests: 2/3 chunks (66.67%)
785 manifests: 2/3 chunks (66.67%)
786 manifests: 3/3 chunks (100.00%)
786 manifests: 3/3 chunks (100.00%)
787 adding file changes
787 adding file changes
788 adding foo/Bar/file.txt revisions
788 adding foo/Bar/file.txt revisions
789 files: 1/3 chunks (33.33%)
789 files: 1/3 chunks (33.33%)
790 adding foo/file.txt revisions
790 adding foo/file.txt revisions
791 files: 2/3 chunks (66.67%)
791 files: 2/3 chunks (66.67%)
792 adding quux/file.py revisions
792 adding quux/file.py revisions
793 files: 3/3 chunks (100.00%)
793 files: 3/3 chunks (100.00%)
794 added 3 changesets with 3 changes to 3 files
794 added 3 changesets with 3 changes to 3 files
795 calling hook pretxnchangegroup.acl: hgext.acl.hook
795 calling hook pretxnchangegroup.acl: hgext.acl.hook
796 acl: acl.allow enabled, 1 entries for user barney
796 acl: acl.allow enabled, 1 entries for user barney
797 acl: acl.deny enabled, 0 entries for user barney
797 acl: acl.deny enabled, 0 entries for user barney
798 acl: allowing changeset ef1ea85a6374
798 acl: allowing changeset ef1ea85a6374
799 acl: allowing changeset f9cafe1212c8
799 acl: allowing changeset f9cafe1212c8
800 acl: allowing changeset 911600dab2ae
800 acl: allowing changeset 911600dab2ae
801 updating the branch cache
801 updating the branch cache
802 rolling back push to revision 1
802 rolling back to revision 1 (undo push)
803 0:6675d58eff77
803 0:6675d58eff77
804
804
805 wilma can change files with a .txt extension
805 wilma can change files with a .txt extension
806 Pushing as user wilma
806 Pushing as user wilma
807 hgrc = """
807 hgrc = """
808 [hooks]
808 [hooks]
809 pretxnchangegroup.acl = python:hgext.acl.hook
809 pretxnchangegroup.acl = python:hgext.acl.hook
810 [acl]
810 [acl]
811 sources = push
811 sources = push
812 [acl.allow]
812 [acl.allow]
813 foo/** = fred
813 foo/** = fred
814 [acl.deny]
814 [acl.deny]
815 foo/bar/** = fred
815 foo/bar/** = fred
816 foo/Bar/** = fred
816 foo/Bar/** = fred
817 [acl.allow]
817 [acl.allow]
818 ** = barney
818 ** = barney
819 **/*.txt = wilma
819 **/*.txt = wilma
820 """
820 """
821 pushing to ../b
821 pushing to ../b
822 searching for changes
822 searching for changes
823 common changesets up to 6675d58eff77
823 common changesets up to 6675d58eff77
824 invalidating branch cache (tip differs)
824 invalidating branch cache (tip differs)
825 3 changesets found
825 3 changesets found
826 list of changesets:
826 list of changesets:
827 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
827 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
828 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
828 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
829 911600dab2ae7a9baff75958b84fe606851ce955
829 911600dab2ae7a9baff75958b84fe606851ce955
830 adding changesets
830 adding changesets
831 bundling changes: 0 chunks
831 bundling changes: 0 chunks
832 bundling changes: 1 chunks
832 bundling changes: 1 chunks
833 bundling changes: 2 chunks
833 bundling changes: 2 chunks
834 bundling changes: 3 chunks
834 bundling changes: 3 chunks
835 bundling changes: 4 chunks
835 bundling changes: 4 chunks
836 bundling changes: 5 chunks
836 bundling changes: 5 chunks
837 bundling changes: 6 chunks
837 bundling changes: 6 chunks
838 bundling changes: 7 chunks
838 bundling changes: 7 chunks
839 bundling changes: 8 chunks
839 bundling changes: 8 chunks
840 bundling changes: 9 chunks
840 bundling changes: 9 chunks
841 bundling manifests: 0 chunks
841 bundling manifests: 0 chunks
842 bundling manifests: 1 chunks
842 bundling manifests: 1 chunks
843 bundling manifests: 2 chunks
843 bundling manifests: 2 chunks
844 bundling manifests: 3 chunks
844 bundling manifests: 3 chunks
845 bundling manifests: 4 chunks
845 bundling manifests: 4 chunks
846 bundling manifests: 5 chunks
846 bundling manifests: 5 chunks
847 bundling manifests: 6 chunks
847 bundling manifests: 6 chunks
848 bundling manifests: 7 chunks
848 bundling manifests: 7 chunks
849 bundling manifests: 8 chunks
849 bundling manifests: 8 chunks
850 bundling manifests: 9 chunks
850 bundling manifests: 9 chunks
851 bundling files: foo/Bar/file.txt 0 chunks
851 bundling files: foo/Bar/file.txt 0 chunks
852 bundling files: foo/Bar/file.txt 1 chunks
852 bundling files: foo/Bar/file.txt 1 chunks
853 bundling files: foo/Bar/file.txt 2 chunks
853 bundling files: foo/Bar/file.txt 2 chunks
854 bundling files: foo/Bar/file.txt 3 chunks
854 bundling files: foo/Bar/file.txt 3 chunks
855 bundling files: foo/file.txt 4 chunks
855 bundling files: foo/file.txt 4 chunks
856 bundling files: foo/file.txt 5 chunks
856 bundling files: foo/file.txt 5 chunks
857 bundling files: foo/file.txt 6 chunks
857 bundling files: foo/file.txt 6 chunks
858 bundling files: foo/file.txt 7 chunks
858 bundling files: foo/file.txt 7 chunks
859 bundling files: quux/file.py 8 chunks
859 bundling files: quux/file.py 8 chunks
860 bundling files: quux/file.py 9 chunks
860 bundling files: quux/file.py 9 chunks
861 bundling files: quux/file.py 10 chunks
861 bundling files: quux/file.py 10 chunks
862 bundling files: quux/file.py 11 chunks
862 bundling files: quux/file.py 11 chunks
863 changesets: 1 chunks
863 changesets: 1 chunks
864 add changeset ef1ea85a6374
864 add changeset ef1ea85a6374
865 changesets: 2 chunks
865 changesets: 2 chunks
866 add changeset f9cafe1212c8
866 add changeset f9cafe1212c8
867 changesets: 3 chunks
867 changesets: 3 chunks
868 add changeset 911600dab2ae
868 add changeset 911600dab2ae
869 adding manifests
869 adding manifests
870 manifests: 1/3 chunks (33.33%)
870 manifests: 1/3 chunks (33.33%)
871 manifests: 2/3 chunks (66.67%)
871 manifests: 2/3 chunks (66.67%)
872 manifests: 3/3 chunks (100.00%)
872 manifests: 3/3 chunks (100.00%)
873 adding file changes
873 adding file changes
874 adding foo/Bar/file.txt revisions
874 adding foo/Bar/file.txt revisions
875 files: 1/3 chunks (33.33%)
875 files: 1/3 chunks (33.33%)
876 adding foo/file.txt revisions
876 adding foo/file.txt revisions
877 files: 2/3 chunks (66.67%)
877 files: 2/3 chunks (66.67%)
878 adding quux/file.py revisions
878 adding quux/file.py revisions
879 files: 3/3 chunks (100.00%)
879 files: 3/3 chunks (100.00%)
880 added 3 changesets with 3 changes to 3 files
880 added 3 changesets with 3 changes to 3 files
881 calling hook pretxnchangegroup.acl: hgext.acl.hook
881 calling hook pretxnchangegroup.acl: hgext.acl.hook
882 acl: acl.allow enabled, 1 entries for user wilma
882 acl: acl.allow enabled, 1 entries for user wilma
883 acl: acl.deny enabled, 0 entries for user wilma
883 acl: acl.deny enabled, 0 entries for user wilma
884 acl: allowing changeset ef1ea85a6374
884 acl: allowing changeset ef1ea85a6374
885 acl: allowing changeset f9cafe1212c8
885 acl: allowing changeset f9cafe1212c8
886 acl: user wilma not allowed on quux/file.py
886 acl: user wilma not allowed on quux/file.py
887 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
887 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
888 transaction abort!
888 transaction abort!
889 rollback completed
889 rollback completed
890 abort: acl: access denied for changeset 911600dab2ae
890 abort: acl: access denied for changeset 911600dab2ae
891 no rollback information available
891 no rollback information available
892 0:6675d58eff77
892 0:6675d58eff77
893
893
894 file specified by acl.config does not exist
894 file specified by acl.config does not exist
895 Pushing as user barney
895 Pushing as user barney
896 hgrc = """
896 hgrc = """
897 [hooks]
897 [hooks]
898 pretxnchangegroup.acl = python:hgext.acl.hook
898 pretxnchangegroup.acl = python:hgext.acl.hook
899 [acl]
899 [acl]
900 sources = push
900 sources = push
901 [acl.allow]
901 [acl.allow]
902 foo/** = fred
902 foo/** = fred
903 [acl.deny]
903 [acl.deny]
904 foo/bar/** = fred
904 foo/bar/** = fred
905 foo/Bar/** = fred
905 foo/Bar/** = fred
906 [acl.allow]
906 [acl.allow]
907 ** = barney
907 ** = barney
908 **/*.txt = wilma
908 **/*.txt = wilma
909 [acl]
909 [acl]
910 config = ../acl.config
910 config = ../acl.config
911 """
911 """
912 pushing to ../b
912 pushing to ../b
913 searching for changes
913 searching for changes
914 common changesets up to 6675d58eff77
914 common changesets up to 6675d58eff77
915 3 changesets found
915 3 changesets found
916 list of changesets:
916 list of changesets:
917 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
917 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
918 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
918 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
919 911600dab2ae7a9baff75958b84fe606851ce955
919 911600dab2ae7a9baff75958b84fe606851ce955
920 adding changesets
920 adding changesets
921 bundling changes: 0 chunks
921 bundling changes: 0 chunks
922 bundling changes: 1 chunks
922 bundling changes: 1 chunks
923 bundling changes: 2 chunks
923 bundling changes: 2 chunks
924 bundling changes: 3 chunks
924 bundling changes: 3 chunks
925 bundling changes: 4 chunks
925 bundling changes: 4 chunks
926 bundling changes: 5 chunks
926 bundling changes: 5 chunks
927 bundling changes: 6 chunks
927 bundling changes: 6 chunks
928 bundling changes: 7 chunks
928 bundling changes: 7 chunks
929 bundling changes: 8 chunks
929 bundling changes: 8 chunks
930 bundling changes: 9 chunks
930 bundling changes: 9 chunks
931 bundling manifests: 0 chunks
931 bundling manifests: 0 chunks
932 bundling manifests: 1 chunks
932 bundling manifests: 1 chunks
933 bundling manifests: 2 chunks
933 bundling manifests: 2 chunks
934 bundling manifests: 3 chunks
934 bundling manifests: 3 chunks
935 bundling manifests: 4 chunks
935 bundling manifests: 4 chunks
936 bundling manifests: 5 chunks
936 bundling manifests: 5 chunks
937 bundling manifests: 6 chunks
937 bundling manifests: 6 chunks
938 bundling manifests: 7 chunks
938 bundling manifests: 7 chunks
939 bundling manifests: 8 chunks
939 bundling manifests: 8 chunks
940 bundling manifests: 9 chunks
940 bundling manifests: 9 chunks
941 bundling files: foo/Bar/file.txt 0 chunks
941 bundling files: foo/Bar/file.txt 0 chunks
942 bundling files: foo/Bar/file.txt 1 chunks
942 bundling files: foo/Bar/file.txt 1 chunks
943 bundling files: foo/Bar/file.txt 2 chunks
943 bundling files: foo/Bar/file.txt 2 chunks
944 bundling files: foo/Bar/file.txt 3 chunks
944 bundling files: foo/Bar/file.txt 3 chunks
945 bundling files: foo/file.txt 4 chunks
945 bundling files: foo/file.txt 4 chunks
946 bundling files: foo/file.txt 5 chunks
946 bundling files: foo/file.txt 5 chunks
947 bundling files: foo/file.txt 6 chunks
947 bundling files: foo/file.txt 6 chunks
948 bundling files: foo/file.txt 7 chunks
948 bundling files: foo/file.txt 7 chunks
949 bundling files: quux/file.py 8 chunks
949 bundling files: quux/file.py 8 chunks
950 bundling files: quux/file.py 9 chunks
950 bundling files: quux/file.py 9 chunks
951 bundling files: quux/file.py 10 chunks
951 bundling files: quux/file.py 10 chunks
952 bundling files: quux/file.py 11 chunks
952 bundling files: quux/file.py 11 chunks
953 changesets: 1 chunks
953 changesets: 1 chunks
954 add changeset ef1ea85a6374
954 add changeset ef1ea85a6374
955 changesets: 2 chunks
955 changesets: 2 chunks
956 add changeset f9cafe1212c8
956 add changeset f9cafe1212c8
957 changesets: 3 chunks
957 changesets: 3 chunks
958 add changeset 911600dab2ae
958 add changeset 911600dab2ae
959 adding manifests
959 adding manifests
960 manifests: 1/3 chunks (33.33%)
960 manifests: 1/3 chunks (33.33%)
961 manifests: 2/3 chunks (66.67%)
961 manifests: 2/3 chunks (66.67%)
962 manifests: 3/3 chunks (100.00%)
962 manifests: 3/3 chunks (100.00%)
963 adding file changes
963 adding file changes
964 adding foo/Bar/file.txt revisions
964 adding foo/Bar/file.txt revisions
965 files: 1/3 chunks (33.33%)
965 files: 1/3 chunks (33.33%)
966 adding foo/file.txt revisions
966 adding foo/file.txt revisions
967 files: 2/3 chunks (66.67%)
967 files: 2/3 chunks (66.67%)
968 adding quux/file.py revisions
968 adding quux/file.py revisions
969 files: 3/3 chunks (100.00%)
969 files: 3/3 chunks (100.00%)
970 added 3 changesets with 3 changes to 3 files
970 added 3 changesets with 3 changes to 3 files
971 calling hook pretxnchangegroup.acl: hgext.acl.hook
971 calling hook pretxnchangegroup.acl: hgext.acl.hook
972 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
972 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
973 transaction abort!
973 transaction abort!
974 rollback completed
974 rollback completed
975 abort: No such file or directory: ../acl.config
975 abort: No such file or directory: ../acl.config
976 no rollback information available
976 no rollback information available
977 0:6675d58eff77
977 0:6675d58eff77
978
978
979 betty is allowed inside foo/ by a acl.config file
979 betty is allowed inside foo/ by a acl.config file
980 Pushing as user betty
980 Pushing as user betty
981 hgrc = """
981 hgrc = """
982 [hooks]
982 [hooks]
983 pretxnchangegroup.acl = python:hgext.acl.hook
983 pretxnchangegroup.acl = python:hgext.acl.hook
984 [acl]
984 [acl]
985 sources = push
985 sources = push
986 [acl.allow]
986 [acl.allow]
987 foo/** = fred
987 foo/** = fred
988 [acl.deny]
988 [acl.deny]
989 foo/bar/** = fred
989 foo/bar/** = fred
990 foo/Bar/** = fred
990 foo/Bar/** = fred
991 [acl.allow]
991 [acl.allow]
992 ** = barney
992 ** = barney
993 **/*.txt = wilma
993 **/*.txt = wilma
994 [acl]
994 [acl]
995 config = ../acl.config
995 config = ../acl.config
996 """
996 """
997 acl.config = """
997 acl.config = """
998 [acl.allow]
998 [acl.allow]
999 foo/** = betty
999 foo/** = betty
1000 """
1000 """
1001 pushing to ../b
1001 pushing to ../b
1002 searching for changes
1002 searching for changes
1003 common changesets up to 6675d58eff77
1003 common changesets up to 6675d58eff77
1004 3 changesets found
1004 3 changesets found
1005 list of changesets:
1005 list of changesets:
1006 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1006 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1007 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1007 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1008 911600dab2ae7a9baff75958b84fe606851ce955
1008 911600dab2ae7a9baff75958b84fe606851ce955
1009 adding changesets
1009 adding changesets
1010 bundling changes: 0 chunks
1010 bundling changes: 0 chunks
1011 bundling changes: 1 chunks
1011 bundling changes: 1 chunks
1012 bundling changes: 2 chunks
1012 bundling changes: 2 chunks
1013 bundling changes: 3 chunks
1013 bundling changes: 3 chunks
1014 bundling changes: 4 chunks
1014 bundling changes: 4 chunks
1015 bundling changes: 5 chunks
1015 bundling changes: 5 chunks
1016 bundling changes: 6 chunks
1016 bundling changes: 6 chunks
1017 bundling changes: 7 chunks
1017 bundling changes: 7 chunks
1018 bundling changes: 8 chunks
1018 bundling changes: 8 chunks
1019 bundling changes: 9 chunks
1019 bundling changes: 9 chunks
1020 bundling manifests: 0 chunks
1020 bundling manifests: 0 chunks
1021 bundling manifests: 1 chunks
1021 bundling manifests: 1 chunks
1022 bundling manifests: 2 chunks
1022 bundling manifests: 2 chunks
1023 bundling manifests: 3 chunks
1023 bundling manifests: 3 chunks
1024 bundling manifests: 4 chunks
1024 bundling manifests: 4 chunks
1025 bundling manifests: 5 chunks
1025 bundling manifests: 5 chunks
1026 bundling manifests: 6 chunks
1026 bundling manifests: 6 chunks
1027 bundling manifests: 7 chunks
1027 bundling manifests: 7 chunks
1028 bundling manifests: 8 chunks
1028 bundling manifests: 8 chunks
1029 bundling manifests: 9 chunks
1029 bundling manifests: 9 chunks
1030 bundling files: foo/Bar/file.txt 0 chunks
1030 bundling files: foo/Bar/file.txt 0 chunks
1031 bundling files: foo/Bar/file.txt 1 chunks
1031 bundling files: foo/Bar/file.txt 1 chunks
1032 bundling files: foo/Bar/file.txt 2 chunks
1032 bundling files: foo/Bar/file.txt 2 chunks
1033 bundling files: foo/Bar/file.txt 3 chunks
1033 bundling files: foo/Bar/file.txt 3 chunks
1034 bundling files: foo/file.txt 4 chunks
1034 bundling files: foo/file.txt 4 chunks
1035 bundling files: foo/file.txt 5 chunks
1035 bundling files: foo/file.txt 5 chunks
1036 bundling files: foo/file.txt 6 chunks
1036 bundling files: foo/file.txt 6 chunks
1037 bundling files: foo/file.txt 7 chunks
1037 bundling files: foo/file.txt 7 chunks
1038 bundling files: quux/file.py 8 chunks
1038 bundling files: quux/file.py 8 chunks
1039 bundling files: quux/file.py 9 chunks
1039 bundling files: quux/file.py 9 chunks
1040 bundling files: quux/file.py 10 chunks
1040 bundling files: quux/file.py 10 chunks
1041 bundling files: quux/file.py 11 chunks
1041 bundling files: quux/file.py 11 chunks
1042 changesets: 1 chunks
1042 changesets: 1 chunks
1043 add changeset ef1ea85a6374
1043 add changeset ef1ea85a6374
1044 changesets: 2 chunks
1044 changesets: 2 chunks
1045 add changeset f9cafe1212c8
1045 add changeset f9cafe1212c8
1046 changesets: 3 chunks
1046 changesets: 3 chunks
1047 add changeset 911600dab2ae
1047 add changeset 911600dab2ae
1048 adding manifests
1048 adding manifests
1049 manifests: 1/3 chunks (33.33%)
1049 manifests: 1/3 chunks (33.33%)
1050 manifests: 2/3 chunks (66.67%)
1050 manifests: 2/3 chunks (66.67%)
1051 manifests: 3/3 chunks (100.00%)
1051 manifests: 3/3 chunks (100.00%)
1052 adding file changes
1052 adding file changes
1053 adding foo/Bar/file.txt revisions
1053 adding foo/Bar/file.txt revisions
1054 files: 1/3 chunks (33.33%)
1054 files: 1/3 chunks (33.33%)
1055 adding foo/file.txt revisions
1055 adding foo/file.txt revisions
1056 files: 2/3 chunks (66.67%)
1056 files: 2/3 chunks (66.67%)
1057 adding quux/file.py revisions
1057 adding quux/file.py revisions
1058 files: 3/3 chunks (100.00%)
1058 files: 3/3 chunks (100.00%)
1059 added 3 changesets with 3 changes to 3 files
1059 added 3 changesets with 3 changes to 3 files
1060 calling hook pretxnchangegroup.acl: hgext.acl.hook
1060 calling hook pretxnchangegroup.acl: hgext.acl.hook
1061 acl: acl.allow enabled, 1 entries for user betty
1061 acl: acl.allow enabled, 1 entries for user betty
1062 acl: acl.deny enabled, 0 entries for user betty
1062 acl: acl.deny enabled, 0 entries for user betty
1063 acl: allowing changeset ef1ea85a6374
1063 acl: allowing changeset ef1ea85a6374
1064 acl: allowing changeset f9cafe1212c8
1064 acl: allowing changeset f9cafe1212c8
1065 acl: user betty not allowed on quux/file.py
1065 acl: user betty not allowed on quux/file.py
1066 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
1066 error: pretxnchangegroup.acl hook failed: acl: access denied for changeset 911600dab2ae
1067 transaction abort!
1067 transaction abort!
1068 rollback completed
1068 rollback completed
1069 abort: acl: access denied for changeset 911600dab2ae
1069 abort: acl: access denied for changeset 911600dab2ae
1070 no rollback information available
1070 no rollback information available
1071 0:6675d58eff77
1071 0:6675d58eff77
1072
1072
1073 acl.config can set only [acl.allow]/[acl.deny]
1073 acl.config can set only [acl.allow]/[acl.deny]
1074 Pushing as user barney
1074 Pushing as user barney
1075 hgrc = """
1075 hgrc = """
1076 [hooks]
1076 [hooks]
1077 pretxnchangegroup.acl = python:hgext.acl.hook
1077 pretxnchangegroup.acl = python:hgext.acl.hook
1078 [acl]
1078 [acl]
1079 sources = push
1079 sources = push
1080 [acl.allow]
1080 [acl.allow]
1081 foo/** = fred
1081 foo/** = fred
1082 [acl.deny]
1082 [acl.deny]
1083 foo/bar/** = fred
1083 foo/bar/** = fred
1084 foo/Bar/** = fred
1084 foo/Bar/** = fred
1085 [acl.allow]
1085 [acl.allow]
1086 ** = barney
1086 ** = barney
1087 **/*.txt = wilma
1087 **/*.txt = wilma
1088 [acl]
1088 [acl]
1089 config = ../acl.config
1089 config = ../acl.config
1090 """
1090 """
1091 acl.config = """
1091 acl.config = """
1092 [acl.allow]
1092 [acl.allow]
1093 foo/** = betty
1093 foo/** = betty
1094 [hooks]
1094 [hooks]
1095 changegroup.acl = false
1095 changegroup.acl = false
1096 """
1096 """
1097 pushing to ../b
1097 pushing to ../b
1098 searching for changes
1098 searching for changes
1099 common changesets up to 6675d58eff77
1099 common changesets up to 6675d58eff77
1100 3 changesets found
1100 3 changesets found
1101 list of changesets:
1101 list of changesets:
1102 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1102 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1103 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1103 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1104 911600dab2ae7a9baff75958b84fe606851ce955
1104 911600dab2ae7a9baff75958b84fe606851ce955
1105 adding changesets
1105 adding changesets
1106 bundling changes: 0 chunks
1106 bundling changes: 0 chunks
1107 bundling changes: 1 chunks
1107 bundling changes: 1 chunks
1108 bundling changes: 2 chunks
1108 bundling changes: 2 chunks
1109 bundling changes: 3 chunks
1109 bundling changes: 3 chunks
1110 bundling changes: 4 chunks
1110 bundling changes: 4 chunks
1111 bundling changes: 5 chunks
1111 bundling changes: 5 chunks
1112 bundling changes: 6 chunks
1112 bundling changes: 6 chunks
1113 bundling changes: 7 chunks
1113 bundling changes: 7 chunks
1114 bundling changes: 8 chunks
1114 bundling changes: 8 chunks
1115 bundling changes: 9 chunks
1115 bundling changes: 9 chunks
1116 bundling manifests: 0 chunks
1116 bundling manifests: 0 chunks
1117 bundling manifests: 1 chunks
1117 bundling manifests: 1 chunks
1118 bundling manifests: 2 chunks
1118 bundling manifests: 2 chunks
1119 bundling manifests: 3 chunks
1119 bundling manifests: 3 chunks
1120 bundling manifests: 4 chunks
1120 bundling manifests: 4 chunks
1121 bundling manifests: 5 chunks
1121 bundling manifests: 5 chunks
1122 bundling manifests: 6 chunks
1122 bundling manifests: 6 chunks
1123 bundling manifests: 7 chunks
1123 bundling manifests: 7 chunks
1124 bundling manifests: 8 chunks
1124 bundling manifests: 8 chunks
1125 bundling manifests: 9 chunks
1125 bundling manifests: 9 chunks
1126 bundling files: foo/Bar/file.txt 0 chunks
1126 bundling files: foo/Bar/file.txt 0 chunks
1127 bundling files: foo/Bar/file.txt 1 chunks
1127 bundling files: foo/Bar/file.txt 1 chunks
1128 bundling files: foo/Bar/file.txt 2 chunks
1128 bundling files: foo/Bar/file.txt 2 chunks
1129 bundling files: foo/Bar/file.txt 3 chunks
1129 bundling files: foo/Bar/file.txt 3 chunks
1130 bundling files: foo/file.txt 4 chunks
1130 bundling files: foo/file.txt 4 chunks
1131 bundling files: foo/file.txt 5 chunks
1131 bundling files: foo/file.txt 5 chunks
1132 bundling files: foo/file.txt 6 chunks
1132 bundling files: foo/file.txt 6 chunks
1133 bundling files: foo/file.txt 7 chunks
1133 bundling files: foo/file.txt 7 chunks
1134 bundling files: quux/file.py 8 chunks
1134 bundling files: quux/file.py 8 chunks
1135 bundling files: quux/file.py 9 chunks
1135 bundling files: quux/file.py 9 chunks
1136 bundling files: quux/file.py 10 chunks
1136 bundling files: quux/file.py 10 chunks
1137 bundling files: quux/file.py 11 chunks
1137 bundling files: quux/file.py 11 chunks
1138 changesets: 1 chunks
1138 changesets: 1 chunks
1139 add changeset ef1ea85a6374
1139 add changeset ef1ea85a6374
1140 changesets: 2 chunks
1140 changesets: 2 chunks
1141 add changeset f9cafe1212c8
1141 add changeset f9cafe1212c8
1142 changesets: 3 chunks
1142 changesets: 3 chunks
1143 add changeset 911600dab2ae
1143 add changeset 911600dab2ae
1144 adding manifests
1144 adding manifests
1145 manifests: 1/3 chunks (33.33%)
1145 manifests: 1/3 chunks (33.33%)
1146 manifests: 2/3 chunks (66.67%)
1146 manifests: 2/3 chunks (66.67%)
1147 manifests: 3/3 chunks (100.00%)
1147 manifests: 3/3 chunks (100.00%)
1148 adding file changes
1148 adding file changes
1149 adding foo/Bar/file.txt revisions
1149 adding foo/Bar/file.txt revisions
1150 files: 1/3 chunks (33.33%)
1150 files: 1/3 chunks (33.33%)
1151 adding foo/file.txt revisions
1151 adding foo/file.txt revisions
1152 files: 2/3 chunks (66.67%)
1152 files: 2/3 chunks (66.67%)
1153 adding quux/file.py revisions
1153 adding quux/file.py revisions
1154 files: 3/3 chunks (100.00%)
1154 files: 3/3 chunks (100.00%)
1155 added 3 changesets with 3 changes to 3 files
1155 added 3 changesets with 3 changes to 3 files
1156 calling hook pretxnchangegroup.acl: hgext.acl.hook
1156 calling hook pretxnchangegroup.acl: hgext.acl.hook
1157 acl: acl.allow enabled, 1 entries for user barney
1157 acl: acl.allow enabled, 1 entries for user barney
1158 acl: acl.deny enabled, 0 entries for user barney
1158 acl: acl.deny enabled, 0 entries for user barney
1159 acl: allowing changeset ef1ea85a6374
1159 acl: allowing changeset ef1ea85a6374
1160 acl: allowing changeset f9cafe1212c8
1160 acl: allowing changeset f9cafe1212c8
1161 acl: allowing changeset 911600dab2ae
1161 acl: allowing changeset 911600dab2ae
1162 updating the branch cache
1162 updating the branch cache
1163 rolling back push to revision 1
1163 rolling back to revision 1 (undo push)
1164 0:6675d58eff77
1164 0:6675d58eff77
1165
1165
@@ -1,95 +1,95 b''
1 # should complain
1 # should complain
2 abort: please specify a revision to backout
2 abort: please specify a revision to backout
3 abort: please specify just one revision
3 abort: please specify just one revision
4 # basic operation
4 # basic operation
5 adding a
5 adding a
6 reverting a
6 reverting a
7 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
7 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
8 a
8 a
9 # file that was removed is recreated
9 # file that was removed is recreated
10 adding a
10 adding a
11 adding a
11 adding a
12 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
12 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
13 content
13 content
14 # backout of backout is as if nothing happened
14 # backout of backout is as if nothing happened
15 removing a
15 removing a
16 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
16 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
17 cat: a: No such file or directory
17 cat: a: No such file or directory
18 # across branch
18 # across branch
19 adding a
19 adding a
20 adding b
20 adding b
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 abort: cannot backout change on a different branch
22 abort: cannot backout change on a different branch
23 adding c
23 adding c
24 created new head
24 created new head
25 abort: cannot backout change on a different branch
25 abort: cannot backout change on a different branch
26 # backout with merge
26 # backout with merge
27 adding a
27 adding a
28 reverting a
28 reverting a
29 created new head
29 created new head
30 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
30 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
31 merging with changeset 3:26b8ccb9ad91
31 merging with changeset 3:26b8ccb9ad91
32 merging a
32 merging a
33 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
33 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
34 (branch merge, don't forget to commit)
34 (branch merge, don't forget to commit)
35 line 1
35 line 1
36 line 2
36 line 2
37 line 3
37 line 3
38 # backout should not back out subsequent changesets
38 # backout should not back out subsequent changesets
39 adding a
39 adding a
40 adding b
40 adding b
41 reverting a
41 reverting a
42 created new head
42 created new head
43 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
43 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
44 the backout changeset is a new head - do not forget to merge
44 the backout changeset is a new head - do not forget to merge
45 (use "backout --merge" if you want to auto-merge)
45 (use "backout --merge" if you want to auto-merge)
46 b
46 b
47 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
48 adding a
48 adding a
49 adding b
49 adding b
50 adding c
50 adding c
51 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
51 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 adding d
52 adding d
53 created new head
53 created new head
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 (branch merge, don't forget to commit)
55 (branch merge, don't forget to commit)
56 # backout of merge should fail
56 # backout of merge should fail
57 abort: cannot backout a merge changeset without --parent
57 abort: cannot backout a merge changeset without --parent
58 # backout of merge with bad parent should fail
58 # backout of merge with bad parent should fail
59 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
59 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
60 # backout of non-merge with parent should fail
60 # backout of non-merge with parent should fail
61 abort: cannot use --parent on non-merge changeset
61 abort: cannot use --parent on non-merge changeset
62 # backout with valid parent should be ok
62 # backout with valid parent should be ok
63 removing d
63 removing d
64 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
64 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
65 rolling back commit to revision 5
65 rolling back to revision 5 (undo commit)
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 removing c
67 removing c
68 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
68 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
69 # named branches
69 # named branches
70 adding default
70 adding default
71 marked working directory as branch branch1
71 marked working directory as branch branch1
72 adding file1
72 adding file1
73 marked working directory as branch branch2
73 marked working directory as branch branch2
74 adding file2
74 adding file2
75 removing file1
75 removing file1
76 created new head
76 created new head
77 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
77 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
78 the backout changeset is a new head - do not forget to merge
78 the backout changeset is a new head - do not forget to merge
79 (use "backout --merge" if you want to auto-merge)
79 (use "backout --merge" if you want to auto-merge)
80 % on branch2 with branch1 not merged, so file1 should still exist:
80 % on branch2 with branch1 not merged, so file1 should still exist:
81 45bbcd363bf0 (branch2)
81 45bbcd363bf0 (branch2)
82 C default
82 C default
83 C file1
83 C file1
84 C file2
84 C file2
85 % on branch2 with branch1 merged, so file1 should be gone:
85 % on branch2 with branch1 merged, so file1 should be gone:
86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
87 (branch merge, don't forget to commit)
87 (branch merge, don't forget to commit)
88 22149cdde76d (branch2) tip
88 22149cdde76d (branch2) tip
89 C default
89 C default
90 C file2
90 C file2
91 % on branch1, so no file1 and file2:
91 % on branch1, so no file1 and file2:
92 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
92 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
93 bf1602f437f3 (branch1)
93 bf1602f437f3 (branch1)
94 C default
94 C default
95 C file1
95 C file1
@@ -1,250 +1,250 b''
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 created new head
2 created new head
3 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
4 rev offset length base linkrev nodeid p1 p2
4 rev offset length base linkrev nodeid p1 p2
5 0 0 3 0 0 362fef284ce2 000000000000 000000000000
5 0 0 3 0 0 362fef284ce2 000000000000 000000000000
6 1 3 5 1 1 125144f7e028 362fef284ce2 000000000000
6 1 3 5 1 1 125144f7e028 362fef284ce2 000000000000
7 2 8 7 2 2 4c982badb186 125144f7e028 000000000000
7 2 8 7 2 2 4c982badb186 125144f7e028 000000000000
8 3 15 9 3 3 19b1fc555737 4c982badb186 000000000000
8 3 15 9 3 3 19b1fc555737 4c982badb186 000000000000
9 rev offset length base linkrev nodeid p1 p2
9 rev offset length base linkrev nodeid p1 p2
10 0 0 75 0 7 2565f3199a74 000000000000 000000000000
10 0 0 75 0 7 2565f3199a74 000000000000 000000000000
11 rev offset length base linkrev nodeid p1 p2
11 rev offset length base linkrev nodeid p1 p2
12 0 0 75 0 8 2565f3199a74 000000000000 000000000000
12 0 0 75 0 8 2565f3199a74 000000000000 000000000000
13 rev offset length base linkrev nodeid p1 p2
13 rev offset length base linkrev nodeid p1 p2
14 0 0 8 0 6 12ab3bcc5ea4 000000000000 000000000000
14 0 0 8 0 6 12ab3bcc5ea4 000000000000 000000000000
15 rev offset length base linkrev nodeid p1 p2
15 rev offset length base linkrev nodeid p1 p2
16 0 0 48 0 0 43eadb1d2d06 000000000000 000000000000
16 0 0 48 0 0 43eadb1d2d06 000000000000 000000000000
17 1 48 48 1 1 8b89697eba2c 43eadb1d2d06 000000000000
17 1 48 48 1 1 8b89697eba2c 43eadb1d2d06 000000000000
18 2 96 48 2 2 626a32663c2f 8b89697eba2c 000000000000
18 2 96 48 2 2 626a32663c2f 8b89697eba2c 000000000000
19 3 144 48 3 3 f54c32f13478 626a32663c2f 000000000000
19 3 144 48 3 3 f54c32f13478 626a32663c2f 000000000000
20 4 192 58 3 6 de68e904d169 626a32663c2f 000000000000
20 4 192 58 3 6 de68e904d169 626a32663c2f 000000000000
21 5 250 68 3 7 09bb521d218d de68e904d169 000000000000
21 5 250 68 3 7 09bb521d218d de68e904d169 000000000000
22 6 318 54 6 8 1fde233dfb0f f54c32f13478 000000000000
22 6 318 54 6 8 1fde233dfb0f f54c32f13478 000000000000
23 checking changesets
23 checking changesets
24 checking manifests
24 checking manifests
25 crosschecking files in changesets and manifests
25 crosschecking files in changesets and manifests
26 checking files
26 checking files
27 4 files, 9 changesets, 7 total revisions
27 4 files, 9 changesets, 7 total revisions
28 searching for changes
28 searching for changes
29 1 changesets found
29 1 changesets found
30 adding changesets
30 adding changesets
31 adding manifests
31 adding manifests
32 adding file changes
32 adding file changes
33 added 1 changesets with 1 changes to 1 files
33 added 1 changesets with 1 changes to 1 files
34 (run 'hg update' to get a working copy)
34 (run 'hg update' to get a working copy)
35 checking changesets
35 checking changesets
36 checking manifests
36 checking manifests
37 crosschecking files in changesets and manifests
37 crosschecking files in changesets and manifests
38 checking files
38 checking files
39 1 files, 1 changesets, 1 total revisions
39 1 files, 1 changesets, 1 total revisions
40 0:5649c9d34dd8
40 0:5649c9d34dd8
41 searching for changes
41 searching for changes
42 2 changesets found
42 2 changesets found
43 adding changesets
43 adding changesets
44 adding manifests
44 adding manifests
45 adding file changes
45 adding file changes
46 added 2 changesets with 2 changes to 1 files
46 added 2 changesets with 2 changes to 1 files
47 (run 'hg update' to get a working copy)
47 (run 'hg update' to get a working copy)
48 checking changesets
48 checking changesets
49 checking manifests
49 checking manifests
50 crosschecking files in changesets and manifests
50 crosschecking files in changesets and manifests
51 checking files
51 checking files
52 1 files, 2 changesets, 2 total revisions
52 1 files, 2 changesets, 2 total revisions
53 1:10b2180f755b
53 1:10b2180f755b
54 searching for changes
54 searching for changes
55 3 changesets found
55 3 changesets found
56 adding changesets
56 adding changesets
57 adding manifests
57 adding manifests
58 adding file changes
58 adding file changes
59 added 3 changesets with 3 changes to 1 files
59 added 3 changesets with 3 changes to 1 files
60 (run 'hg update' to get a working copy)
60 (run 'hg update' to get a working copy)
61 checking changesets
61 checking changesets
62 checking manifests
62 checking manifests
63 crosschecking files in changesets and manifests
63 crosschecking files in changesets and manifests
64 checking files
64 checking files
65 1 files, 3 changesets, 3 total revisions
65 1 files, 3 changesets, 3 total revisions
66 2:d62976ca1e50
66 2:d62976ca1e50
67 searching for changes
67 searching for changes
68 4 changesets found
68 4 changesets found
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 4 changesets with 4 changes to 1 files
72 added 4 changesets with 4 changes to 1 files
73 (run 'hg update' to get a working copy)
73 (run 'hg update' to get a working copy)
74 checking changesets
74 checking changesets
75 checking manifests
75 checking manifests
76 crosschecking files in changesets and manifests
76 crosschecking files in changesets and manifests
77 checking files
77 checking files
78 1 files, 4 changesets, 4 total revisions
78 1 files, 4 changesets, 4 total revisions
79 3:ac69c658229d
79 3:ac69c658229d
80 searching for changes
80 searching for changes
81 2 changesets found
81 2 changesets found
82 adding changesets
82 adding changesets
83 adding manifests
83 adding manifests
84 adding file changes
84 adding file changes
85 added 2 changesets with 2 changes to 1 files
85 added 2 changesets with 2 changes to 1 files
86 (run 'hg update' to get a working copy)
86 (run 'hg update' to get a working copy)
87 checking changesets
87 checking changesets
88 checking manifests
88 checking manifests
89 crosschecking files in changesets and manifests
89 crosschecking files in changesets and manifests
90 checking files
90 checking files
91 1 files, 2 changesets, 2 total revisions
91 1 files, 2 changesets, 2 total revisions
92 1:5f4f3ceb285e
92 1:5f4f3ceb285e
93 searching for changes
93 searching for changes
94 3 changesets found
94 3 changesets found
95 adding changesets
95 adding changesets
96 adding manifests
96 adding manifests
97 adding file changes
97 adding file changes
98 added 3 changesets with 3 changes to 1 files
98 added 3 changesets with 3 changes to 1 files
99 (run 'hg update' to get a working copy)
99 (run 'hg update' to get a working copy)
100 checking changesets
100 checking changesets
101 checking manifests
101 checking manifests
102 crosschecking files in changesets and manifests
102 crosschecking files in changesets and manifests
103 checking files
103 checking files
104 1 files, 3 changesets, 3 total revisions
104 1 files, 3 changesets, 3 total revisions
105 2:024e4e7df376
105 2:024e4e7df376
106 searching for changes
106 searching for changes
107 4 changesets found
107 4 changesets found
108 adding changesets
108 adding changesets
109 adding manifests
109 adding manifests
110 adding file changes
110 adding file changes
111 added 4 changesets with 5 changes to 2 files
111 added 4 changesets with 5 changes to 2 files
112 (run 'hg update' to get a working copy)
112 (run 'hg update' to get a working copy)
113 checking changesets
113 checking changesets
114 checking manifests
114 checking manifests
115 crosschecking files in changesets and manifests
115 crosschecking files in changesets and manifests
116 checking files
116 checking files
117 2 files, 4 changesets, 5 total revisions
117 2 files, 4 changesets, 5 total revisions
118 3:1e3f6b843bd6
118 3:1e3f6b843bd6
119 searching for changes
119 searching for changes
120 5 changesets found
120 5 changesets found
121 adding changesets
121 adding changesets
122 adding manifests
122 adding manifests
123 adding file changes
123 adding file changes
124 added 5 changesets with 6 changes to 3 files
124 added 5 changesets with 6 changes to 3 files
125 (run 'hg update' to get a working copy)
125 (run 'hg update' to get a working copy)
126 checking changesets
126 checking changesets
127 checking manifests
127 checking manifests
128 crosschecking files in changesets and manifests
128 crosschecking files in changesets and manifests
129 checking files
129 checking files
130 3 files, 5 changesets, 6 total revisions
130 3 files, 5 changesets, 6 total revisions
131 4:27f57c869697
131 4:27f57c869697
132 searching for changes
132 searching for changes
133 5 changesets found
133 5 changesets found
134 adding changesets
134 adding changesets
135 adding manifests
135 adding manifests
136 adding file changes
136 adding file changes
137 added 5 changesets with 5 changes to 2 files
137 added 5 changesets with 5 changes to 2 files
138 (run 'hg update' to get a working copy)
138 (run 'hg update' to get a working copy)
139 checking changesets
139 checking changesets
140 checking manifests
140 checking manifests
141 crosschecking files in changesets and manifests
141 crosschecking files in changesets and manifests
142 checking files
142 checking files
143 2 files, 5 changesets, 5 total revisions
143 2 files, 5 changesets, 5 total revisions
144 4:088ff9d6e1e1
144 4:088ff9d6e1e1
145 pulling from ../test-7
145 pulling from ../test-7
146 searching for changes
146 searching for changes
147 adding changesets
147 adding changesets
148 adding manifests
148 adding manifests
149 adding file changes
149 adding file changes
150 added 4 changesets with 2 changes to 3 files (+1 heads)
150 added 4 changesets with 2 changes to 3 files (+1 heads)
151 (run 'hg heads' to see heads, 'hg merge' to merge)
151 (run 'hg heads' to see heads, 'hg merge' to merge)
152 checking changesets
152 checking changesets
153 checking manifests
153 checking manifests
154 crosschecking files in changesets and manifests
154 crosschecking files in changesets and manifests
155 checking files
155 checking files
156 4 files, 9 changesets, 7 total revisions
156 4 files, 9 changesets, 7 total revisions
157 rolling back pull to revision 5
157 rolling back to revision 5 (undo pull)
158 % should fail
158 % should fail
159 abort: --base is incompatible with specifying a destination
159 abort: --base is incompatible with specifying a destination
160 abort: repository default-push not found!
160 abort: repository default-push not found!
161 2 changesets found
161 2 changesets found
162 4 changesets found
162 4 changesets found
163 6 changesets found
163 6 changesets found
164 1 changesets found
164 1 changesets found
165 no changes found
165 no changes found
166 1 changesets found
166 1 changesets found
167 4 changesets found
167 4 changesets found
168 updating to branch default
168 updating to branch default
169 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 % 2
170 % 2
171 2:d62976ca1e50
171 2:d62976ca1e50
172 adding changesets
172 adding changesets
173 transaction abort!
173 transaction abort!
174 rollback completed
174 rollback completed
175 abort: 00changelog.i@ac69c658229d: unknown parent!
175 abort: 00changelog.i@ac69c658229d: unknown parent!
176 % 2
176 % 2
177 2:d62976ca1e50
177 2:d62976ca1e50
178 adding changesets
178 adding changesets
179 adding manifests
179 adding manifests
180 adding file changes
180 adding file changes
181 added 6 changesets with 4 changes to 4 files (+1 heads)
181 added 6 changesets with 4 changes to 4 files (+1 heads)
182 (run 'hg heads' to see heads, 'hg merge' to merge)
182 (run 'hg heads' to see heads, 'hg merge' to merge)
183 % 8
183 % 8
184 8:088ff9d6e1e1
184 8:088ff9d6e1e1
185 checking changesets
185 checking changesets
186 checking manifests
186 checking manifests
187 crosschecking files in changesets and manifests
187 crosschecking files in changesets and manifests
188 checking files
188 checking files
189 4 files, 9 changesets, 7 total revisions
189 4 files, 9 changesets, 7 total revisions
190 rolling back unbundle to revision 3
190 rolling back to revision 3 (undo unbundle)
191 % 2
191 % 2
192 2:d62976ca1e50
192 2:d62976ca1e50
193 adding changesets
193 adding changesets
194 adding manifests
194 adding manifests
195 adding file changes
195 adding file changes
196 added 2 changesets with 2 changes to 2 files
196 added 2 changesets with 2 changes to 2 files
197 (run 'hg update' to get a working copy)
197 (run 'hg update' to get a working copy)
198 % 4
198 % 4
199 4:088ff9d6e1e1
199 4:088ff9d6e1e1
200 checking changesets
200 checking changesets
201 checking manifests
201 checking manifests
202 crosschecking files in changesets and manifests
202 crosschecking files in changesets and manifests
203 checking files
203 checking files
204 2 files, 5 changesets, 5 total revisions
204 2 files, 5 changesets, 5 total revisions
205 rolling back unbundle to revision 3
205 rolling back to revision 3 (undo unbundle)
206 adding changesets
206 adding changesets
207 adding manifests
207 adding manifests
208 adding file changes
208 adding file changes
209 added 4 changesets with 3 changes to 3 files (+1 heads)
209 added 4 changesets with 3 changes to 3 files (+1 heads)
210 (run 'hg heads' to see heads, 'hg merge' to merge)
210 (run 'hg heads' to see heads, 'hg merge' to merge)
211 % 6
211 % 6
212 6:27f57c869697
212 6:27f57c869697
213 checking changesets
213 checking changesets
214 checking manifests
214 checking manifests
215 crosschecking files in changesets and manifests
215 crosschecking files in changesets and manifests
216 checking files
216 checking files
217 3 files, 7 changesets, 6 total revisions
217 3 files, 7 changesets, 6 total revisions
218 rolling back unbundle to revision 3
218 rolling back to revision 3 (undo unbundle)
219 adding changesets
219 adding changesets
220 adding manifests
220 adding manifests
221 adding file changes
221 adding file changes
222 added 2 changesets with 2 changes to 2 files
222 added 2 changesets with 2 changes to 2 files
223 (run 'hg update' to get a working copy)
223 (run 'hg update' to get a working copy)
224 % 4
224 % 4
225 4:088ff9d6e1e1
225 4:088ff9d6e1e1
226 checking changesets
226 checking changesets
227 checking manifests
227 checking manifests
228 crosschecking files in changesets and manifests
228 crosschecking files in changesets and manifests
229 checking files
229 checking files
230 2 files, 5 changesets, 5 total revisions
230 2 files, 5 changesets, 5 total revisions
231 warning: detected divergent renames of afile to:
231 warning: detected divergent renames of afile to:
232 anotherfile
232 anotherfile
233 adifferentfile
233 adifferentfile
234 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
234 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
235 (branch merge, don't forget to commit)
235 (branch merge, don't forget to commit)
236 7 changesets found
236 7 changesets found
237 updating to branch default
237 updating to branch default
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 adding changesets
239 adding changesets
240 adding manifests
240 adding manifests
241 adding file changes
241 adding file changes
242 added 7 changesets with 4 changes to 4 files
242 added 7 changesets with 4 changes to 4 files
243 (run 'hg update' to get a working copy)
243 (run 'hg update' to get a working copy)
244 % 9
244 % 9
245 9:e3061ea42e4c
245 9:e3061ea42e4c
246 checking changesets
246 checking changesets
247 checking manifests
247 checking manifests
248 crosschecking files in changesets and manifests
248 crosschecking files in changesets and manifests
249 checking files
249 checking files
250 4 files, 10 changesets, 7 total revisions
250 4 files, 10 changesets, 7 total revisions
@@ -1,365 +1,365 b''
1 ====== Setting up test
1 ====== Setting up test
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 created new head
3 created new head
4 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
4 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
5 checking changesets
5 checking changesets
6 checking manifests
6 checking manifests
7 crosschecking files in changesets and manifests
7 crosschecking files in changesets and manifests
8 checking files
8 checking files
9 4 files, 9 changesets, 7 total revisions
9 4 files, 9 changesets, 7 total revisions
10 ====== Bundle --all
10 ====== Bundle --all
11 9 changesets found
11 9 changesets found
12 ====== Bundle test to full.hg
12 ====== Bundle test to full.hg
13 searching for changes
13 searching for changes
14 9 changesets found
14 9 changesets found
15 ====== Unbundle full.hg in test
15 ====== Unbundle full.hg in test
16 adding changesets
16 adding changesets
17 adding manifests
17 adding manifests
18 adding file changes
18 adding file changes
19 added 0 changesets with 0 changes to 4 files
19 added 0 changesets with 0 changes to 4 files
20 (run 'hg update' to get a working copy)
20 (run 'hg update' to get a working copy)
21 ====== Verify empty
21 ====== Verify empty
22 checking changesets
22 checking changesets
23 checking manifests
23 checking manifests
24 crosschecking files in changesets and manifests
24 crosschecking files in changesets and manifests
25 checking files
25 checking files
26 0 files, 0 changesets, 0 total revisions
26 0 files, 0 changesets, 0 total revisions
27 ====== Pull full.hg into test (using --cwd)
27 ====== Pull full.hg into test (using --cwd)
28 pulling from ../full.hg
28 pulling from ../full.hg
29 searching for changes
29 searching for changes
30 no changes found
30 no changes found
31 ====== Pull full.hg into empty (using --cwd)
31 ====== Pull full.hg into empty (using --cwd)
32 pulling from ../full.hg
32 pulling from ../full.hg
33 requesting all changes
33 requesting all changes
34 adding changesets
34 adding changesets
35 adding manifests
35 adding manifests
36 adding file changes
36 adding file changes
37 added 9 changesets with 7 changes to 4 files (+1 heads)
37 added 9 changesets with 7 changes to 4 files (+1 heads)
38 (run 'hg heads' to see heads, 'hg merge' to merge)
38 (run 'hg heads' to see heads, 'hg merge' to merge)
39 ====== Rollback empty
39 ====== Rollback empty
40 rolling back pull to revision 0
40 rolling back to revision 0 (undo pull)
41 ====== Pull full.hg into empty again (using --cwd)
41 ====== Pull full.hg into empty again (using --cwd)
42 pulling from ../full.hg
42 pulling from ../full.hg
43 requesting all changes
43 requesting all changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 9 changesets with 7 changes to 4 files (+1 heads)
47 added 9 changesets with 7 changes to 4 files (+1 heads)
48 (run 'hg heads' to see heads, 'hg merge' to merge)
48 (run 'hg heads' to see heads, 'hg merge' to merge)
49 ====== Pull full.hg into test (using -R)
49 ====== Pull full.hg into test (using -R)
50 pulling from full.hg
50 pulling from full.hg
51 searching for changes
51 searching for changes
52 no changes found
52 no changes found
53 ====== Pull full.hg into empty (using -R)
53 ====== Pull full.hg into empty (using -R)
54 pulling from full.hg
54 pulling from full.hg
55 searching for changes
55 searching for changes
56 no changes found
56 no changes found
57 ====== Rollback empty
57 ====== Rollback empty
58 rolling back pull to revision 0
58 rolling back to revision 0 (undo pull)
59 ====== Pull full.hg into empty again (using -R)
59 ====== Pull full.hg into empty again (using -R)
60 pulling from full.hg
60 pulling from full.hg
61 requesting all changes
61 requesting all changes
62 adding changesets
62 adding changesets
63 adding manifests
63 adding manifests
64 adding file changes
64 adding file changes
65 added 9 changesets with 7 changes to 4 files (+1 heads)
65 added 9 changesets with 7 changes to 4 files (+1 heads)
66 (run 'hg heads' to see heads, 'hg merge' to merge)
66 (run 'hg heads' to see heads, 'hg merge' to merge)
67 ====== Log -R full.hg in fresh empty
67 ====== Log -R full.hg in fresh empty
68 changeset: 8:088ff9d6e1e1
68 changeset: 8:088ff9d6e1e1
69 tag: tip
69 tag: tip
70 parent: 3:ac69c658229d
70 parent: 3:ac69c658229d
71 user: test
71 user: test
72 date: Mon Jan 12 13:46:40 1970 +0000
72 date: Mon Jan 12 13:46:40 1970 +0000
73 summary: 0.3m
73 summary: 0.3m
74
74
75 changeset: 7:27f57c869697
75 changeset: 7:27f57c869697
76 user: test
76 user: test
77 date: Mon Jan 12 13:46:40 1970 +0000
77 date: Mon Jan 12 13:46:40 1970 +0000
78 summary: 1.3m
78 summary: 1.3m
79
79
80 changeset: 6:1e3f6b843bd6
80 changeset: 6:1e3f6b843bd6
81 user: test
81 user: test
82 date: Mon Jan 12 13:46:40 1970 +0000
82 date: Mon Jan 12 13:46:40 1970 +0000
83 summary: 1.3
83 summary: 1.3
84
84
85 changeset: 5:024e4e7df376
85 changeset: 5:024e4e7df376
86 user: test
86 user: test
87 date: Mon Jan 12 13:46:40 1970 +0000
87 date: Mon Jan 12 13:46:40 1970 +0000
88 summary: 1.2
88 summary: 1.2
89
89
90 changeset: 4:5f4f3ceb285e
90 changeset: 4:5f4f3ceb285e
91 parent: 0:5649c9d34dd8
91 parent: 0:5649c9d34dd8
92 user: test
92 user: test
93 date: Mon Jan 12 13:46:40 1970 +0000
93 date: Mon Jan 12 13:46:40 1970 +0000
94 summary: 1.1
94 summary: 1.1
95
95
96 changeset: 3:ac69c658229d
96 changeset: 3:ac69c658229d
97 user: test
97 user: test
98 date: Mon Jan 12 13:46:40 1970 +0000
98 date: Mon Jan 12 13:46:40 1970 +0000
99 summary: 0.3
99 summary: 0.3
100
100
101 changeset: 2:d62976ca1e50
101 changeset: 2:d62976ca1e50
102 user: test
102 user: test
103 date: Mon Jan 12 13:46:40 1970 +0000
103 date: Mon Jan 12 13:46:40 1970 +0000
104 summary: 0.2
104 summary: 0.2
105
105
106 changeset: 1:10b2180f755b
106 changeset: 1:10b2180f755b
107 user: test
107 user: test
108 date: Mon Jan 12 13:46:40 1970 +0000
108 date: Mon Jan 12 13:46:40 1970 +0000
109 summary: 0.1
109 summary: 0.1
110
110
111 changeset: 0:5649c9d34dd8
111 changeset: 0:5649c9d34dd8
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: 0.0
114 summary: 0.0
115
115
116 ====== Pull ../full.hg into empty (with hook)
116 ====== Pull ../full.hg into empty (with hook)
117 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:../full.hg
117 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:../full.hg
118 pulling from bundle://../full.hg
118 pulling from bundle://../full.hg
119 requesting all changes
119 requesting all changes
120 adding changesets
120 adding changesets
121 adding manifests
121 adding manifests
122 adding file changes
122 adding file changes
123 added 9 changesets with 7 changes to 4 files (+1 heads)
123 added 9 changesets with 7 changes to 4 files (+1 heads)
124 (run 'hg heads' to see heads, 'hg merge' to merge)
124 (run 'hg heads' to see heads, 'hg merge' to merge)
125 ====== Rollback empty
125 ====== Rollback empty
126 rolling back pull to revision 0
126 rolling back to revision 0 (undo pull)
127 ====== Log -R bundle:empty+full.hg
127 ====== Log -R bundle:empty+full.hg
128 8 7 6 5 4 3 2 1 0
128 8 7 6 5 4 3 2 1 0
129 ====== Pull full.hg into empty again (using -R; with hook)
129 ====== Pull full.hg into empty again (using -R; with hook)
130 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:empty+full.hg
130 changegroup hook: HG_NODE=5649c9d34dd87d0ecb5fd39672128376e83b22e1 HG_SOURCE=pull HG_URL=bundle:empty+full.hg
131 pulling from full.hg
131 pulling from full.hg
132 requesting all changes
132 requesting all changes
133 adding changesets
133 adding changesets
134 adding manifests
134 adding manifests
135 adding file changes
135 adding file changes
136 added 9 changesets with 7 changes to 4 files (+1 heads)
136 added 9 changesets with 7 changes to 4 files (+1 heads)
137 (run 'hg heads' to see heads, 'hg merge' to merge)
137 (run 'hg heads' to see heads, 'hg merge' to merge)
138 ====== Create partial clones
138 ====== Create partial clones
139 requesting all changes
139 requesting all changes
140 adding changesets
140 adding changesets
141 adding manifests
141 adding manifests
142 adding file changes
142 adding file changes
143 added 4 changesets with 4 changes to 1 files
143 added 4 changesets with 4 changes to 1 files
144 updating to branch default
144 updating to branch default
145 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
145 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 updating to branch default
146 updating to branch default
147 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
148 ====== Log -R full.hg in partial
148 ====== Log -R full.hg in partial
149 changeset: 8:088ff9d6e1e1
149 changeset: 8:088ff9d6e1e1
150 tag: tip
150 tag: tip
151 parent: 3:ac69c658229d
151 parent: 3:ac69c658229d
152 user: test
152 user: test
153 date: Mon Jan 12 13:46:40 1970 +0000
153 date: Mon Jan 12 13:46:40 1970 +0000
154 summary: 0.3m
154 summary: 0.3m
155
155
156 changeset: 7:27f57c869697
156 changeset: 7:27f57c869697
157 user: test
157 user: test
158 date: Mon Jan 12 13:46:40 1970 +0000
158 date: Mon Jan 12 13:46:40 1970 +0000
159 summary: 1.3m
159 summary: 1.3m
160
160
161 changeset: 6:1e3f6b843bd6
161 changeset: 6:1e3f6b843bd6
162 user: test
162 user: test
163 date: Mon Jan 12 13:46:40 1970 +0000
163 date: Mon Jan 12 13:46:40 1970 +0000
164 summary: 1.3
164 summary: 1.3
165
165
166 changeset: 5:024e4e7df376
166 changeset: 5:024e4e7df376
167 user: test
167 user: test
168 date: Mon Jan 12 13:46:40 1970 +0000
168 date: Mon Jan 12 13:46:40 1970 +0000
169 summary: 1.2
169 summary: 1.2
170
170
171 changeset: 4:5f4f3ceb285e
171 changeset: 4:5f4f3ceb285e
172 parent: 0:5649c9d34dd8
172 parent: 0:5649c9d34dd8
173 user: test
173 user: test
174 date: Mon Jan 12 13:46:40 1970 +0000
174 date: Mon Jan 12 13:46:40 1970 +0000
175 summary: 1.1
175 summary: 1.1
176
176
177 changeset: 3:ac69c658229d
177 changeset: 3:ac69c658229d
178 user: test
178 user: test
179 date: Mon Jan 12 13:46:40 1970 +0000
179 date: Mon Jan 12 13:46:40 1970 +0000
180 summary: 0.3
180 summary: 0.3
181
181
182 changeset: 2:d62976ca1e50
182 changeset: 2:d62976ca1e50
183 user: test
183 user: test
184 date: Mon Jan 12 13:46:40 1970 +0000
184 date: Mon Jan 12 13:46:40 1970 +0000
185 summary: 0.2
185 summary: 0.2
186
186
187 changeset: 1:10b2180f755b
187 changeset: 1:10b2180f755b
188 user: test
188 user: test
189 date: Mon Jan 12 13:46:40 1970 +0000
189 date: Mon Jan 12 13:46:40 1970 +0000
190 summary: 0.1
190 summary: 0.1
191
191
192 changeset: 0:5649c9d34dd8
192 changeset: 0:5649c9d34dd8
193 user: test
193 user: test
194 date: Mon Jan 12 13:46:40 1970 +0000
194 date: Mon Jan 12 13:46:40 1970 +0000
195 summary: 0.0
195 summary: 0.0
196
196
197 ====== Incoming full.hg in partial
197 ====== Incoming full.hg in partial
198 comparing with bundle://../full.hg
198 comparing with bundle://../full.hg
199 searching for changes
199 searching for changes
200 changeset: 4:5f4f3ceb285e
200 changeset: 4:5f4f3ceb285e
201 parent: 0:5649c9d34dd8
201 parent: 0:5649c9d34dd8
202 user: test
202 user: test
203 date: Mon Jan 12 13:46:40 1970 +0000
203 date: Mon Jan 12 13:46:40 1970 +0000
204 summary: 1.1
204 summary: 1.1
205
205
206 changeset: 5:024e4e7df376
206 changeset: 5:024e4e7df376
207 user: test
207 user: test
208 date: Mon Jan 12 13:46:40 1970 +0000
208 date: Mon Jan 12 13:46:40 1970 +0000
209 summary: 1.2
209 summary: 1.2
210
210
211 changeset: 6:1e3f6b843bd6
211 changeset: 6:1e3f6b843bd6
212 user: test
212 user: test
213 date: Mon Jan 12 13:46:40 1970 +0000
213 date: Mon Jan 12 13:46:40 1970 +0000
214 summary: 1.3
214 summary: 1.3
215
215
216 changeset: 7:27f57c869697
216 changeset: 7:27f57c869697
217 user: test
217 user: test
218 date: Mon Jan 12 13:46:40 1970 +0000
218 date: Mon Jan 12 13:46:40 1970 +0000
219 summary: 1.3m
219 summary: 1.3m
220
220
221 changeset: 8:088ff9d6e1e1
221 changeset: 8:088ff9d6e1e1
222 tag: tip
222 tag: tip
223 parent: 3:ac69c658229d
223 parent: 3:ac69c658229d
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: 0.3m
226 summary: 0.3m
227
227
228 ====== Outgoing -R full.hg vs partial2 in partial
228 ====== Outgoing -R full.hg vs partial2 in partial
229 comparing with ../partial2
229 comparing with ../partial2
230 searching for changes
230 searching for changes
231 changeset: 4:5f4f3ceb285e
231 changeset: 4:5f4f3ceb285e
232 parent: 0:5649c9d34dd8
232 parent: 0:5649c9d34dd8
233 user: test
233 user: test
234 date: Mon Jan 12 13:46:40 1970 +0000
234 date: Mon Jan 12 13:46:40 1970 +0000
235 summary: 1.1
235 summary: 1.1
236
236
237 changeset: 5:024e4e7df376
237 changeset: 5:024e4e7df376
238 user: test
238 user: test
239 date: Mon Jan 12 13:46:40 1970 +0000
239 date: Mon Jan 12 13:46:40 1970 +0000
240 summary: 1.2
240 summary: 1.2
241
241
242 changeset: 6:1e3f6b843bd6
242 changeset: 6:1e3f6b843bd6
243 user: test
243 user: test
244 date: Mon Jan 12 13:46:40 1970 +0000
244 date: Mon Jan 12 13:46:40 1970 +0000
245 summary: 1.3
245 summary: 1.3
246
246
247 changeset: 7:27f57c869697
247 changeset: 7:27f57c869697
248 user: test
248 user: test
249 date: Mon Jan 12 13:46:40 1970 +0000
249 date: Mon Jan 12 13:46:40 1970 +0000
250 summary: 1.3m
250 summary: 1.3m
251
251
252 changeset: 8:088ff9d6e1e1
252 changeset: 8:088ff9d6e1e1
253 tag: tip
253 tag: tip
254 parent: 3:ac69c658229d
254 parent: 3:ac69c658229d
255 user: test
255 user: test
256 date: Mon Jan 12 13:46:40 1970 +0000
256 date: Mon Jan 12 13:46:40 1970 +0000
257 summary: 0.3m
257 summary: 0.3m
258
258
259 ====== Outgoing -R does-not-exist.hg vs partial2 in partial
259 ====== Outgoing -R does-not-exist.hg vs partial2 in partial
260 abort: No such file or directory: ../does-not-exist.hg
260 abort: No such file or directory: ../does-not-exist.hg
261 ====== Direct clone from bundle (all-history)
261 ====== Direct clone from bundle (all-history)
262 requesting all changes
262 requesting all changes
263 adding changesets
263 adding changesets
264 adding manifests
264 adding manifests
265 adding file changes
265 adding file changes
266 added 9 changesets with 7 changes to 4 files (+1 heads)
266 added 9 changesets with 7 changes to 4 files (+1 heads)
267 updating to branch default
267 updating to branch default
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 changeset: 8:088ff9d6e1e1
269 changeset: 8:088ff9d6e1e1
270 tag: tip
270 tag: tip
271 parent: 3:ac69c658229d
271 parent: 3:ac69c658229d
272 user: test
272 user: test
273 date: Mon Jan 12 13:46:40 1970 +0000
273 date: Mon Jan 12 13:46:40 1970 +0000
274 summary: 0.3m
274 summary: 0.3m
275
275
276 changeset: 7:27f57c869697
276 changeset: 7:27f57c869697
277 user: test
277 user: test
278 date: Mon Jan 12 13:46:40 1970 +0000
278 date: Mon Jan 12 13:46:40 1970 +0000
279 summary: 1.3m
279 summary: 1.3m
280
280
281 ====== Unbundle incremental bundles into fresh empty in one go
281 ====== Unbundle incremental bundles into fresh empty in one go
282 1 changesets found
282 1 changesets found
283 1 changesets found
283 1 changesets found
284 adding changesets
284 adding changesets
285 adding manifests
285 adding manifests
286 adding file changes
286 adding file changes
287 added 1 changesets with 1 changes to 1 files
287 added 1 changesets with 1 changes to 1 files
288 adding changesets
288 adding changesets
289 adding manifests
289 adding manifests
290 adding file changes
290 adding file changes
291 added 1 changesets with 1 changes to 1 files
291 added 1 changesets with 1 changes to 1 files
292 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 ====== test for 540d1059c802
293 ====== test for 540d1059c802
294 updating to branch default
294 updating to branch default
295 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
295 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 searching for changes
296 searching for changes
297 1 changesets found
297 1 changesets found
298 comparing with ../bundle.hg
298 comparing with ../bundle.hg
299 searching for changes
299 searching for changes
300 changeset: 2:ed1b79f46b9a
300 changeset: 2:ed1b79f46b9a
301 tag: tip
301 tag: tip
302 parent: 0:bbd179dfa0a7
302 parent: 0:bbd179dfa0a7
303 user: test
303 user: test
304 date: Thu Jan 01 00:00:00 1970 +0000
304 date: Thu Jan 01 00:00:00 1970 +0000
305 summary: change foo
305 summary: change foo
306
306
307 ===== test that verify bundle does not traceback
307 ===== test that verify bundle does not traceback
308 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
308 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
309 abort: cannot verify bundle or remote repos
309 abort: cannot verify bundle or remote repos
310 checking changesets
310 checking changesets
311 checking manifests
311 checking manifests
312 crosschecking files in changesets and manifests
312 crosschecking files in changesets and manifests
313 checking files
313 checking files
314 2 files, 2 changesets, 2 total revisions
314 2 files, 2 changesets, 2 total revisions
315 ====== diff against bundle
315 ====== diff against bundle
316 diff -r 088ff9d6e1e1 anotherfile
316 diff -r 088ff9d6e1e1 anotherfile
317 --- a/anotherfile Mon Jan 12 13:46:40 1970 +0000
317 --- a/anotherfile Mon Jan 12 13:46:40 1970 +0000
318 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
318 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
319 @@ -1,4 +0,0 @@
319 @@ -1,4 +0,0 @@
320 -0
320 -0
321 -1
321 -1
322 -2
322 -2
323 -3
323 -3
324 ====== bundle single branch
324 ====== bundle single branch
325 adding a
325 adding a
326 adding b
326 adding b
327 adding b1
327 adding b1
328 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
328 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
329 adding c
329 adding c
330 created new head
330 created new head
331 adding c1
331 adding c1
332 == bundling via incoming
332 == bundling via incoming
333 comparing with .
333 comparing with .
334 searching for changes
334 searching for changes
335 d2ae7f538514cd87c17547b0de4cea71fe1af9fb
335 d2ae7f538514cd87c17547b0de4cea71fe1af9fb
336 5ece8e77363e2b5269e27c66828b72da29e4341a
336 5ece8e77363e2b5269e27c66828b72da29e4341a
337 == bundling
337 == bundling
338 searching for changes
338 searching for changes
339 common changesets up to c0025332f9ed
339 common changesets up to c0025332f9ed
340 2 changesets found
340 2 changesets found
341 list of changesets:
341 list of changesets:
342 d2ae7f538514cd87c17547b0de4cea71fe1af9fb
342 d2ae7f538514cd87c17547b0de4cea71fe1af9fb
343 5ece8e77363e2b5269e27c66828b72da29e4341a
343 5ece8e77363e2b5269e27c66828b72da29e4341a
344 bundling changes: 0 chunks
344 bundling changes: 0 chunks
345 bundling changes: 1 chunks
345 bundling changes: 1 chunks
346 bundling changes: 2 chunks
346 bundling changes: 2 chunks
347 bundling changes: 3 chunks
347 bundling changes: 3 chunks
348 bundling changes: 4 chunks
348 bundling changes: 4 chunks
349 bundling changes: 5 chunks
349 bundling changes: 5 chunks
350 bundling changes: 6 chunks
350 bundling changes: 6 chunks
351 bundling manifests: 0 chunks
351 bundling manifests: 0 chunks
352 bundling manifests: 1 chunks
352 bundling manifests: 1 chunks
353 bundling manifests: 2 chunks
353 bundling manifests: 2 chunks
354 bundling manifests: 3 chunks
354 bundling manifests: 3 chunks
355 bundling manifests: 4 chunks
355 bundling manifests: 4 chunks
356 bundling manifests: 5 chunks
356 bundling manifests: 5 chunks
357 bundling manifests: 6 chunks
357 bundling manifests: 6 chunks
358 bundling files: b 0 chunks
358 bundling files: b 0 chunks
359 bundling files: b 1 chunks
359 bundling files: b 1 chunks
360 bundling files: b 2 chunks
360 bundling files: b 2 chunks
361 bundling files: b 3 chunks
361 bundling files: b 3 chunks
362 bundling files: b1 4 chunks
362 bundling files: b1 4 chunks
363 bundling files: b1 5 chunks
363 bundling files: b1 5 chunks
364 bundling files: b1 6 chunks
364 bundling files: b1 6 chunks
365 bundling files: b1 7 chunks
365 bundling files: b1 7 chunks
@@ -1,288 +1,288 b''
1 % create cvs repository
1 % create cvs repository
2 % create source directory
2 % create source directory
3 % import source directory
3 % import source directory
4 N src/a
4 N src/a
5 N src/b/c
5 N src/b/c
6
6
7 No conflicts created by this import
7 No conflicts created by this import
8
8
9 % checkout source directory
9 % checkout source directory
10 U src/a
10 U src/a
11 U src/b/c
11 U src/b/c
12 % commit a new revision changing b/c
12 % commit a new revision changing b/c
13 checking in src/b/c,v
13 checking in src/b/c,v
14 % convert fresh repo
14 % convert fresh repo
15 initializing destination src-hg repository
15 initializing destination src-hg repository
16 connecting to cvsrepo
16 connecting to cvsrepo
17 scanning source...
17 scanning source...
18 collecting CVS rlog
18 collecting CVS rlog
19 5 log entries
19 5 log entries
20 cvslog hook: 5 entries
20 cvslog hook: 5 entries
21 creating changesets
21 creating changesets
22 3 changeset entries
22 3 changeset entries
23 cvschangesets hook: 3 changesets
23 cvschangesets hook: 3 changesets
24 sorting...
24 sorting...
25 converting...
25 converting...
26 2 Initial revision
26 2 Initial revision
27 1 import
27 1 import
28 0 ci0
28 0 ci0
29 updating tags
29 updating tags
30 a
30 a
31 c
31 c
32 c
32 c
33 % convert fresh repo with --filemap
33 % convert fresh repo with --filemap
34 initializing destination src-filemap repository
34 initializing destination src-filemap repository
35 connecting to cvsrepo
35 connecting to cvsrepo
36 scanning source...
36 scanning source...
37 collecting CVS rlog
37 collecting CVS rlog
38 5 log entries
38 5 log entries
39 cvslog hook: 5 entries
39 cvslog hook: 5 entries
40 creating changesets
40 creating changesets
41 3 changeset entries
41 3 changeset entries
42 cvschangesets hook: 3 changesets
42 cvschangesets hook: 3 changesets
43 sorting...
43 sorting...
44 converting...
44 converting...
45 2 Initial revision
45 2 Initial revision
46 1 import
46 1 import
47 filtering out empty revision
47 filtering out empty revision
48 rolling back commit to revision 1
48 rolling back to revision 1 (undo commit)
49 0 ci0
49 0 ci0
50 updating tags
50 updating tags
51 c
51 c
52 c
52 c
53 2 update tags files: .hgtags
53 2 update tags files: .hgtags
54 1 ci0 files: b/c
54 1 ci0 files: b/c
55 0 Initial revision files: b/c
55 0 Initial revision files: b/c
56 % convert full repository (issue1649)
56 % convert full repository (issue1649)
57 U srcfull/src/a
57 U srcfull/src/a
58 U srcfull/src/b/c
58 U srcfull/src/b/c
59 CVS
59 CVS
60 CVSROOT
60 CVSROOT
61 src
61 src
62 initializing destination srcfull-hg repository
62 initializing destination srcfull-hg repository
63 connecting to cvsrepo
63 connecting to cvsrepo
64 scanning source...
64 scanning source...
65 collecting CVS rlog
65 collecting CVS rlog
66 creating changesets
66 creating changesets
67 4 changeset entries
67 4 changeset entries
68 sorting...
68 sorting...
69 converting...
69 converting...
70 updating tags
70 updating tags
71 a
71 a
72 c
72 c
73 c
73 c
74 % commit new file revisions
74 % commit new file revisions
75 checking in src/a,v
75 checking in src/a,v
76 checking in src/b/c,v
76 checking in src/b/c,v
77 % convert again
77 % convert again
78 connecting to cvsrepo
78 connecting to cvsrepo
79 scanning source...
79 scanning source...
80 collecting CVS rlog
80 collecting CVS rlog
81 7 log entries
81 7 log entries
82 cvslog hook: 7 entries
82 cvslog hook: 7 entries
83 creating changesets
83 creating changesets
84 4 changeset entries
84 4 changeset entries
85 cvschangesets hook: 4 changesets
85 cvschangesets hook: 4 changesets
86 sorting...
86 sorting...
87 converting...
87 converting...
88 0 ci1
88 0 ci1
89 a
89 a
90 a
90 a
91 c
91 c
92 c
92 c
93 c
93 c
94 % convert again with --filemap
94 % convert again with --filemap
95 connecting to cvsrepo
95 connecting to cvsrepo
96 scanning source...
96 scanning source...
97 collecting CVS rlog
97 collecting CVS rlog
98 7 log entries
98 7 log entries
99 cvslog hook: 7 entries
99 cvslog hook: 7 entries
100 creating changesets
100 creating changesets
101 4 changeset entries
101 4 changeset entries
102 cvschangesets hook: 4 changesets
102 cvschangesets hook: 4 changesets
103 sorting...
103 sorting...
104 converting...
104 converting...
105 0 ci1
105 0 ci1
106 c
106 c
107 c
107 c
108 c
108 c
109 3 ci1 files: b/c
109 3 ci1 files: b/c
110 2 update tags files: .hgtags
110 2 update tags files: .hgtags
111 1 ci0 files: b/c
111 1 ci0 files: b/c
112 0 Initial revision files: b/c
112 0 Initial revision files: b/c
113 % commit branch
113 % commit branch
114 U b/c
114 U b/c
115 T a
115 T a
116 T b/c
116 T b/c
117 checking in src/b/c,v
117 checking in src/b/c,v
118 % convert again
118 % convert again
119 connecting to cvsrepo
119 connecting to cvsrepo
120 scanning source...
120 scanning source...
121 collecting CVS rlog
121 collecting CVS rlog
122 8 log entries
122 8 log entries
123 cvslog hook: 8 entries
123 cvslog hook: 8 entries
124 creating changesets
124 creating changesets
125 5 changeset entries
125 5 changeset entries
126 cvschangesets hook: 5 changesets
126 cvschangesets hook: 5 changesets
127 sorting...
127 sorting...
128 converting...
128 converting...
129 0 ci2
129 0 ci2
130 c
130 c
131 d
131 d
132 % convert again with --filemap
132 % convert again with --filemap
133 connecting to cvsrepo
133 connecting to cvsrepo
134 scanning source...
134 scanning source...
135 collecting CVS rlog
135 collecting CVS rlog
136 8 log entries
136 8 log entries
137 cvslog hook: 8 entries
137 cvslog hook: 8 entries
138 creating changesets
138 creating changesets
139 5 changeset entries
139 5 changeset entries
140 cvschangesets hook: 5 changesets
140 cvschangesets hook: 5 changesets
141 sorting...
141 sorting...
142 converting...
142 converting...
143 0 ci2
143 0 ci2
144 c
144 c
145 d
145 d
146 4 ci2 files: b/c
146 4 ci2 files: b/c
147 3 ci1 files: b/c
147 3 ci1 files: b/c
148 2 update tags files: .hgtags
148 2 update tags files: .hgtags
149 1 ci0 files: b/c
149 1 ci0 files: b/c
150 0 Initial revision files: b/c
150 0 Initial revision files: b/c
151 % commit a new revision with funny log message
151 % commit a new revision with funny log message
152 checking in src/a,v
152 checking in src/a,v
153 % convert again
153 % convert again
154 connecting to cvsrepo
154 connecting to cvsrepo
155 scanning source...
155 scanning source...
156 collecting CVS rlog
156 collecting CVS rlog
157 9 log entries
157 9 log entries
158 cvslog hook: 9 entries
158 cvslog hook: 9 entries
159 creating changesets
159 creating changesets
160 6 changeset entries
160 6 changeset entries
161 cvschangesets hook: 6 changesets
161 cvschangesets hook: 6 changesets
162 sorting...
162 sorting...
163 converting...
163 converting...
164 0 funny
164 0 funny
165 o 6 (branch) funny
165 o 6 (branch) funny
166 | ----------------------------
166 | ----------------------------
167 | log message files: a
167 | log message files: a
168 o 5 (branch) ci2 files: b/c
168 o 5 (branch) ci2 files: b/c
169
169
170 o 4 () ci1 files: a b/c
170 o 4 () ci1 files: a b/c
171 |
171 |
172 o 3 () update tags files: .hgtags
172 o 3 () update tags files: .hgtags
173 |
173 |
174 o 2 () ci0 files: b/c
174 o 2 () ci0 files: b/c
175 |
175 |
176 | o 1 (INITIAL) import files:
176 | o 1 (INITIAL) import files:
177 |/
177 |/
178 o 0 () Initial revision files: a b/c
178 o 0 () Initial revision files: a b/c
179
179
180 % testing debugcvsps
180 % testing debugcvsps
181 collecting CVS rlog
181 collecting CVS rlog
182 9 log entries
182 9 log entries
183 cvslog hook: 9 entries
183 cvslog hook: 9 entries
184 creating changesets
184 creating changesets
185 8 changeset entries
185 8 changeset entries
186 cvschangesets hook: 8 changesets
186 cvschangesets hook: 8 changesets
187 ---------------------
187 ---------------------
188 PatchSet 1
188 PatchSet 1
189 Date:
189 Date:
190 Author:
190 Author:
191 Branch: HEAD
191 Branch: HEAD
192 Tag: (none)
192 Tag: (none)
193 Branchpoints: INITIAL
193 Branchpoints: INITIAL
194 Log:
194 Log:
195 Initial revision
195 Initial revision
196
196
197 Members:
197 Members:
198 a:INITIAL->1.1
198 a:INITIAL->1.1
199
199
200 ---------------------
200 ---------------------
201 PatchSet 2
201 PatchSet 2
202 Date:
202 Date:
203 Author:
203 Author:
204 Branch: HEAD
204 Branch: HEAD
205 Tag: (none)
205 Tag: (none)
206 Branchpoints: INITIAL, branch
206 Branchpoints: INITIAL, branch
207 Log:
207 Log:
208 Initial revision
208 Initial revision
209
209
210 Members:
210 Members:
211 b/c:INITIAL->1.1
211 b/c:INITIAL->1.1
212
212
213 ---------------------
213 ---------------------
214 PatchSet 3
214 PatchSet 3
215 Date:
215 Date:
216 Author:
216 Author:
217 Branch: INITIAL
217 Branch: INITIAL
218 Tag: start
218 Tag: start
219 Log:
219 Log:
220 import
220 import
221
221
222 Members:
222 Members:
223 a:1.1->1.1.1.1
223 a:1.1->1.1.1.1
224 b/c:1.1->1.1.1.1
224 b/c:1.1->1.1.1.1
225
225
226 ---------------------
226 ---------------------
227 PatchSet 4
227 PatchSet 4
228 Date:
228 Date:
229 Author:
229 Author:
230 Branch: HEAD
230 Branch: HEAD
231 Tag: (none)
231 Tag: (none)
232 Log:
232 Log:
233 ci0
233 ci0
234
234
235 Members:
235 Members:
236 b/c:1.1->1.2
236 b/c:1.1->1.2
237
237
238 ---------------------
238 ---------------------
239 PatchSet 5
239 PatchSet 5
240 Date:
240 Date:
241 Author:
241 Author:
242 Branch: HEAD
242 Branch: HEAD
243 Tag: (none)
243 Tag: (none)
244 Branchpoints: branch
244 Branchpoints: branch
245 Log:
245 Log:
246 ci1
246 ci1
247
247
248 Members:
248 Members:
249 a:1.1->1.2
249 a:1.1->1.2
250
250
251 ---------------------
251 ---------------------
252 PatchSet 6
252 PatchSet 6
253 Date:
253 Date:
254 Author:
254 Author:
255 Branch: HEAD
255 Branch: HEAD
256 Tag: (none)
256 Tag: (none)
257 Log:
257 Log:
258 ci1
258 ci1
259
259
260 Members:
260 Members:
261 b/c:1.2->1.3
261 b/c:1.2->1.3
262
262
263 ---------------------
263 ---------------------
264 PatchSet 7
264 PatchSet 7
265 Date:
265 Date:
266 Author:
266 Author:
267 Branch: branch
267 Branch: branch
268 Tag: (none)
268 Tag: (none)
269 Log:
269 Log:
270 ci2
270 ci2
271
271
272 Members:
272 Members:
273 b/c:1.1->1.1.2.1
273 b/c:1.1->1.1.2.1
274
274
275 ---------------------
275 ---------------------
276 PatchSet 8
276 PatchSet 8
277 Date:
277 Date:
278 Author:
278 Author:
279 Branch: branch
279 Branch: branch
280 Tag: (none)
280 Tag: (none)
281 Log:
281 Log:
282 funny
282 funny
283 ----------------------------
283 ----------------------------
284 log message
284 log message
285
285
286 Members:
286 Members:
287 a:1.2->1.2.2.1
287 a:1.2->1.2.2.1
288
288
@@ -1,63 +1,63 b''
1 adding a
1 adding a
2 % default context
2 % default context
3 diff -r cf9f4ba66af2 a
3 diff -r cf9f4ba66af2 a
4 --- a/a
4 --- a/a
5 +++ b/a
5 +++ b/a
6 @@ -2,7 +2,7 @@
6 @@ -2,7 +2,7 @@
7 c
7 c
8 a
8 a
9 a
9 a
10 -b
10 -b
11 +dd
11 +dd
12 a
12 a
13 a
13 a
14 c
14 c
15 % --unified=2
15 % --unified=2
16 diff -r cf9f4ba66af2 a
16 diff -r cf9f4ba66af2 a
17 --- a/a
17 --- a/a
18 +++ b/a
18 +++ b/a
19 @@ -3,5 +3,5 @@
19 @@ -3,5 +3,5 @@
20 a
20 a
21 a
21 a
22 -b
22 -b
23 +dd
23 +dd
24 a
24 a
25 a
25 a
26 % diffstat
26 % diffstat
27 a | 2 +-
27 a | 2 +-
28 1 files changed, 1 insertions(+), 1 deletions(-)
28 1 files changed, 1 insertions(+), 1 deletions(-)
29 % record
29 % record
30 diff --git a/a b/a
30 diff --git a/a b/a
31 old mode 100644
31 old mode 100644
32 new mode 100755
32 new mode 100755
33 1 hunks, 2 lines changed
33 1 hunks, 2 lines changed
34 examine changes to 'a'? [Ynsfdaq?]
34 examine changes to 'a'? [Ynsfdaq?]
35 @@ -2,7 +2,7 @@
35 @@ -2,7 +2,7 @@
36 c
36 c
37 a
37 a
38 a
38 a
39 -b
39 -b
40 +dd
40 +dd
41 a
41 a
42 a
42 a
43 c
43 c
44 record this change to 'a'? [Ynsfdaq?]
44 record this change to 'a'? [Ynsfdaq?]
45
45
46 rolling back commit to revision 1
46 rolling back to revision 1 (undo commit)
47 % qrecord
47 % qrecord
48 diff --git a/a b/a
48 diff --git a/a b/a
49 old mode 100644
49 old mode 100644
50 new mode 100755
50 new mode 100755
51 1 hunks, 2 lines changed
51 1 hunks, 2 lines changed
52 examine changes to 'a'? [Ynsfdaq?]
52 examine changes to 'a'? [Ynsfdaq?]
53 @@ -2,7 +2,7 @@
53 @@ -2,7 +2,7 @@
54 c
54 c
55 a
55 a
56 a
56 a
57 -b
57 -b
58 +dd
58 +dd
59 a
59 a
60 a
60 a
61 c
61 c
62 record this change to 'a'? [Ynsfdaq?]
62 record this change to 'a'? [Ynsfdaq?]
63
63
@@ -1,177 +1,177 b''
1 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
1 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
2 pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$HGTMP/test-hook/a
2 pretxncommit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$HGTMP/test-hook/a
3 0:29b62aeb769f
3 0:29b62aeb769f
4 commit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000
4 commit hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000
5 commit.b hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000
5 commit.b hook: HG_NODE=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PARENT1=0000000000000000000000000000000000000000
6 updating to branch default
6 updating to branch default
7 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
8 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
9 pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a
9 pretxncommit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a
10 1:b702efe96888
10 1:b702efe96888
11 commit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
11 commit hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
12 commit.b hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
12 commit.b hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
14 precommit hook: HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
15 pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a
15 pretxncommit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b HG_PENDING=$HGTMP/test-hook/a
16 2:1324a5531bac
16 2:1324a5531bac
17 commit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
17 commit hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
18 commit.b hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
18 commit.b hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT1=29b62aeb769fdf78d8d9c5f28b017f76d7ef824b
19 created new head
19 created new head
20 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
21 (branch merge, don't forget to commit)
22 precommit hook: HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
22 precommit hook: HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
23 pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=$HGTMP/test-hook/a
23 pretxncommit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2 HG_PENDING=$HGTMP/test-hook/a
24 3:4c52fb2e4022
24 3:4c52fb2e4022
25 commit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
25 commit hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
26 commit.b hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
26 commit.b hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_PARENT1=1324a5531bac09b329c3845d35ae6a7526874edb HG_PARENT2=b702efe9688826e3a91283852b328b84dbf37bc2
27 pre-identify hook: HG_ARGS=id
27 pre-identify hook: HG_ARGS=id
28 warning: pre-identify hook exited with status 1
28 warning: pre-identify hook exited with status 1
29 pre-cat hook: HG_ARGS=cat b
29 pre-cat hook: HG_ARGS=cat b
30 post-cat hook: HG_ARGS=cat b HG_RESULT=0
30 post-cat hook: HG_ARGS=cat b HG_RESULT=0
31 b
31 b
32 prechangegroup hook: HG_SOURCE=pull HG_URL=file:
32 prechangegroup hook: HG_SOURCE=pull HG_URL=file:
33 changegroup hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_SOURCE=pull HG_URL=file:
33 changegroup hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_SOURCE=pull HG_URL=file:
34 incoming hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_SOURCE=pull HG_URL=file:
34 incoming hook: HG_NODE=b702efe9688826e3a91283852b328b84dbf37bc2 HG_SOURCE=pull HG_URL=file:
35 incoming hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_SOURCE=pull HG_URL=file:
35 incoming hook: HG_NODE=1324a5531bac09b329c3845d35ae6a7526874edb HG_SOURCE=pull HG_URL=file:
36 incoming hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_SOURCE=pull HG_URL=file:
36 incoming hook: HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_SOURCE=pull HG_URL=file:
37 pulling from ../a
37 pulling from ../a
38 searching for changes
38 searching for changes
39 adding changesets
39 adding changesets
40 adding manifests
40 adding manifests
41 adding file changes
41 adding file changes
42 added 3 changesets with 2 changes to 2 files
42 added 3 changesets with 2 changes to 2 files
43 (run 'hg update' to get a working copy)
43 (run 'hg update' to get a working copy)
44 pretag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a
44 pretag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a
45 precommit hook: HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
45 precommit hook: HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
46 pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=$HGTMP/test-hook/a
46 pretxncommit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321 HG_PENDING=$HGTMP/test-hook/a
47 4:8ea2ef7ad3e8
47 4:8ea2ef7ad3e8
48 commit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
48 commit hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
49 commit.b hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
49 commit.b hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PARENT1=4c52fb2e402287dd5dc052090682536c8406c321
50 tag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a
50 tag hook: HG_LOCAL=0 HG_NODE=4c52fb2e402287dd5dc052090682536c8406c321 HG_TAG=a
51 pretag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=la
51 pretag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=la
52 tag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=la
52 tag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=la
53 pretag hook: HG_LOCAL=0 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fa
53 pretag hook: HG_LOCAL=0 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fa
54 pretag.forbid hook: HG_LOCAL=0 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fa
54 pretag.forbid hook: HG_LOCAL=0 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fa
55 abort: pretag.forbid hook exited with status 1
55 abort: pretag.forbid hook exited with status 1
56 pretag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fla
56 pretag hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fla
57 pretag.forbid hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fla
57 pretag.forbid hook: HG_LOCAL=1 HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_TAG=fla
58 abort: pretag.forbid hook exited with status 1
58 abort: pretag.forbid hook exited with status 1
59 4:8ea2ef7ad3e8
59 4:8ea2ef7ad3e8
60 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
60 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
61 pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a
61 pretxncommit hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a
62 5:fad284daf8c0
62 5:fad284daf8c0
63 5:fad284daf8c0
63 5:fad284daf8c0
64 pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a
64 pretxncommit.forbid hook: HG_NODE=fad284daf8c032148abaffcd745dafeceefceb61 HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/a
65 transaction abort!
65 transaction abort!
66 rollback completed
66 rollback completed
67 abort: pretxncommit.forbid1 hook exited with status 1
67 abort: pretxncommit.forbid1 hook exited with status 1
68 4:8ea2ef7ad3e8
68 4:8ea2ef7ad3e8
69 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
69 precommit hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
70 precommit.forbid hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
70 precommit.forbid hook: HG_PARENT1=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198
71 abort: precommit.forbid hook exited with status 1
71 abort: precommit.forbid hook exited with status 1
72 4:8ea2ef7ad3e8
72 4:8ea2ef7ad3e8
73 preupdate hook: HG_PARENT1=b702efe96888
73 preupdate hook: HG_PARENT1=b702efe96888
74 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
74 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
75 preupdate hook: HG_PARENT1=8ea2ef7ad3e8
75 preupdate hook: HG_PARENT1=8ea2ef7ad3e8
76 update hook: HG_ERROR=0 HG_PARENT1=8ea2ef7ad3e8
76 update hook: HG_ERROR=0 HG_PARENT1=8ea2ef7ad3e8
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 3:4c52fb2e4022
78 3:4c52fb2e4022
79 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:
79 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:
80 pulling from ../a
80 pulling from ../a
81 searching for changes
81 searching for changes
82 abort: prechangegroup.forbid hook exited with status 1
82 abort: prechangegroup.forbid hook exited with status 1
83 4:8ea2ef7ad3e8
83 4:8ea2ef7ad3e8
84 pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/b HG_SOURCE=pull HG_URL=file:
84 pretxnchangegroup.forbid hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_PENDING=$HGTMP/test-hook/b HG_SOURCE=pull HG_URL=file:
85 pulling from ../a
85 pulling from ../a
86 searching for changes
86 searching for changes
87 adding changesets
87 adding changesets
88 adding manifests
88 adding manifests
89 adding file changes
89 adding file changes
90 added 1 changesets with 1 changes to 1 files
90 added 1 changesets with 1 changes to 1 files
91 transaction abort!
91 transaction abort!
92 rollback completed
92 rollback completed
93 abort: pretxnchangegroup.forbid1 hook exited with status 1
93 abort: pretxnchangegroup.forbid1 hook exited with status 1
94 3:4c52fb2e4022
94 3:4c52fb2e4022
95 preoutgoing hook: HG_SOURCE=pull
95 preoutgoing hook: HG_SOURCE=pull
96 outgoing hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_SOURCE=pull
96 outgoing hook: HG_NODE=8ea2ef7ad3e8cac946c72f1e0c79d6aebc301198 HG_SOURCE=pull
97 pulling from ../a
97 pulling from ../a
98 searching for changes
98 searching for changes
99 adding changesets
99 adding changesets
100 adding manifests
100 adding manifests
101 adding file changes
101 adding file changes
102 added 1 changesets with 1 changes to 1 files
102 added 1 changesets with 1 changes to 1 files
103 (run 'hg update' to get a working copy)
103 (run 'hg update' to get a working copy)
104 rolling back pull to revision 4
104 rolling back to revision 4 (undo pull)
105 preoutgoing hook: HG_SOURCE=pull
105 preoutgoing hook: HG_SOURCE=pull
106 preoutgoing.forbid hook: HG_SOURCE=pull
106 preoutgoing.forbid hook: HG_SOURCE=pull
107 pulling from ../a
107 pulling from ../a
108 searching for changes
108 searching for changes
109 abort: preoutgoing.forbid hook exited with status 1
109 abort: preoutgoing.forbid hook exited with status 1
110 preoutgoing hook: HG_SOURCE=clone
110 preoutgoing hook: HG_SOURCE=clone
111 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
111 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
112 updating to branch default
112 updating to branch default
113 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
114 preoutgoing hook: HG_SOURCE=clone
114 preoutgoing hook: HG_SOURCE=clone
115 preoutgoing.forbid hook: HG_SOURCE=clone
115 preoutgoing.forbid hook: HG_SOURCE=clone
116 abort: preoutgoing.forbid hook exited with status 1
116 abort: preoutgoing.forbid hook exited with status 1
117 # test python hooks
117 # test python hooks
118 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
118 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
119 error: preoutgoing.raise hook raised an exception: exception from hook
119 error: preoutgoing.raise hook raised an exception: exception from hook
120 pulling from ../a
120 pulling from ../a
121 searching for changes
121 searching for changes
122 error: preoutgoing.abort hook failed: raise abort from hook
122 error: preoutgoing.abort hook failed: raise abort from hook
123 abort: raise abort from hook
123 abort: raise abort from hook
124 pulling from ../a
124 pulling from ../a
125 searching for changes
125 searching for changes
126 hook args:
126 hook args:
127 hooktype preoutgoing
127 hooktype preoutgoing
128 source pull
128 source pull
129 abort: preoutgoing.fail hook failed
129 abort: preoutgoing.fail hook failed
130 pulling from ../a
130 pulling from ../a
131 searching for changes
131 searching for changes
132 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
132 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
133 pulling from ../a
133 pulling from ../a
134 searching for changes
134 searching for changes
135 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
135 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
136 pulling from ../a
136 pulling from ../a
137 searching for changes
137 searching for changes
138 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
138 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
139 pulling from ../a
139 pulling from ../a
140 searching for changes
140 searching for changes
141 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
141 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
142 pulling from ../a
142 pulling from ../a
143 searching for changes
143 searching for changes
144 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
144 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
145 pulling from ../a
145 pulling from ../a
146 searching for changes
146 searching for changes
147 hook args:
147 hook args:
148 hooktype preoutgoing
148 hooktype preoutgoing
149 source pull
149 source pull
150 adding changesets
150 adding changesets
151 adding manifests
151 adding manifests
152 adding file changes
152 adding file changes
153 added 1 changesets with 1 changes to 1 files
153 added 1 changesets with 1 changes to 1 files
154 (run 'hg update' to get a working copy)
154 (run 'hg update' to get a working copy)
155 # make sure --traceback works
155 # make sure --traceback works
156 Traceback (most recent call last):
156 Traceback (most recent call last):
157 Automatically installed hook
157 Automatically installed hook
158 foo
158 foo
159 calling hook commit.auto: <function autohook>
159 calling hook commit.auto: <function autohook>
160 Automatically installed hook
160 Automatically installed hook
161 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
161 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
162 hooks.commit.auto=<function autohook>
162 hooks.commit.auto=<function autohook>
163 # test python hook configured with python:[file]:[hook] syntax
163 # test python hook configured with python:[file]:[hook] syntax
164 hook works
164 hook works
165 nothing changed
165 nothing changed
166 # make sure --traceback works on hook import failure
166 # make sure --traceback works on hook import failure
167 exception from first failed import attempt:
167 exception from first failed import attempt:
168 Traceback (most recent call last):
168 Traceback (most recent call last):
169 ImportError: No module named somebogusmodule
169 ImportError: No module named somebogusmodule
170 exception from second failed import attempt:
170 exception from second failed import attempt:
171 Traceback (most recent call last):
171 Traceback (most recent call last):
172 ImportError: No module named hgext_importfail
172 ImportError: No module named hgext_importfail
173 Traceback (most recent call last):
173 Traceback (most recent call last):
174 # commit and update hooks should run after command completion (issue 1827)
174 # commit and update hooks should run after command completion (issue 1827)
175 8da618c33484 tip
175 8da618c33484 tip
176 29b62aeb769f
176 29b62aeb769f
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,381 +1,381 b''
1 adding a
1 adding a
2 adding d1/d2/a
2 adding d1/d2/a
3 % import exported patch
3 % import exported patch
4 requesting all changes
4 requesting all changes
5 adding changesets
5 adding changesets
6 adding manifests
6 adding manifests
7 adding file changes
7 adding file changes
8 added 1 changesets with 2 changes to 2 files
8 added 1 changesets with 2 changes to 2 files
9 updating to branch default
9 updating to branch default
10 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 applying ../tip.patch
11 applying ../tip.patch
12 % message should be same
12 % message should be same
13 summary: second change
13 summary: second change
14 % committer should be same
14 % committer should be same
15 user: someone
15 user: someone
16 % import exported patch with external patcher
16 % import exported patch with external patcher
17 requesting all changes
17 requesting all changes
18 adding changesets
18 adding changesets
19 adding manifests
19 adding manifests
20 adding file changes
20 adding file changes
21 added 1 changesets with 2 changes to 2 files
21 added 1 changesets with 2 changes to 2 files
22 updating to branch default
22 updating to branch default
23 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 applying ../tip.patch
24 applying ../tip.patch
25 line2
25 line2
26 % import of plain diff should fail without message
26 % import of plain diff should fail without message
27 requesting all changes
27 requesting all changes
28 adding changesets
28 adding changesets
29 adding manifests
29 adding manifests
30 adding file changes
30 adding file changes
31 added 1 changesets with 2 changes to 2 files
31 added 1 changesets with 2 changes to 2 files
32 updating to branch default
32 updating to branch default
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 applying ../tip.patch
34 applying ../tip.patch
35 abort: empty commit message
35 abort: empty commit message
36 % import of plain diff should be ok with message
36 % import of plain diff should be ok with message
37 requesting all changes
37 requesting all changes
38 adding changesets
38 adding changesets
39 adding manifests
39 adding manifests
40 adding file changes
40 adding file changes
41 added 1 changesets with 2 changes to 2 files
41 added 1 changesets with 2 changes to 2 files
42 updating to branch default
42 updating to branch default
43 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 applying ../tip.patch
44 applying ../tip.patch
45 % import of plain diff with specific date and user
45 % import of plain diff with specific date and user
46 requesting all changes
46 requesting all changes
47 adding changesets
47 adding changesets
48 adding manifests
48 adding manifests
49 adding file changes
49 adding file changes
50 added 1 changesets with 2 changes to 2 files
50 added 1 changesets with 2 changes to 2 files
51 updating to branch default
51 updating to branch default
52 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
52 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 applying ../tip.patch
53 applying ../tip.patch
54 changeset: 1:ca68f19f3a40
54 changeset: 1:ca68f19f3a40
55 tag: tip
55 tag: tip
56 user: user@nowhere.net
56 user: user@nowhere.net
57 date: Thu Jan 01 00:00:01 1970 +0000
57 date: Thu Jan 01 00:00:01 1970 +0000
58 files: a
58 files: a
59 description:
59 description:
60 patch
60 patch
61
61
62
62
63 diff -r 80971e65b431 -r ca68f19f3a40 a
63 diff -r 80971e65b431 -r ca68f19f3a40 a
64 --- a/a Thu Jan 01 00:00:00 1970 +0000
64 --- a/a Thu Jan 01 00:00:00 1970 +0000
65 +++ b/a Thu Jan 01 00:00:01 1970 +0000
65 +++ b/a Thu Jan 01 00:00:01 1970 +0000
66 @@ -1,1 +1,2 @@
66 @@ -1,1 +1,2 @@
67 line 1
67 line 1
68 +line 2
68 +line 2
69
69
70 % import of plain diff should be ok with --no-commit
70 % import of plain diff should be ok with --no-commit
71 requesting all changes
71 requesting all changes
72 adding changesets
72 adding changesets
73 adding manifests
73 adding manifests
74 adding file changes
74 adding file changes
75 added 1 changesets with 2 changes to 2 files
75 added 1 changesets with 2 changes to 2 files
76 updating to branch default
76 updating to branch default
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 applying ../tip.patch
78 applying ../tip.patch
79 diff -r 80971e65b431 a
79 diff -r 80971e65b431 a
80 --- a/a
80 --- a/a
81 +++ b/a
81 +++ b/a
82 @@ -1,1 +1,2 @@
82 @@ -1,1 +1,2 @@
83 line 1
83 line 1
84 +line 2
84 +line 2
85 % hg -R repo import
85 % hg -R repo import
86 requesting all changes
86 requesting all changes
87 adding changesets
87 adding changesets
88 adding manifests
88 adding manifests
89 adding file changes
89 adding file changes
90 added 1 changesets with 2 changes to 2 files
90 added 1 changesets with 2 changes to 2 files
91 updating to branch default
91 updating to branch default
92 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 applying tip.patch
93 applying tip.patch
94 % import from stdin
94 % import from stdin
95 requesting all changes
95 requesting all changes
96 adding changesets
96 adding changesets
97 adding manifests
97 adding manifests
98 adding file changes
98 adding file changes
99 added 1 changesets with 2 changes to 2 files
99 added 1 changesets with 2 changes to 2 files
100 updating to branch default
100 updating to branch default
101 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 applying patch from stdin
102 applying patch from stdin
103 % import two patches in one stream
103 % import two patches in one stream
104 applying patch from stdin
104 applying patch from stdin
105 applied 80971e65b431
105 applied 80971e65b431
106 1d4bd90af0e4 tip
106 1d4bd90af0e4 tip
107 1d4bd90af0e4 tip
107 1d4bd90af0e4 tip
108 % override commit message
108 % override commit message
109 requesting all changes
109 requesting all changes
110 adding changesets
110 adding changesets
111 adding manifests
111 adding manifests
112 adding file changes
112 adding file changes
113 added 1 changesets with 2 changes to 2 files
113 added 1 changesets with 2 changes to 2 files
114 updating to branch default
114 updating to branch default
115 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 applying patch from stdin
116 applying patch from stdin
117 summary: override
117 summary: override
118 % plain diff in email, subject, message body
118 % plain diff in email, subject, message body
119 requesting all changes
119 requesting all changes
120 adding changesets
120 adding changesets
121 adding manifests
121 adding manifests
122 adding file changes
122 adding file changes
123 added 1 changesets with 2 changes to 2 files
123 added 1 changesets with 2 changes to 2 files
124 updating to branch default
124 updating to branch default
125 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 applying ../msg.patch
126 applying ../msg.patch
127 user: email patcher
127 user: email patcher
128 summary: email patch
128 summary: email patch
129 % plain diff in email, no subject, message body
129 % plain diff in email, no subject, message body
130 requesting all changes
130 requesting all changes
131 adding changesets
131 adding changesets
132 adding manifests
132 adding manifests
133 adding file changes
133 adding file changes
134 added 1 changesets with 2 changes to 2 files
134 added 1 changesets with 2 changes to 2 files
135 updating to branch default
135 updating to branch default
136 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
137 applying patch from stdin
137 applying patch from stdin
138 % plain diff in email, subject, no message body
138 % plain diff in email, subject, no message body
139 requesting all changes
139 requesting all changes
140 adding changesets
140 adding changesets
141 adding manifests
141 adding manifests
142 adding file changes
142 adding file changes
143 added 1 changesets with 2 changes to 2 files
143 added 1 changesets with 2 changes to 2 files
144 updating to branch default
144 updating to branch default
145 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
145 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 applying patch from stdin
146 applying patch from stdin
147 % plain diff in email, no subject, no message body, should fail
147 % plain diff in email, no subject, no message body, should fail
148 requesting all changes
148 requesting all changes
149 adding changesets
149 adding changesets
150 adding manifests
150 adding manifests
151 adding file changes
151 adding file changes
152 added 1 changesets with 2 changes to 2 files
152 added 1 changesets with 2 changes to 2 files
153 updating to branch default
153 updating to branch default
154 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
154 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 applying patch from stdin
155 applying patch from stdin
156 abort: empty commit message
156 abort: empty commit message
157 % hg export in email, should use patch header
157 % hg export in email, should use patch header
158 requesting all changes
158 requesting all changes
159 adding changesets
159 adding changesets
160 adding manifests
160 adding manifests
161 adding file changes
161 adding file changes
162 added 1 changesets with 2 changes to 2 files
162 added 1 changesets with 2 changes to 2 files
163 updating to branch default
163 updating to branch default
164 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 applying patch from stdin
165 applying patch from stdin
166 summary: second change
166 summary: second change
167 % plain diff in email, [PATCH] subject, message body with subject
167 % plain diff in email, [PATCH] subject, message body with subject
168 requesting all changes
168 requesting all changes
169 adding changesets
169 adding changesets
170 adding manifests
170 adding manifests
171 adding file changes
171 adding file changes
172 added 1 changesets with 2 changes to 2 files
172 added 1 changesets with 2 changes to 2 files
173 updating to branch default
173 updating to branch default
174 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 applying patch from stdin
175 applying patch from stdin
176 email patch
176 email patch
177
177
178 next line
178 next line
179 ---
179 ---
180 % import patch1 patch2; rollback
180 % import patch1 patch2; rollback
181 parent: 0
181 parent: 0
182 applying ../patch1
182 applying ../patch1
183 applying ../patch2
183 applying ../patch2
184 applied 1d4bd90af0e4
184 applied 1d4bd90af0e4
185 rolling back commit to revision 2
185 rolling back to revision 2 (undo commit)
186 parent: 1
186 parent: 1
187 % hg import in a subdirectory
187 % hg import in a subdirectory
188 requesting all changes
188 requesting all changes
189 adding changesets
189 adding changesets
190 adding manifests
190 adding manifests
191 adding file changes
191 adding file changes
192 added 1 changesets with 2 changes to 2 files
192 added 1 changesets with 2 changes to 2 files
193 updating to branch default
193 updating to branch default
194 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 applying ../../../tip.patch
195 applying ../../../tip.patch
196 % message should be 'subdir change'
196 % message should be 'subdir change'
197 summary: subdir change
197 summary: subdir change
198 % committer should be 'someoneelse'
198 % committer should be 'someoneelse'
199 user: someoneelse
199 user: someoneelse
200 % should be empty
200 % should be empty
201 % test fuzziness
201 % test fuzziness
202 adding a
202 adding a
203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 created new head
204 created new head
205 applying tip.patch
205 applying tip.patch
206 patching file a
206 patching file a
207 Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
207 Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
208 reverting a
208 reverting a
209 % test fuzziness with eol=auto
209 % test fuzziness with eol=auto
210 applying tip.patch
210 applying tip.patch
211 patching file a
211 patching file a
212 Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
212 Hunk #1 succeeded at 1 with fuzz 2 (offset -2 lines).
213 adding a
213 adding a
214 adding b1
214 adding b1
215 adding c1
215 adding c1
216 adding d
216 adding d
217 diff --git a/a b/a
217 diff --git a/a b/a
218 --- a/a
218 --- a/a
219 +++ b/a
219 +++ b/a
220 @@ -0,0 +1,1 @@
220 @@ -0,0 +1,1 @@
221 +a
221 +a
222 diff --git a/b1 b/b2
222 diff --git a/b1 b/b2
223 rename from b1
223 rename from b1
224 rename to b2
224 rename to b2
225 --- a/b1
225 --- a/b1
226 +++ b/b2
226 +++ b/b2
227 @@ -0,0 +1,1 @@
227 @@ -0,0 +1,1 @@
228 +b
228 +b
229 diff --git a/c1 b/c1
229 diff --git a/c1 b/c1
230 --- a/c1
230 --- a/c1
231 +++ b/c1
231 +++ b/c1
232 @@ -0,0 +1,1 @@
232 @@ -0,0 +1,1 @@
233 +c
233 +c
234 diff --git a/c1 b/c2
234 diff --git a/c1 b/c2
235 copy from c1
235 copy from c1
236 copy to c2
236 copy to c2
237 --- a/c1
237 --- a/c1
238 +++ b/c2
238 +++ b/c2
239 @@ -0,0 +1,1 @@
239 @@ -0,0 +1,1 @@
240 +c
240 +c
241 diff --git a/d b/d
241 diff --git a/d b/d
242 --- a/d
242 --- a/d
243 +++ b/d
243 +++ b/d
244 @@ -1,1 +0,0 @@
244 @@ -1,1 +0,0 @@
245 -d
245 -d
246 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
246 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
247 applying empty.diff
247 applying empty.diff
248 % a file
248 % a file
249 a
249 a
250 % b1 file
250 % b1 file
251 % b2 file
251 % b2 file
252 b
252 b
253 % c1 file
253 % c1 file
254 c
254 c
255 % c2 file
255 % c2 file
256 c
256 c
257 % d file
257 % d file
258 % test trailing binary removal
258 % test trailing binary removal
259 adding a
259 adding a
260 adding b
260 adding b
261 R a
261 R a
262 R b
262 R b
263 diff --git a/a b/a
263 diff --git a/a b/a
264 diff --git a/b b/b
264 diff --git a/b b/b
265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 applying remove.diff
266 applying remove.diff
267 % test update+rename with common name (issue 927)
267 % test update+rename with common name (issue 927)
268 adding a
268 adding a
269 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
269 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
270 applying copy.diff
270 applying copy.diff
271 % view a
271 % view a
272 a
272 a
273 % view a2
273 % view a2
274 a
274 a
275 % test -p0
275 % test -p0
276 adding a
276 adding a
277 applying patch from stdin
277 applying patch from stdin
278 bb
278 bb
279 % test paths outside repo root
279 % test paths outside repo root
280 applying patch from stdin
280 applying patch from stdin
281 abort: ../outside/foo not under root
281 abort: ../outside/foo not under root
282 % test import with similarity (issue295)
282 % test import with similarity (issue295)
283 adding a
283 adding a
284 applying ../rename.diff
284 applying ../rename.diff
285 patching file a
285 patching file a
286 patching file b
286 patching file b
287 removing a
287 removing a
288 adding b
288 adding b
289 recording removal of a as rename to b (88% similar)
289 recording removal of a as rename to b (88% similar)
290 A b
290 A b
291 a
291 a
292 R a
292 R a
293 undeleting a
293 undeleting a
294 forgetting b
294 forgetting b
295 applying ../rename.diff
295 applying ../rename.diff
296 patching file a
296 patching file a
297 patching file b
297 patching file b
298 removing a
298 removing a
299 adding b
299 adding b
300 A b
300 A b
301 R a
301 R a
302 % add empty file from the end of patch (issue 1495)
302 % add empty file from the end of patch (issue 1495)
303 adding a
303 adding a
304 applying a.patch
304 applying a.patch
305 % create file when source is not /dev/null
305 % create file when source is not /dev/null
306 applying ../create.patch
306 applying ../create.patch
307 a
307 a
308 applying ../create2.patch
308 applying ../create2.patch
309 a
309 a
310 % first line mistaken for email headers (issue 1859)
310 % first line mistaken for email headers (issue 1859)
311 applying a.patch
311 applying a.patch
312 changeset: 0:5a681217c0ad
312 changeset: 0:5a681217c0ad
313 tag: tip
313 tag: tip
314 user: test
314 user: test
315 date: Thu Jan 01 00:00:00 1970 +0000
315 date: Thu Jan 01 00:00:00 1970 +0000
316 files: a
316 files: a
317 description:
317 description:
318 module: summary
318 module: summary
319
319
320 description
320 description
321
321
322
322
323 % --- in commit message
323 % --- in commit message
324 applying a.patch
324 applying a.patch
325 changeset: 0:f34d9187897d
325 changeset: 0:f34d9187897d
326 tag: tip
326 tag: tip
327 user: test
327 user: test
328 date: Thu Jan 01 00:00:00 1970 +0000
328 date: Thu Jan 01 00:00:00 1970 +0000
329 files: a
329 files: a
330 description:
330 description:
331 module: summary
331 module: summary
332
332
333
333
334 % tricky header splitting
334 % tricky header splitting
335 applying ../trickyheaders.patch
335 applying ../trickyheaders.patch
336 # HG changeset patch
336 # HG changeset patch
337 # User User B
337 # User User B
338 # Date 0 0
338 # Date 0 0
339 # Node ID eb56ab91903632294ac504838508cb370c0901d2
339 # Node ID eb56ab91903632294ac504838508cb370c0901d2
340 # Parent 0000000000000000000000000000000000000000
340 # Parent 0000000000000000000000000000000000000000
341 from: tricky!
341 from: tricky!
342
342
343 That is not a header.
343 That is not a header.
344
344
345 diff --git a/foo b/foo
345 diff --git a/foo b/foo
346 new file mode 100644
346 new file mode 100644
347 --- /dev/null
347 --- /dev/null
348 +++ b/foo
348 +++ b/foo
349 @@ -0,0 +1,1 @@
349 @@ -0,0 +1,1 @@
350 +foo
350 +foo
351 % issue2102
351 % issue2102
352 adding src/cmd/gc/mksys.bash
352 adding src/cmd/gc/mksys.bash
353 applying patch from stdin
353 applying patch from stdin
354 parent: 1:d59915696727 tip
354 parent: 1:d59915696727 tip
355 help management of empty pkg and lib directories in perforce
355 help management of empty pkg and lib directories in perforce
356 branch: default
356 branch: default
357 commit: (clean)
357 commit: (clean)
358 update: (current)
358 update: (current)
359 diff --git a/lib/place-holder b/lib/place-holder
359 diff --git a/lib/place-holder b/lib/place-holder
360 new file mode 100644
360 new file mode 100644
361 --- /dev/null
361 --- /dev/null
362 +++ b/lib/place-holder
362 +++ b/lib/place-holder
363 @@ -0,0 +1,2 @@
363 @@ -0,0 +1,2 @@
364 +perforce does not maintain empty directories.
364 +perforce does not maintain empty directories.
365 +this file helps.
365 +this file helps.
366 diff --git a/pkg/place-holder b/pkg/place-holder
366 diff --git a/pkg/place-holder b/pkg/place-holder
367 new file mode 100644
367 new file mode 100644
368 --- /dev/null
368 --- /dev/null
369 +++ b/pkg/place-holder
369 +++ b/pkg/place-holder
370 @@ -0,0 +1,2 @@
370 @@ -0,0 +1,2 @@
371 +perforce does not maintain empty directories.
371 +perforce does not maintain empty directories.
372 +this file helps.
372 +this file helps.
373 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
373 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
374 old mode 100644
374 old mode 100644
375 new mode 100755
375 new mode 100755
376 % diff lines looking like headers
376 % diff lines looking like headers
377 adding a
377 adding a
378 adding b
378 adding b
379 adding c
379 adding c
380 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
381 applying patch from stdin
381 applying patch from stdin
@@ -1,480 +1,480 b''
1 % hg kwdemo
1 % hg kwdemo
2 [extensions]
2 [extensions]
3 keyword =
3 keyword =
4 [keyword]
4 [keyword]
5 demo.txt =
5 demo.txt =
6 [keywordmaps]
6 [keywordmaps]
7 Author = {author|user}
7 Author = {author|user}
8 Date = {date|utcdate}
8 Date = {date|utcdate}
9 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
9 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
10 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
10 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
11 RCSFile = {file|basename},v
11 RCSFile = {file|basename},v
12 RCSfile = {file|basename},v
12 RCSfile = {file|basename},v
13 Revision = {node|short}
13 Revision = {node|short}
14 Source = {root}/{file},v
14 Source = {root}/{file},v
15 $Author: test $
15 $Author: test $
16 $Date: 2000/00/00 00:00:00 $
16 $Date: 2000/00/00 00:00:00 $
17 $Header: /TMP/demo.txt,v xxxxxxxxxxxx 2000/00/00 00:00:00 test $
17 $Header: /TMP/demo.txt,v xxxxxxxxxxxx 2000/00/00 00:00:00 test $
18 $Id: demo.txt,v xxxxxxxxxxxx 2000/00/00 00:00:00 test $
18 $Id: demo.txt,v xxxxxxxxxxxx 2000/00/00 00:00:00 test $
19 $RCSFile: demo.txt,v $
19 $RCSFile: demo.txt,v $
20 $RCSfile: demo.txt,v $
20 $RCSfile: demo.txt,v $
21 $Revision: xxxxxxxxxxxx $
21 $Revision: xxxxxxxxxxxx $
22 $Source: /TMP/demo.txt,v $
22 $Source: /TMP/demo.txt,v $
23 [extensions]
23 [extensions]
24 keyword =
24 keyword =
25 [keyword]
25 [keyword]
26 demo.txt =
26 demo.txt =
27 [keywordmaps]
27 [keywordmaps]
28 Branch = {branches}
28 Branch = {branches}
29 $Branch: demobranch $
29 $Branch: demobranch $
30 % kwshrink should exit silently in empty/invalid repo
30 % kwshrink should exit silently in empty/invalid repo
31 pulling from test-keyword.hg
31 pulling from test-keyword.hg
32 requesting all changes
32 requesting all changes
33 adding changesets
33 adding changesets
34 adding manifests
34 adding manifests
35 adding file changes
35 adding file changes
36 added 1 changesets with 1 changes to 1 files
36 added 1 changesets with 1 changes to 1 files
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 % cat
38 % cat
39 expand $Id$
39 expand $Id$
40 do not process $Id:
40 do not process $Id:
41 xxx $
41 xxx $
42 ignore $Id$
42 ignore $Id$
43 % no kwfiles
43 % no kwfiles
44 % untracked candidates
44 % untracked candidates
45 k a
45 k a
46 % addremove
46 % addremove
47 adding a
47 adding a
48 adding b
48 adding b
49 % status
49 % status
50 A a
50 A a
51 A b
51 A b
52 % default keyword expansion including commit hook
52 % default keyword expansion including commit hook
53 % interrupted commit should not change state or run commit hook
53 % interrupted commit should not change state or run commit hook
54 abort: empty commit message
54 abort: empty commit message
55 % status
55 % status
56 A a
56 A a
57 A b
57 A b
58 % commit
58 % commit
59 a
59 a
60 b
60 b
61 overwriting a expanding keywords
61 overwriting a expanding keywords
62 running hook commit.test: cp a hooktest
62 running hook commit.test: cp a hooktest
63 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
63 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
64 % status
64 % status
65 ? hooktest
65 ? hooktest
66 % identify
66 % identify
67 ef63ca68695b
67 ef63ca68695b
68 % cat
68 % cat
69 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
69 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
70 do not process $Id:
70 do not process $Id:
71 xxx $
71 xxx $
72 ignore $Id$
72 ignore $Id$
73 % hg cat
73 % hg cat
74 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
74 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
75 do not process $Id:
75 do not process $Id:
76 xxx $
76 xxx $
77 ignore $Id$
77 ignore $Id$
78 a
78 a
79 % diff a hooktest
79 % diff a hooktest
80 % removing commit hook from config
80 % removing commit hook from config
81 % bundle
81 % bundle
82 2 changesets found
82 2 changesets found
83 % notify on pull to check whether keywords stay as is in email
83 % notify on pull to check whether keywords stay as is in email
84 % ie. if patch.diff wrapper acts as it should
84 % ie. if patch.diff wrapper acts as it should
85 % pull from bundle
85 % pull from bundle
86 pulling from ../kw.hg
86 pulling from ../kw.hg
87 requesting all changes
87 requesting all changes
88 adding changesets
88 adding changesets
89 adding manifests
89 adding manifests
90 adding file changes
90 adding file changes
91 added 2 changesets with 3 changes to 3 files
91 added 2 changesets with 3 changes to 3 files
92
92
93 diff -r 000000000000 -r a2392c293916 sym
93 diff -r 000000000000 -r a2392c293916 sym
94 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
94 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
95 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
95 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
96 @@ -0,0 +1,1 @@
96 @@ -0,0 +1,1 @@
97 +a
97 +a
98 \ No newline at end of file
98 \ No newline at end of file
99
99
100 diff -r a2392c293916 -r ef63ca68695b a
100 diff -r a2392c293916 -r ef63ca68695b a
101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
103 @@ -0,0 +1,3 @@
103 @@ -0,0 +1,3 @@
104 +expand $Id$
104 +expand $Id$
105 +do not process $Id:
105 +do not process $Id:
106 +xxx $
106 +xxx $
107 diff -r a2392c293916 -r ef63ca68695b b
107 diff -r a2392c293916 -r ef63ca68695b b
108 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
108 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
109 +++ b/b Thu Jan 01 00:00:00 1970 +0000
109 +++ b/b Thu Jan 01 00:00:00 1970 +0000
110 @@ -0,0 +1,1 @@
110 @@ -0,0 +1,1 @@
111 +ignore $Id$
111 +ignore $Id$
112 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 % remove notify config
113 % remove notify config
114 % touch
114 % touch
115 % status
115 % status
116 % update
116 % update
117 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 % cat
118 % cat
119 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
119 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
120 do not process $Id:
120 do not process $Id:
121 xxx $
121 xxx $
122 ignore $Id$
122 ignore $Id$
123 % check whether expansion is filewise
123 % check whether expansion is filewise
124 % commit c
124 % commit c
125 adding c
125 adding c
126 % force expansion
126 % force expansion
127 overwriting a expanding keywords
127 overwriting a expanding keywords
128 overwriting c expanding keywords
128 overwriting c expanding keywords
129 % compare changenodes in a c
129 % compare changenodes in a c
130 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
130 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
131 do not process $Id:
131 do not process $Id:
132 xxx $
132 xxx $
133 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
133 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
134 tests for different changenodes
134 tests for different changenodes
135 % qinit -c
135 % qinit -c
136 % qimport
136 % qimport
137 % qcommit
137 % qcommit
138 % keywords should not be expanded in patch
138 % keywords should not be expanded in patch
139 # HG changeset patch
139 # HG changeset patch
140 # User User Name <user@example.com>
140 # User User Name <user@example.com>
141 # Date 1 0
141 # Date 1 0
142 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
142 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
143 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
143 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
144 cndiff
144 cndiff
145
145
146 diff -r ef63ca68695b -r 40a904bbbe4c c
146 diff -r ef63ca68695b -r 40a904bbbe4c c
147 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148 +++ b/c Thu Jan 01 00:00:01 1970 +0000
148 +++ b/c Thu Jan 01 00:00:01 1970 +0000
149 @@ -0,0 +1,2 @@
149 @@ -0,0 +1,2 @@
150 +$Id$
150 +$Id$
151 +tests for different changenodes
151 +tests for different changenodes
152 % qpop
152 % qpop
153 popping mqtest.diff
153 popping mqtest.diff
154 patch queue now empty
154 patch queue now empty
155 % qgoto - should imply qpush
155 % qgoto - should imply qpush
156 applying mqtest.diff
156 applying mqtest.diff
157 now at: mqtest.diff
157 now at: mqtest.diff
158 % cat
158 % cat
159 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
159 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
160 tests for different changenodes
160 tests for different changenodes
161 % qpop and move on
161 % qpop and move on
162 popping mqtest.diff
162 popping mqtest.diff
163 patch queue now empty
163 patch queue now empty
164 % copy
164 % copy
165 % kwfiles added
165 % kwfiles added
166 a
166 a
167 c
167 c
168 % commit
168 % commit
169 c
169 c
170 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
170 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
171 overwriting c expanding keywords
171 overwriting c expanding keywords
172 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
172 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
173 % cat a c
173 % cat a c
174 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
174 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
175 do not process $Id:
175 do not process $Id:
176 xxx $
176 xxx $
177 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
177 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
178 do not process $Id:
178 do not process $Id:
179 xxx $
179 xxx $
180 % touch copied c
180 % touch copied c
181 % status
181 % status
182 % kwfiles
182 % kwfiles
183 a
183 a
184 c
184 c
185 % ignored files
185 % ignored files
186 I b
186 I b
187 I sym
187 I sym
188 % all files
188 % all files
189 K a
189 K a
190 K c
190 K c
191 I b
191 I b
192 I sym
192 I sym
193 % diff --rev
193 % diff --rev
194 diff -r ef63ca68695b c
194 diff -r ef63ca68695b c
195 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
195 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
196 @@ -0,0 +1,3 @@
196 @@ -0,0 +1,3 @@
197 +expand $Id$
197 +expand $Id$
198 +do not process $Id:
198 +do not process $Id:
199 +xxx $
199 +xxx $
200 % rollback
200 % rollback
201 rolling back commit to revision 2
201 rolling back to revision 2 (undo commit)
202 % status
202 % status
203 A c
203 A c
204 % update -C
204 % update -C
205 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 % custom keyword expansion
206 % custom keyword expansion
207 % try with kwdemo
207 % try with kwdemo
208 [extensions]
208 [extensions]
209 keyword =
209 keyword =
210 [keyword]
210 [keyword]
211 * =
211 * =
212 b = ignore
212 b = ignore
213 demo.txt =
213 demo.txt =
214 [keywordmaps]
214 [keywordmaps]
215 Xinfo = {author}: {desc}
215 Xinfo = {author}: {desc}
216 $Xinfo: test: hg keyword configuration and expansion example $
216 $Xinfo: test: hg keyword configuration and expansion example $
217 % cat
217 % cat
218 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
218 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
219 do not process $Id:
219 do not process $Id:
220 xxx $
220 xxx $
221 ignore $Id$
221 ignore $Id$
222 % hg cat
222 % hg cat
223 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
223 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
224 do not process $Id:
224 do not process $Id:
225 xxx $
225 xxx $
226 ignore $Id$
226 ignore $Id$
227 a
227 a
228 % interrupted commit should not change state
228 % interrupted commit should not change state
229 abort: empty commit message
229 abort: empty commit message
230 % status
230 % status
231 M a
231 M a
232 ? c
232 ? c
233 ? log
233 ? log
234 % commit
234 % commit
235 a
235 a
236 overwriting a expanding keywords
236 overwriting a expanding keywords
237 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
237 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
238 % status
238 % status
239 ? c
239 ? c
240 % verify
240 % verify
241 checking changesets
241 checking changesets
242 checking manifests
242 checking manifests
243 crosschecking files in changesets and manifests
243 crosschecking files in changesets and manifests
244 checking files
244 checking files
245 3 files, 3 changesets, 4 total revisions
245 3 files, 3 changesets, 4 total revisions
246 % cat
246 % cat
247 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
247 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
248 do not process $Id:
248 do not process $Id:
249 xxx $
249 xxx $
250 $Xinfo: User Name <user@example.com>: firstline $
250 $Xinfo: User Name <user@example.com>: firstline $
251 ignore $Id$
251 ignore $Id$
252 % hg cat
252 % hg cat
253 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
253 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
254 do not process $Id:
254 do not process $Id:
255 xxx $
255 xxx $
256 $Xinfo: User Name <user@example.com>: firstline $
256 $Xinfo: User Name <user@example.com>: firstline $
257 ignore $Id$
257 ignore $Id$
258 a
258 a
259 % annotate
259 % annotate
260 1: expand $Id$
260 1: expand $Id$
261 1: do not process $Id:
261 1: do not process $Id:
262 1: xxx $
262 1: xxx $
263 2: $Xinfo$
263 2: $Xinfo$
264 % remove
264 % remove
265 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
265 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
266 % status
266 % status
267 ? c
267 ? c
268 % rollback
268 % rollback
269 rolling back commit to revision 3
269 rolling back to revision 3 (undo commit)
270 % status
270 % status
271 R a
271 R a
272 ? c
272 ? c
273 % revert a
273 % revert a
274 % cat a
274 % cat a
275 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
275 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
276 do not process $Id:
276 do not process $Id:
277 xxx $
277 xxx $
278 $Xinfo: User Name <user@example.com>: firstline $
278 $Xinfo: User Name <user@example.com>: firstline $
279 % clone to test incoming
279 % clone to test incoming
280 requesting all changes
280 requesting all changes
281 adding changesets
281 adding changesets
282 adding manifests
282 adding manifests
283 adding file changes
283 adding file changes
284 added 2 changesets with 3 changes to 3 files
284 added 2 changesets with 3 changes to 3 files
285 updating to branch default
285 updating to branch default
286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 % incoming
287 % incoming
288 comparing with test-keyword/Test
288 comparing with test-keyword/Test
289 searching for changes
289 searching for changes
290 changeset: 2:bb948857c743
290 changeset: 2:bb948857c743
291 tag: tip
291 tag: tip
292 user: User Name <user@example.com>
292 user: User Name <user@example.com>
293 date: Thu Jan 01 00:00:02 1970 +0000
293 date: Thu Jan 01 00:00:02 1970 +0000
294 summary: firstline
294 summary: firstline
295
295
296 % commit rejecttest
296 % commit rejecttest
297 a
297 a
298 overwriting a expanding keywords
298 overwriting a expanding keywords
299 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
299 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
300 % export
300 % export
301 % import
301 % import
302 applying ../rejecttest.diff
302 applying ../rejecttest.diff
303 % cat
303 % cat
304 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
304 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
305 do not process $Id: rejecttest
305 do not process $Id: rejecttest
306 xxx $
306 xxx $
307 $Xinfo: User Name <user@example.com>: rejects? $
307 $Xinfo: User Name <user@example.com>: rejects? $
308 ignore $Id$
308 ignore $Id$
309
309
310 % rollback
310 % rollback
311 rolling back commit to revision 3
311 rolling back to revision 3 (undo commit)
312 % clean update
312 % clean update
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 % kwexpand/kwshrink on selected files
314 % kwexpand/kwshrink on selected files
315 % copy a x/a
315 % copy a x/a
316 % kwexpand a
316 % kwexpand a
317 overwriting a expanding keywords
317 overwriting a expanding keywords
318 % kwexpand x/a should abort
318 % kwexpand x/a should abort
319 abort: outstanding uncommitted changes
319 abort: outstanding uncommitted changes
320 x/a
320 x/a
321 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
321 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
322 overwriting x/a expanding keywords
322 overwriting x/a expanding keywords
323 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
323 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
324 % cat a
324 % cat a
325 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
325 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
326 do not process $Id:
326 do not process $Id:
327 xxx $
327 xxx $
328 $Xinfo: User Name <user@example.com>: xa $
328 $Xinfo: User Name <user@example.com>: xa $
329 % kwshrink a inside directory x
329 % kwshrink a inside directory x
330 overwriting x/a shrinking keywords
330 overwriting x/a shrinking keywords
331 % cat a
331 % cat a
332 expand $Id$
332 expand $Id$
333 do not process $Id:
333 do not process $Id:
334 xxx $
334 xxx $
335 $Xinfo$
335 $Xinfo$
336 % kwexpand nonexistent
336 % kwexpand nonexistent
337 nonexistent:
337 nonexistent:
338 % hg serve
338 % hg serve
339 % expansion
339 % expansion
340 % hgweb file
340 % hgweb file
341 200 Script output follows
341 200 Script output follows
342
342
343 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
343 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
344 do not process $Id:
344 do not process $Id:
345 xxx $
345 xxx $
346 $Xinfo: User Name <user@example.com>: firstline $
346 $Xinfo: User Name <user@example.com>: firstline $
347 % no expansion
347 % no expansion
348 % hgweb annotate
348 % hgweb annotate
349 200 Script output follows
349 200 Script output follows
350
350
351
351
352 user@1: expand $Id$
352 user@1: expand $Id$
353 user@1: do not process $Id:
353 user@1: do not process $Id:
354 user@1: xxx $
354 user@1: xxx $
355 user@2: $Xinfo$
355 user@2: $Xinfo$
356
356
357
357
358
358
359
359
360 % hgweb changeset
360 % hgweb changeset
361 200 Script output follows
361 200 Script output follows
362
362
363
363
364 # HG changeset patch
364 # HG changeset patch
365 # User User Name <user@example.com>
365 # User User Name <user@example.com>
366 # Date 3 0
366 # Date 3 0
367 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
367 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
368 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
368 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
369 xa
369 xa
370
370
371 diff -r bb948857c743 -r b4560182a3f9 x/a
371 diff -r bb948857c743 -r b4560182a3f9 x/a
372 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
372 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
373 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
373 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
374 @@ -0,0 +1,4 @@
374 @@ -0,0 +1,4 @@
375 +expand $Id$
375 +expand $Id$
376 +do not process $Id:
376 +do not process $Id:
377 +xxx $
377 +xxx $
378 +$Xinfo$
378 +$Xinfo$
379
379
380 % hgweb filediff
380 % hgweb filediff
381 200 Script output follows
381 200 Script output follows
382
382
383
383
384 diff -r ef63ca68695b -r bb948857c743 a
384 diff -r ef63ca68695b -r bb948857c743 a
385 --- a/a Thu Jan 01 00:00:00 1970 +0000
385 --- a/a Thu Jan 01 00:00:00 1970 +0000
386 +++ b/a Thu Jan 01 00:00:02 1970 +0000
386 +++ b/a Thu Jan 01 00:00:02 1970 +0000
387 @@ -1,3 +1,4 @@
387 @@ -1,3 +1,4 @@
388 expand $Id$
388 expand $Id$
389 do not process $Id:
389 do not process $Id:
390 xxx $
390 xxx $
391 +$Xinfo$
391 +$Xinfo$
392
392
393
393
394
394
395
395
396 % errors encountered
396 % errors encountered
397 % merge/resolve
397 % merge/resolve
398 % simplemerge
398 % simplemerge
399 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
400 created new head
400 created new head
401 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
401 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 (branch merge, don't forget to commit)
402 (branch merge, don't forget to commit)
403 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
403 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
404 foo
404 foo
405 % conflict
405 % conflict
406 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
406 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 created new head
407 created new head
408 merging m
408 merging m
409 warning: conflicts during merge.
409 warning: conflicts during merge.
410 merging m failed!
410 merging m failed!
411 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
411 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
412 use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
412 use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
413 % keyword stays outside conflict zone
413 % keyword stays outside conflict zone
414 $Id$
414 $Id$
415 <<<<<<< local
415 <<<<<<< local
416 bar
416 bar
417 =======
417 =======
418 foo
418 foo
419 >>>>>>> other
419 >>>>>>> other
420 % resolve to local
420 % resolve to local
421 $Id: m 41efa6d38e9b Thu, 01 Jan 1970 00:00:00 +0000 test $
421 $Id: m 41efa6d38e9b Thu, 01 Jan 1970 00:00:00 +0000 test $
422 bar
422 bar
423 % test restricted mode with transplant -b
423 % test restricted mode with transplant -b
424 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
424 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
425 marked working directory as branch foo
425 marked working directory as branch foo
426 created new head
426 created new head
427 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
427 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
428 applying 4aa30d025d50
428 applying 4aa30d025d50
429 4aa30d025d50 transplanted to 5a4da427c162
429 4aa30d025d50 transplanted to 5a4da427c162
430 % no expansion in changeset
430 % no expansion in changeset
431 changeset: 11:5a4da427c162
431 changeset: 11:5a4da427c162
432 tag: tip
432 tag: tip
433 parent: 9:41efa6d38e9b
433 parent: 9:41efa6d38e9b
434 user: test
434 user: test
435 date: Thu Jan 01 00:00:00 1970 +0000
435 date: Thu Jan 01 00:00:00 1970 +0000
436 summary: 9foobranch
436 summary: 9foobranch
437
437
438 diff -r 41efa6d38e9b -r 5a4da427c162 a
438 diff -r 41efa6d38e9b -r 5a4da427c162 a
439 --- a/a Thu Jan 01 00:00:00 1970 +0000
439 --- a/a Thu Jan 01 00:00:00 1970 +0000
440 +++ b/a Thu Jan 01 00:00:00 1970 +0000
440 +++ b/a Thu Jan 01 00:00:00 1970 +0000
441 @@ -1,3 +1,4 @@
441 @@ -1,3 +1,4 @@
442 +foobranch
442 +foobranch
443 expand $Id$
443 expand $Id$
444 do not process $Id:
444 do not process $Id:
445 xxx $
445 xxx $
446
446
447 % expansion in file
447 % expansion in file
448 foobranch
448 foobranch
449 expand $Id: a 5a4da427c162 Thu, 01 Jan 1970 00:00:00 +0000 test $
449 expand $Id: a 5a4da427c162 Thu, 01 Jan 1970 00:00:00 +0000 test $
450 % switch off expansion
450 % switch off expansion
451 % kwshrink with unknown file u
451 % kwshrink with unknown file u
452 overwriting a shrinking keywords
452 overwriting a shrinking keywords
453 overwriting m shrinking keywords
453 overwriting m shrinking keywords
454 overwriting x/a shrinking keywords
454 overwriting x/a shrinking keywords
455 % cat
455 % cat
456 expand $Id$
456 expand $Id$
457 do not process $Id:
457 do not process $Id:
458 xxx $
458 xxx $
459 $Xinfo$
459 $Xinfo$
460 ignore $Id$
460 ignore $Id$
461 % hg cat
461 % hg cat
462 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
462 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
463 do not process $Id:
463 do not process $Id:
464 xxx $
464 xxx $
465 $Xinfo: User Name <user@example.com>: firstline $
465 $Xinfo: User Name <user@example.com>: firstline $
466 ignore $Id$
466 ignore $Id$
467 a
467 a
468 % cat
468 % cat
469 expand $Id$
469 expand $Id$
470 do not process $Id:
470 do not process $Id:
471 xxx $
471 xxx $
472 $Xinfo$
472 $Xinfo$
473 ignore $Id$
473 ignore $Id$
474 % hg cat
474 % hg cat
475 expand $Id$
475 expand $Id$
476 do not process $Id:
476 do not process $Id:
477 xxx $
477 xxx $
478 $Xinfo$
478 $Xinfo$
479 ignore $Id$
479 ignore $Id$
480 a
480 a
@@ -1,181 +1,181 b''
1 marked working directory as branch foo
1 marked working directory as branch foo
2 foo
2 foo
3 marked working directory as branch bar
3 marked working directory as branch bar
4 % branch shadowing
4 % branch shadowing
5 abort: a branch of the same name already exists (use 'hg update' to switch to it)
5 abort: a branch of the same name already exists (use 'hg update' to switch to it)
6 marked working directory as branch default
6 marked working directory as branch default
7 % there should be only one default branch head
7 % there should be only one default branch head
8 changeset: 3:bf1bc2f45e83
8 changeset: 3:bf1bc2f45e83
9 tag: tip
9 tag: tip
10 user: test
10 user: test
11 date: Mon Jan 12 13:46:40 1970 +0000
11 date: Mon Jan 12 13:46:40 1970 +0000
12 summary: clear branch name
12 summary: clear branch name
13
13
14 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 foo
15 foo
16 created new head
16 created new head
17 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
18 (branch merge, don't forget to commit)
18 (branch merge, don't forget to commit)
19 foo
19 foo
20 changeset: 5:5f8fb06e083e
20 changeset: 5:5f8fb06e083e
21 branch: foo
21 branch: foo
22 tag: tip
22 tag: tip
23 parent: 4:4909a3732169
23 parent: 4:4909a3732169
24 parent: 3:bf1bc2f45e83
24 parent: 3:bf1bc2f45e83
25 user: test
25 user: test
26 date: Mon Jan 12 13:46:40 1970 +0000
26 date: Mon Jan 12 13:46:40 1970 +0000
27 summary: merge
27 summary: merge
28
28
29 changeset: 4:4909a3732169
29 changeset: 4:4909a3732169
30 branch: foo
30 branch: foo
31 parent: 1:b699b1cec9c2
31 parent: 1:b699b1cec9c2
32 user: test
32 user: test
33 date: Mon Jan 12 13:46:40 1970 +0000
33 date: Mon Jan 12 13:46:40 1970 +0000
34 summary: modify a branch
34 summary: modify a branch
35
35
36 changeset: 3:bf1bc2f45e83
36 changeset: 3:bf1bc2f45e83
37 user: test
37 user: test
38 date: Mon Jan 12 13:46:40 1970 +0000
38 date: Mon Jan 12 13:46:40 1970 +0000
39 summary: clear branch name
39 summary: clear branch name
40
40
41 changeset: 2:67ec16bde7f1
41 changeset: 2:67ec16bde7f1
42 branch: bar
42 branch: bar
43 user: test
43 user: test
44 date: Mon Jan 12 13:46:40 1970 +0000
44 date: Mon Jan 12 13:46:40 1970 +0000
45 summary: change branch name
45 summary: change branch name
46
46
47 changeset: 1:b699b1cec9c2
47 changeset: 1:b699b1cec9c2
48 branch: foo
48 branch: foo
49 user: test
49 user: test
50 date: Mon Jan 12 13:46:40 1970 +0000
50 date: Mon Jan 12 13:46:40 1970 +0000
51 summary: add branch name
51 summary: add branch name
52
52
53 changeset: 0:be8523e69bf8
53 changeset: 0:be8523e69bf8
54 user: test
54 user: test
55 date: Mon Jan 12 13:46:40 1970 +0000
55 date: Mon Jan 12 13:46:40 1970 +0000
56 summary: initial
56 summary: initial
57
57
58 foo 5:5f8fb06e083e
58 foo 5:5f8fb06e083e
59 default 3:bf1bc2f45e83 (inactive)
59 default 3:bf1bc2f45e83 (inactive)
60 bar 2:67ec16bde7f1 (inactive)
60 bar 2:67ec16bde7f1 (inactive)
61 foo
61 foo
62 default
62 default
63 bar
63 bar
64 % test for invalid branch cache
64 % test for invalid branch cache
65 rolling back commit to revision 5
65 rolling back to revision 5 (undo commit)
66 changeset: 4:4909a3732169
66 changeset: 4:4909a3732169
67 branch: foo
67 branch: foo
68 tag: tip
68 tag: tip
69 parent: 1:b699b1cec9c2
69 parent: 1:b699b1cec9c2
70 user: test
70 user: test
71 date: Mon Jan 12 13:46:40 1970 +0000
71 date: Mon Jan 12 13:46:40 1970 +0000
72 summary: modify a branch
72 summary: modify a branch
73
73
74 invalidating branch cache (tip differs)
74 invalidating branch cache (tip differs)
75 changeset: 4:4909a3732169c0c20011c4f4b8fdff4e3d89b23f
75 changeset: 4:4909a3732169c0c20011c4f4b8fdff4e3d89b23f
76 branch: foo
76 branch: foo
77 tag: tip
77 tag: tip
78 parent: 1:b699b1cec9c2966b3700de4fef0dc123cd754c31
78 parent: 1:b699b1cec9c2966b3700de4fef0dc123cd754c31
79 parent: -1:0000000000000000000000000000000000000000
79 parent: -1:0000000000000000000000000000000000000000
80 manifest: 4:d01b250baaa05909152f7ae07d7a649deea0df9a
80 manifest: 4:d01b250baaa05909152f7ae07d7a649deea0df9a
81 user: test
81 user: test
82 date: Mon Jan 12 13:46:40 1970 +0000
82 date: Mon Jan 12 13:46:40 1970 +0000
83 files: a
83 files: a
84 extra: branch=foo
84 extra: branch=foo
85 description:
85 description:
86 modify a branch
86 modify a branch
87
87
88
88
89 4:4909a3732169
89 4:4909a3732169
90 4909a3732169c0c20011c4f4b8fdff4e3d89b23f 4
90 4909a3732169c0c20011c4f4b8fdff4e3d89b23f 4
91 bf1bc2f45e834c75404d0ddab57d53beab56e2f8 default
91 bf1bc2f45e834c75404d0ddab57d53beab56e2f8 default
92 4909a3732169c0c20011c4f4b8fdff4e3d89b23f foo
92 4909a3732169c0c20011c4f4b8fdff4e3d89b23f foo
93 67ec16bde7f1575d523313b9bca000f6a6f12dca bar
93 67ec16bde7f1575d523313b9bca000f6a6f12dca bar
94 % push should update the branch cache
94 % push should update the branch cache
95 % pushing just rev 0
95 % pushing just rev 0
96 be8523e69bf892e25817fc97187516b3c0804ae4 0
96 be8523e69bf892e25817fc97187516b3c0804ae4 0
97 be8523e69bf892e25817fc97187516b3c0804ae4 default
97 be8523e69bf892e25817fc97187516b3c0804ae4 default
98 % pushing everything
98 % pushing everything
99 4909a3732169c0c20011c4f4b8fdff4e3d89b23f 4
99 4909a3732169c0c20011c4f4b8fdff4e3d89b23f 4
100 bf1bc2f45e834c75404d0ddab57d53beab56e2f8 default
100 bf1bc2f45e834c75404d0ddab57d53beab56e2f8 default
101 4909a3732169c0c20011c4f4b8fdff4e3d89b23f foo
101 4909a3732169c0c20011c4f4b8fdff4e3d89b23f foo
102 67ec16bde7f1575d523313b9bca000f6a6f12dca bar
102 67ec16bde7f1575d523313b9bca000f6a6f12dca bar
103 % update with no arguments: tipmost revision of the current branch
103 % update with no arguments: tipmost revision of the current branch
104 bf1bc2f45e83
104 bf1bc2f45e83
105 4909a3732169 (foo) tip
105 4909a3732169 (foo) tip
106 marked working directory as branch foobar
106 marked working directory as branch foobar
107 abort: branch foobar not found
107 abort: branch foobar not found
108 % fastforward merge
108 % fastforward merge
109 marked working directory as branch ff
109 marked working directory as branch ff
110 adding ff
110 adding ff
111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 (branch merge, don't forget to commit)
113 (branch merge, don't forget to commit)
114 foo
114 foo
115 changeset: 6:f0c74f92a385
115 changeset: 6:f0c74f92a385
116 branch: foo
116 branch: foo
117 tag: tip
117 tag: tip
118 parent: 4:4909a3732169
118 parent: 4:4909a3732169
119 parent: 5:c420d2121b71
119 parent: 5:c420d2121b71
120 user: test
120 user: test
121 date: Mon Jan 12 13:46:40 1970 +0000
121 date: Mon Jan 12 13:46:40 1970 +0000
122 summary: Merge ff into foo
122 summary: Merge ff into foo
123
123
124 a
124 a
125 ff
125 ff
126 % test merging, add 3 default heads and one test head
126 % test merging, add 3 default heads and one test head
127 adding a
127 adding a
128 adding b
128 adding b
129 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
129 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
130 adding c
130 adding c
131 created new head
131 created new head
132 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
132 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 adding d
133 adding d
134 created new head
134 created new head
135 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
135 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
136 marked working directory as branch test
136 marked working directory as branch test
137 adding e
137 adding e
138 created new head
138 created new head
139 changeset: 4:3a1e01ed1df4
139 changeset: 4:3a1e01ed1df4
140 branch: test
140 branch: test
141 tag: tip
141 tag: tip
142 parent: 0:cb9a9f314b8b
142 parent: 0:cb9a9f314b8b
143 user: test
143 user: test
144 date: Thu Jan 01 00:00:00 1970 +0000
144 date: Thu Jan 01 00:00:00 1970 +0000
145 summary: e
145 summary: e
146
146
147 changeset: 3:980f7dc84c29
147 changeset: 3:980f7dc84c29
148 parent: 0:cb9a9f314b8b
148 parent: 0:cb9a9f314b8b
149 user: test
149 user: test
150 date: Thu Jan 01 00:00:00 1970 +0000
150 date: Thu Jan 01 00:00:00 1970 +0000
151 summary: d
151 summary: d
152
152
153 changeset: 2:d36c0562f908
153 changeset: 2:d36c0562f908
154 parent: 0:cb9a9f314b8b
154 parent: 0:cb9a9f314b8b
155 user: test
155 user: test
156 date: Thu Jan 01 00:00:00 1970 +0000
156 date: Thu Jan 01 00:00:00 1970 +0000
157 summary: c
157 summary: c
158
158
159 changeset: 1:d2ae7f538514
159 changeset: 1:d2ae7f538514
160 user: test
160 user: test
161 date: Thu Jan 01 00:00:00 1970 +0000
161 date: Thu Jan 01 00:00:00 1970 +0000
162 summary: b
162 summary: b
163
163
164 changeset: 0:cb9a9f314b8b
164 changeset: 0:cb9a9f314b8b
165 user: test
165 user: test
166 date: Thu Jan 01 00:00:00 1970 +0000
166 date: Thu Jan 01 00:00:00 1970 +0000
167 summary: a
167 summary: a
168
168
169 % implicit merge with test branch as parent
169 % implicit merge with test branch as parent
170 abort: branch 'test' has one head - please merge with an explicit rev
170 abort: branch 'test' has one head - please merge with an explicit rev
171 (run 'hg heads' to see all heads)
171 (run 'hg heads' to see all heads)
172 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
172 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 % implicit merge with default branch as parent
173 % implicit merge with default branch as parent
174 abort: branch 'default' has 3 heads - please merge with an explicit rev
174 abort: branch 'default' has 3 heads - please merge with an explicit rev
175 (run 'hg heads .' to see heads)
175 (run 'hg heads .' to see heads)
176 % 3 branch heads, explicit merge required
176 % 3 branch heads, explicit merge required
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
177 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 (branch merge, don't forget to commit)
178 (branch merge, don't forget to commit)
179 % 2 branch heads, implicit merge works
179 % 2 branch heads, implicit merge works
180 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 (branch merge, don't forget to commit)
181 (branch merge, don't forget to commit)
@@ -1,219 +1,219 b''
1 notify extension - hooks for sending email notifications at commit/push time
1 notify extension - hooks for sending email notifications at commit/push time
2
2
3 Subscriptions can be managed through a hgrc file. Default mode is to print
3 Subscriptions can be managed through a hgrc file. Default mode is to print
4 messages to stdout, for testing and configuring.
4 messages to stdout, for testing and configuring.
5
5
6 To use, configure the notify extension and enable it in hgrc like this:
6 To use, configure the notify extension and enable it in hgrc like this:
7
7
8 [extensions]
8 [extensions]
9 notify =
9 notify =
10
10
11 [hooks]
11 [hooks]
12 # one email for each incoming changeset
12 # one email for each incoming changeset
13 incoming.notify = python:hgext.notify.hook
13 incoming.notify = python:hgext.notify.hook
14 # batch emails when many changesets incoming at one time
14 # batch emails when many changesets incoming at one time
15 changegroup.notify = python:hgext.notify.hook
15 changegroup.notify = python:hgext.notify.hook
16
16
17 [notify]
17 [notify]
18 # config items go here
18 # config items go here
19
19
20 Required configuration items:
20 Required configuration items:
21
21
22 config = /path/to/file # file containing subscriptions
22 config = /path/to/file # file containing subscriptions
23
23
24 Optional configuration items:
24 Optional configuration items:
25
25
26 test = True # print messages to stdout for testing
26 test = True # print messages to stdout for testing
27 strip = 3 # number of slashes to strip for url paths
27 strip = 3 # number of slashes to strip for url paths
28 domain = example.com # domain to use if committer missing domain
28 domain = example.com # domain to use if committer missing domain
29 style = ... # style file to use when formatting email
29 style = ... # style file to use when formatting email
30 template = ... # template to use when formatting email
30 template = ... # template to use when formatting email
31 incoming = ... # template to use when run as incoming hook
31 incoming = ... # template to use when run as incoming hook
32 changegroup = ... # template when run as changegroup hook
32 changegroup = ... # template when run as changegroup hook
33 maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
33 maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
34 maxsubject = 67 # truncate subject line longer than this
34 maxsubject = 67 # truncate subject line longer than this
35 diffstat = True # add a diffstat before the diff content
35 diffstat = True # add a diffstat before the diff content
36 sources = serve # notify if source of incoming changes in this list
36 sources = serve # notify if source of incoming changes in this list
37 # (serve == ssh or http, push, pull, bundle)
37 # (serve == ssh or http, push, pull, bundle)
38 merge = False # send notification for merges (default True)
38 merge = False # send notification for merges (default True)
39 [email]
39 [email]
40 from = user@host.com # email address to send as if none given
40 from = user@host.com # email address to send as if none given
41 [web]
41 [web]
42 baseurl = http://hgserver/... # root of hg web site for browsing commits
42 baseurl = http://hgserver/... # root of hg web site for browsing commits
43
43
44 The notify config file has same format as a regular hgrc file. It has two
44 The notify config file has same format as a regular hgrc file. It has two
45 sections so you can express subscriptions in whatever way is handier for you.
45 sections so you can express subscriptions in whatever way is handier for you.
46
46
47 [usersubs]
47 [usersubs]
48 # key is subscriber email, value is ","-separated list of glob patterns
48 # key is subscriber email, value is ","-separated list of glob patterns
49 user@host = pattern
49 user@host = pattern
50
50
51 [reposubs]
51 [reposubs]
52 # key is glob pattern, value is ","-separated list of subscriber emails
52 # key is glob pattern, value is ","-separated list of subscriber emails
53 pattern = user@host
53 pattern = user@host
54
54
55 Glob patterns are matched against path to repository root.
55 Glob patterns are matched against path to repository root.
56
56
57 If you like, you can put notify config file in repository that users can push
57 If you like, you can put notify config file in repository that users can push
58 changes to, they can manage their own subscriptions.
58 changes to, they can manage their own subscriptions.
59
59
60 no commands defined
60 no commands defined
61 % commit
61 % commit
62 adding a
62 adding a
63 % clone
63 % clone
64 updating to branch default
64 updating to branch default
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
65 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 % commit
66 % commit
67 % pull (minimal config)
67 % pull (minimal config)
68 pulling from ../a
68 pulling from ../a
69 searching for changes
69 searching for changes
70 adding changesets
70 adding changesets
71 adding manifests
71 adding manifests
72 adding file changes
72 adding file changes
73 added 1 changesets with 1 changes to 1 files
73 added 1 changesets with 1 changes to 1 files
74 Content-Type: text/plain; charset="us-ascii"
74 Content-Type: text/plain; charset="us-ascii"
75 MIME-Version: 1.0
75 MIME-Version: 1.0
76 Content-Transfer-Encoding: 7bit
76 Content-Transfer-Encoding: 7bit
77 Date:
77 Date:
78 Subject: changeset in test-notify/b: b
78 Subject: changeset in test-notify/b: b
79 From: test
79 From: test
80 X-Hg-Notification: changeset 0647d048b600
80 X-Hg-Notification: changeset 0647d048b600
81 Message-Id:
81 Message-Id:
82 To: baz, foo@bar
82 To: baz, foo@bar
83
83
84 changeset 0647d048b600 in test-notify/b
84 changeset 0647d048b600 in test-notify/b
85 details: test-notify/b?cmd=changeset;node=0647d048b600
85 details: test-notify/b?cmd=changeset;node=0647d048b600
86 description: b
86 description: b
87
87
88 diffs (6 lines):
88 diffs (6 lines):
89
89
90 diff -r cb9a9f314b8b -r 0647d048b600 a
90 diff -r cb9a9f314b8b -r 0647d048b600 a
91 --- a/a Thu Jan 01 00:00:00 1970 +0000
91 --- a/a Thu Jan 01 00:00:00 1970 +0000
92 +++ b/a Thu Jan 01 00:00:01 1970 +0000
92 +++ b/a Thu Jan 01 00:00:01 1970 +0000
93 @@ -1,1 +1,2 @@
93 @@ -1,1 +1,2 @@
94 a
94 a
95 +a
95 +a
96 (run 'hg update' to get a working copy)
96 (run 'hg update' to get a working copy)
97 % fail for config file is missing
97 % fail for config file is missing
98 rolling back pull to revision 1
98 rolling back to revision 1 (undo pull)
99 pull failed
99 pull failed
100 % pull
100 % pull
101 rolling back pull to revision 1
101 rolling back to revision 1 (undo pull)
102 pulling from ../a
102 pulling from ../a
103 searching for changes
103 searching for changes
104 adding changesets
104 adding changesets
105 adding manifests
105 adding manifests
106 adding file changes
106 adding file changes
107 added 1 changesets with 1 changes to 1 files
107 added 1 changesets with 1 changes to 1 files
108 Content-Type: text/plain; charset="us-ascii"
108 Content-Type: text/plain; charset="us-ascii"
109 MIME-Version: 1.0
109 MIME-Version: 1.0
110 Content-Transfer-Encoding: 7bit
110 Content-Transfer-Encoding: 7bit
111 X-Test: foo
111 X-Test: foo
112 Date:
112 Date:
113 Subject: b
113 Subject: b
114 From: test@test.com
114 From: test@test.com
115 X-Hg-Notification: changeset 0647d048b600
115 X-Hg-Notification: changeset 0647d048b600
116 Message-Id:
116 Message-Id:
117 To: baz@test.com, foo@bar
117 To: baz@test.com, foo@bar
118
118
119 changeset 0647d048b600
119 changeset 0647d048b600
120 description:
120 description:
121 b
121 b
122 diffs (6 lines):
122 diffs (6 lines):
123
123
124 diff -r cb9a9f314b8b -r 0647d048b600 a
124 diff -r cb9a9f314b8b -r 0647d048b600 a
125 --- a/a Thu Jan 01 00:00:00 1970 +0000
125 --- a/a Thu Jan 01 00:00:00 1970 +0000
126 +++ b/a Thu Jan 01 00:00:01 1970 +0000
126 +++ b/a Thu Jan 01 00:00:01 1970 +0000
127 @@ -1,1 +1,2 @@
127 @@ -1,1 +1,2 @@
128 a
128 a
129 +a
129 +a
130 (run 'hg update' to get a working copy)
130 (run 'hg update' to get a working copy)
131 % pull
131 % pull
132 rolling back pull to revision 1
132 rolling back to revision 1 (undo pull)
133 pulling from ../a
133 pulling from ../a
134 searching for changes
134 searching for changes
135 adding changesets
135 adding changesets
136 adding manifests
136 adding manifests
137 adding file changes
137 adding file changes
138 added 1 changesets with 1 changes to 1 files
138 added 1 changesets with 1 changes to 1 files
139 Content-Type: text/plain; charset="us-ascii"
139 Content-Type: text/plain; charset="us-ascii"
140 MIME-Version: 1.0
140 MIME-Version: 1.0
141 Content-Transfer-Encoding: 7bit
141 Content-Transfer-Encoding: 7bit
142 X-Test: foo
142 X-Test: foo
143 Date:
143 Date:
144 Subject: b
144 Subject: b
145 From: test@test.com
145 From: test@test.com
146 X-Hg-Notification: changeset 0647d048b600
146 X-Hg-Notification: changeset 0647d048b600
147 Message-Id:
147 Message-Id:
148 To: baz@test.com, foo@bar
148 To: baz@test.com, foo@bar
149
149
150 changeset 0647d048b600
150 changeset 0647d048b600
151 description:
151 description:
152 b
152 b
153 diffstat:
153 diffstat:
154
154
155 a | 1 +
155 a | 1 +
156 1 files changed, 1 insertions(+), 0 deletions(-)
156 1 files changed, 1 insertions(+), 0 deletions(-)
157
157
158 diffs (6 lines):
158 diffs (6 lines):
159
159
160 diff -r cb9a9f314b8b -r 0647d048b600 a
160 diff -r cb9a9f314b8b -r 0647d048b600 a
161 --- a/a Thu Jan 01 00:00:00 1970 +0000
161 --- a/a Thu Jan 01 00:00:00 1970 +0000
162 +++ b/a Thu Jan 01 00:00:01 1970 +0000
162 +++ b/a Thu Jan 01 00:00:01 1970 +0000
163 @@ -1,1 +1,2 @@
163 @@ -1,1 +1,2 @@
164 a
164 a
165 +a
165 +a
166 (run 'hg update' to get a working copy)
166 (run 'hg update' to get a working copy)
167 % test merge
167 % test merge
168 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 created new head
169 created new head
170 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 (branch merge, don't forget to commit)
171 (branch merge, don't forget to commit)
172 pulling from ../a
172 pulling from ../a
173 searching for changes
173 searching for changes
174 adding changesets
174 adding changesets
175 adding manifests
175 adding manifests
176 adding file changes
176 adding file changes
177 added 2 changesets with 0 changes to 0 files
177 added 2 changesets with 0 changes to 0 files
178 Content-Type: text/plain; charset="us-ascii"
178 Content-Type: text/plain; charset="us-ascii"
179 MIME-Version: 1.0
179 MIME-Version: 1.0
180 Content-Transfer-Encoding: 7bit
180 Content-Transfer-Encoding: 7bit
181 X-Test: foo
181 X-Test: foo
182 Date:
182 Date:
183 Subject: adda2
183 Subject: adda2
184 From: test@test.com
184 From: test@test.com
185 X-Hg-Notification: changeset 0a184ce6067f
185 X-Hg-Notification: changeset 0a184ce6067f
186 Message-Id:
186 Message-Id:
187 To: baz@test.com, foo@bar
187 To: baz@test.com, foo@bar
188
188
189 changeset 0a184ce6067f
189 changeset 0a184ce6067f
190 description:
190 description:
191 adda2
191 adda2
192 diffstat:
192 diffstat:
193
193
194 a | 1 +
194 a | 1 +
195 1 files changed, 1 insertions(+), 0 deletions(-)
195 1 files changed, 1 insertions(+), 0 deletions(-)
196
196
197 diffs (6 lines):
197 diffs (6 lines):
198
198
199 diff -r cb9a9f314b8b -r 0a184ce6067f a
199 diff -r cb9a9f314b8b -r 0a184ce6067f a
200 --- a/a Thu Jan 01 00:00:00 1970 +0000
200 --- a/a Thu Jan 01 00:00:00 1970 +0000
201 +++ b/a Thu Jan 01 00:00:02 1970 +0000
201 +++ b/a Thu Jan 01 00:00:02 1970 +0000
202 @@ -1,1 +1,2 @@
202 @@ -1,1 +1,2 @@
203 a
203 a
204 +a
204 +a
205 Content-Type: text/plain; charset="us-ascii"
205 Content-Type: text/plain; charset="us-ascii"
206 MIME-Version: 1.0
206 MIME-Version: 1.0
207 Content-Transfer-Encoding: 7bit
207 Content-Transfer-Encoding: 7bit
208 X-Test: foo
208 X-Test: foo
209 Date:
209 Date:
210 Subject: merge
210 Subject: merge
211 From: test@test.com
211 From: test@test.com
212 X-Hg-Notification: changeset 22c88b85aa27
212 X-Hg-Notification: changeset 22c88b85aa27
213 Message-Id:
213 Message-Id:
214 To: baz@test.com, foo@bar
214 To: baz@test.com, foo@bar
215
215
216 changeset 22c88b85aa27
216 changeset 22c88b85aa27
217 description:
217 description:
218 merge
218 merge
219 (run 'hg update' to get a working copy)
219 (run 'hg update' to get a working copy)
@@ -1,42 +1,42 b''
1 changeset: 2:effea6de0384
1 changeset: 2:effea6de0384
2 tag: tip
2 tag: tip
3 parent: 0:bbd179dfa0a7
3 parent: 0:bbd179dfa0a7
4 user: test
4 user: test
5 date: Thu Jan 01 00:00:00 1970 +0000
5 date: Thu Jan 01 00:00:00 1970 +0000
6 summary: add bar
6 summary: add bar
7
7
8 changeset: 1:ed1b79f46b9a
8 changeset: 1:ed1b79f46b9a
9 user: test
9 user: test
10 date: Thu Jan 01 00:00:00 1970 +0000
10 date: Thu Jan 01 00:00:00 1970 +0000
11 summary: change foo
11 summary: change foo
12
12
13 changeset: 0:bbd179dfa0a7
13 changeset: 0:bbd179dfa0a7
14 user: test
14 user: test
15 date: Thu Jan 01 00:00:00 1970 +0000
15 date: Thu Jan 01 00:00:00 1970 +0000
16 summary: add foo
16 summary: add foo
17
17
18 % pull a missing revision
18 % pull a missing revision
19 abort: unknown revision 'missing'!
19 abort: unknown revision 'missing'!
20 % pull multiple revisions with update
20 % pull multiple revisions with update
21 0:bbd179dfa0a7
21 0:bbd179dfa0a7
22 rolling back pull to revision 0
22 rolling back to revision 0 (undo pull)
23 % pull -r 0
23 % pull -r 0
24 changeset: 0:bbd179dfa0a7
24 changeset: 0:bbd179dfa0a7
25 tag: tip
25 tag: tip
26 user: test
26 user: test
27 date: Thu Jan 01 00:00:00 1970 +0000
27 date: Thu Jan 01 00:00:00 1970 +0000
28 summary: add foo
28 summary: add foo
29
29
30 % pull -r 1
30 % pull -r 1
31 changeset: 1:ed1b79f46b9a
31 changeset: 1:ed1b79f46b9a
32 tag: tip
32 tag: tip
33 user: test
33 user: test
34 date: Thu Jan 01 00:00:00 1970 +0000
34 date: Thu Jan 01 00:00:00 1970 +0000
35 summary: change foo
35 summary: change foo
36
36
37 changeset: 0:bbd179dfa0a7
37 changeset: 0:bbd179dfa0a7
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: add foo
40 summary: add foo
41
41
42 % pull -r 1 again
42 % pull -r 1 again
@@ -1,38 +1,38 b''
1 adding a
1 adding a
2 updating to branch default
2 updating to branch default
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 % expect ssl error
4 % expect ssl error
5 pushing to http://localhost:$HGPORT/
5 pushing to http://localhost:$HGPORT/
6 searching for changes
6 searching for changes
7 remote: ssl required
7 remote: ssl required
8 % serve errors
8 % serve errors
9 % expect authorization error
9 % expect authorization error
10 abort: authorization failed
10 abort: authorization failed
11 pushing to http://localhost:$HGPORT/
11 pushing to http://localhost:$HGPORT/
12 searching for changes
12 searching for changes
13 % serve errors
13 % serve errors
14 % expect authorization error: must have authorized user
14 % expect authorization error: must have authorized user
15 abort: authorization failed
15 abort: authorization failed
16 pushing to http://localhost:$HGPORT/
16 pushing to http://localhost:$HGPORT/
17 searching for changes
17 searching for changes
18 % serve errors
18 % serve errors
19 % expect success
19 % expect success
20 pushing to http://localhost:$HGPORT/
20 pushing to http://localhost:$HGPORT/
21 searching for changes
21 searching for changes
22 remote: adding changesets
22 remote: adding changesets
23 remote: adding manifests
23 remote: adding manifests
24 remote: adding file changes
24 remote: adding file changes
25 remote: added 1 changesets with 1 changes to 1 files
25 remote: added 1 changesets with 1 changes to 1 files
26 % serve errors
26 % serve errors
27 changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_URL=remote:http
27 changegroup hook: HG_NODE=ba677d0156c1196c1a699fa53f390dcfc3ce3872 HG_SOURCE=serve HG_URL=remote:http
28 rolling back serve to revision 1
28 rolling back to revision 1 (undo serve)
29 % expect authorization error: all users denied
29 % expect authorization error: all users denied
30 abort: authorization failed
30 abort: authorization failed
31 pushing to http://localhost:$HGPORT/
31 pushing to http://localhost:$HGPORT/
32 searching for changes
32 searching for changes
33 % serve errors
33 % serve errors
34 % expect authorization error: some users denied, users must be authenticated
34 % expect authorization error: some users denied, users must be authenticated
35 abort: authorization failed
35 abort: authorization failed
36 pushing to http://localhost:$HGPORT/
36 pushing to http://localhost:$HGPORT/
37 searching for changes
37 searching for changes
38 % serve errors
38 % serve errors
@@ -1,43 +1,43 b''
1 % create source repository
1 % create source repository
2 adding a
2 adding a
3 % fork source repository
3 % fork source repository
4 updating to branch default
4 updating to branch default
5 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
6 adding b
6 adding b
7 % update source repository
7 % update source repository
8 % merge repositories
8 % merge repositories
9 pulling from ../t2
9 pulling from ../t2
10 searching for changes
10 searching for changes
11 adding changesets
11 adding changesets
12 adding manifests
12 adding manifests
13 adding file changes
13 adding file changes
14 added 1 changesets with 1 changes to 1 files (+1 heads)
14 added 1 changesets with 1 changes to 1 files (+1 heads)
15 (run 'hg heads' to see heads, 'hg merge' to merge)
15 (run 'hg heads' to see heads, 'hg merge' to merge)
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 (branch merge, don't forget to commit)
17 (branch merge, don't forget to commit)
18 M b
18 M b
19 % rename b as c
19 % rename b as c
20 A c
20 A c
21 R b
21 R b
22 % rename back c as b
22 % rename back c as b
23 M b
23 M b
24 % test issue 1476
24 % test issue 1476
25 adding a
25 adding a
26 adding b1
26 adding b1
27 adding b2
27 adding b2
28 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
28 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
29 adding c1
29 adding c1
30 adding c2
30 adding c2
31 created new head
31 created new head
32 % merge heads
32 % merge heads
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 (branch merge, don't forget to commit)
34 (branch merge, don't forget to commit)
35 % commit issue 1476
35 % commit issue 1476
36 copies: c2 (c1)
36 copies: c2 (c1)
37 rolling back commit to revision 3
37 rolling back to revision 3 (undo commit)
38 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
38 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
39 % merge heads again
39 % merge heads again
40 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 (branch merge, don't forget to commit)
41 (branch merge, don't forget to commit)
42 % commit issue 1476 with a rename on the other side
42 % commit issue 1476 with a rename on the other side
43 copies: b2 (b1)
43 copies: b2 (b1)
@@ -1,43 +1,43 b''
1 checking changesets
1 checking changesets
2 checking manifests
2 checking manifests
3 crosschecking files in changesets and manifests
3 crosschecking files in changesets and manifests
4 checking files
4 checking files
5 1 files, 1 changesets, 1 total revisions
5 1 files, 1 changesets, 1 total revisions
6 changeset: 0:0acdaf898367
6 changeset: 0:0acdaf898367
7 tag: tip
7 tag: tip
8 user: test
8 user: test
9 date: Mon Jan 12 13:46:40 1970 +0000
9 date: Mon Jan 12 13:46:40 1970 +0000
10 summary: test
10 summary: test
11
11
12 rolling back commit to revision 0
12 rolling back to revision 0 (undo commit)
13 checking changesets
13 checking changesets
14 checking manifests
14 checking manifests
15 crosschecking files in changesets and manifests
15 crosschecking files in changesets and manifests
16 checking files
16 checking files
17 0 files, 0 changesets, 0 total revisions
17 0 files, 0 changesets, 0 total revisions
18 A a
18 A a
19 % Test issue 902
19 % Test issue 902
20 marked working directory as branch test
20 marked working directory as branch test
21 rolling back commit to revision 0
21 rolling back to revision 0 (undo commit)
22 default
22 default
23 % Test issue 1635 (commit message saved)
23 % Test issue 1635 (commit message saved)
24 .hg/last-message.txt:
24 .hg/last-message.txt:
25 test2
25 test2
26 % Test rollback of hg before issue 902 was fixed
26 % Test rollback of hg before issue 902 was fixed
27 marked working directory as branch test
27 marked working directory as branch test
28 rolling back commit to revision 0
28 rolling back to revision 0 (undo commit)
29 Named branch could not be reset, current branch still is: test
29 Named branch could not be reset, current branch still is: test
30 test
30 test
31 % rollback by pretxncommit saves commit message (issue 1635)
31 % rollback by pretxncommit saves commit message (issue 1635)
32 transaction abort!
32 transaction abort!
33 rollback completed
33 rollback completed
34 abort: pretxncommit hook exited ...
34 abort: pretxncommit hook exited ...
35 .hg/last-message.txt:
35 .hg/last-message.txt:
36 precious commit message
36 precious commit message
37 % same thing, but run $EDITOR
37 % same thing, but run $EDITOR
38 transaction abort!
38 transaction abort!
39 rollback completed
39 rollback completed
40 note: commit message saved in .hg/last-message.txt
40 note: commit message saved in .hg/last-message.txt
41 abort: pretxncommit hook exited ...
41 abort: pretxncommit hook exited ...
42 .hg/last-message.txt:
42 .hg/last-message.txt:
43 another precious commit message
43 another precious commit message
@@ -1,153 +1,153 b''
1 % setup
1 % setup
2 no tag cache
2 no tag cache
3 000000000000 tip
3 000000000000 tip
4 no tag cache
4 no tag cache
5 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
6 acb14030fe0a tip
6 acb14030fe0a tip
7 tag cache exists
7 tag cache exists
8 % create local tag with long name
8 % create local tag with long name
9 tip 0:acb14030fe0a
9 tip 0:acb14030fe0a
10 This is a local tag with a really long name! 0:acb14030fe0a
10 This is a local tag with a really long name! 0:acb14030fe0a
11 % create a tag behind hg's back
11 % create a tag behind hg's back
12 acb14030fe0a21b60322c440ad2d20cf7685a376 first
12 acb14030fe0a21b60322c440ad2d20cf7685a376 first
13 tip 1:b9154636be93
13 tip 1:b9154636be93
14 first 0:acb14030fe0a
14 first 0:acb14030fe0a
15 b9154636be93 tip
15 b9154636be93 tip
16 % identify with cold cache
16 % identify with cold cache
17 b9154636be93 tip
17 b9154636be93 tip
18 % identify with unwritable cache
18 % identify with unwritable cache
19 b9154636be93 tip
19 b9154636be93 tip
20 % create a branch
20 % create a branch
21 M a
21 M a
22 b9154636be93+ tip
22 b9154636be93+ tip
23 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
24 acb14030fe0a+ first
24 acb14030fe0a+ first
25 acb14030fe0a+ first
25 acb14030fe0a+ first
26 M a
26 M a
27 created new head
27 created new head
28 c8edf04160c7 tip
28 c8edf04160c7 tip
29 % merge the two heads
29 % merge the two heads
30 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 (branch merge, don't forget to commit)
31 (branch merge, don't forget to commit)
32 c8edf04160c7+b9154636be93+ tip
32 c8edf04160c7+b9154636be93+ tip
33 M .hgtags
33 M .hgtags
34 % create fake head, make sure tag not visible afterwards
34 % create fake head, make sure tag not visible afterwards
35 tip 6:35ff301afafe
35 tip 6:35ff301afafe
36 first 0:acb14030fe0a
36 first 0:acb14030fe0a
37 % add invalid tags
37 % add invalid tags
38 committing .hgtags:
38 committing .hgtags:
39 acb14030fe0a21b60322c440ad2d20cf7685a376 first
39 acb14030fe0a21b60322c440ad2d20cf7685a376 first
40 spam
40 spam
41
41
42 foo bar
42 foo bar
43 % report tag parse error on other head
43 % report tag parse error on other head
44 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 created new head
45 created new head
46 .hgtags@75d9f02dfe28, line 2: cannot parse entry
46 .hgtags@75d9f02dfe28, line 2: cannot parse entry
47 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
47 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
48 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
48 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
49 tip 8:c4be69a18c11
49 tip 8:c4be69a18c11
50 first 0:acb14030fe0a
50 first 0:acb14030fe0a
51 changeset: 8:c4be69a18c11
51 changeset: 8:c4be69a18c11
52 tag: tip
52 tag: tip
53 parent: 3:ac5e980c4dc0
53 parent: 3:ac5e980c4dc0
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: head
56 summary: head
57
57
58 % test tag precedence rules
58 % test tag precedence rules
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 created new head
61 created new head
62 tip 4:0c192d7d5e6b
62 tip 4:0c192d7d5e6b
63 bar 1:78391a272241
63 bar 1:78391a272241
64 tip 4:0c192d7d5e6b
64 tip 4:0c192d7d5e6b
65 bar 1:78391a272241
65 bar 1:78391a272241
66 % detailed dump of tag info
66 % detailed dump of tag info
67 heads:
67 heads:
68 4:0c192d7d5e6b
68 4:0c192d7d5e6b
69 3:6fa450212aeb
69 3:6fa450212aeb
70 2:7a94127795a3
70 2:7a94127795a3
71 rev 2: .hgtags:
71 rev 2: .hgtags:
72 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
72 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
73 rev 3: .hgtags:
73 rev 3: .hgtags:
74 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
74 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
75 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
75 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
76 78391a272241d70354aa14c874552cad6b51bb42 bar
76 78391a272241d70354aa14c874552cad6b51bb42 bar
77 rev 4: .hgtags:
77 rev 4: .hgtags:
78 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
78 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
79 .hg/tags.cache:
79 .hg/tags.cache:
80 4 0c192d7d5e6b78a714de54a2e9627952a877e25a 0c04f2a8af31de17fab7422878ee5a2dadbc943d
80 4 0c192d7d5e6b78a714de54a2e9627952a877e25a 0c04f2a8af31de17fab7422878ee5a2dadbc943d
81 3 6fa450212aeb2a21ed616a54aea39a4a27894cd7 7d3b718c964ef37b89e550ebdafd5789e76ce1b0
81 3 6fa450212aeb2a21ed616a54aea39a4a27894cd7 7d3b718c964ef37b89e550ebdafd5789e76ce1b0
82 2 7a94127795a33c10a370c93f731fd9fea0b79af6 0c04f2a8af31de17fab7422878ee5a2dadbc943d
82 2 7a94127795a33c10a370c93f731fd9fea0b79af6 0c04f2a8af31de17fab7422878ee5a2dadbc943d
83
83
84 78391a272241d70354aa14c874552cad6b51bb42 bar
84 78391a272241d70354aa14c874552cad6b51bb42 bar
85 % test tag removal
85 % test tag removal
86 changeset: 5:5f6e8655b1c7
86 changeset: 5:5f6e8655b1c7
87 tag: tip
87 tag: tip
88 user: test
88 user: test
89 date: Thu Jan 01 00:00:00 1970 +0000
89 date: Thu Jan 01 00:00:00 1970 +0000
90 files: .hgtags
90 files: .hgtags
91 description:
91 description:
92 Removed tag bar
92 Removed tag bar
93
93
94
94
95 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
95 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
96 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
96 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
97 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
97 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
98 @@ -1,1 +1,3 @@
98 @@ -1,1 +1,3 @@
99 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
99 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
100 +78391a272241d70354aa14c874552cad6b51bb42 bar
100 +78391a272241d70354aa14c874552cad6b51bb42 bar
101 +0000000000000000000000000000000000000000 bar
101 +0000000000000000000000000000000000000000 bar
102
102
103 tip 5:5f6e8655b1c7
103 tip 5:5f6e8655b1c7
104 tip 5:5f6e8655b1c7
104 tip 5:5f6e8655b1c7
105 % remove nonexistent tag
105 % remove nonexistent tag
106 abort: tag 'foobar' does not exist
106 abort: tag 'foobar' does not exist
107 changeset: 5:5f6e8655b1c7
107 changeset: 5:5f6e8655b1c7
108 tag: tip
108 tag: tip
109 user: test
109 user: test
110 date: Thu Jan 01 00:00:00 1970 +0000
110 date: Thu Jan 01 00:00:00 1970 +0000
111 summary: Removed tag bar
111 summary: Removed tag bar
112
112
113 % rollback undoes tag operation
113 % rollback undoes tag operation
114 rolling back commit to revision 5
114 rolling back to revision 5 (undo commit)
115 tip 4:0c192d7d5e6b
115 tip 4:0c192d7d5e6b
116 bar 1:78391a272241
116 bar 1:78391a272241
117 tip 4:0c192d7d5e6b
117 tip 4:0c192d7d5e6b
118 bar 1:78391a272241
118 bar 1:78391a272241
119 % test tag rank
119 % test tag rank
120 tip 5:85f05169d91d
120 tip 5:85f05169d91d
121 bar 0:bbd179dfa0a7
121 bar 0:bbd179dfa0a7
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 created new head
123 created new head
124 tip 6:735c3ca72986
124 tip 6:735c3ca72986
125 bar 0:bbd179dfa0a7
125 bar 0:bbd179dfa0a7
126 % don't allow moving tag without -f
126 % don't allow moving tag without -f
127 abort: tag 'bar' already exists (use -f to force)
127 abort: tag 'bar' already exists (use -f to force)
128 tip 6:735c3ca72986
128 tip 6:735c3ca72986
129 bar 0:bbd179dfa0a7
129 bar 0:bbd179dfa0a7
130 % strip 1: expose an old head
130 % strip 1: expose an old head
131 tip 5:735c3ca72986
131 tip 5:735c3ca72986
132 bar 1:78391a272241
132 bar 1:78391a272241
133 tip 5:735c3ca72986
133 tip 5:735c3ca72986
134 bar 1:78391a272241
134 bar 1:78391a272241
135 % strip 2: destroy whole branch, no old head exposed
135 % strip 2: destroy whole branch, no old head exposed
136 tip 4:735c3ca72986
136 tip 4:735c3ca72986
137 bar 0:bbd179dfa0a7
137 bar 0:bbd179dfa0a7
138 tip 4:735c3ca72986
138 tip 4:735c3ca72986
139 bar 0:bbd179dfa0a7
139 bar 0:bbd179dfa0a7
140 % test tag rank with 3 heads
140 % test tag rank with 3 heads
141 adding foo
141 adding foo
142 tip 3:197c21bbbf2c
142 tip 3:197c21bbbf2c
143 bar 2:6fa450212aeb
143 bar 2:6fa450212aeb
144 % bar should still point to rev 2
144 % bar should still point to rev 2
145 tip 4:3b4b14ed0202
145 tip 4:3b4b14ed0202
146 bar 2:6fa450212aeb
146 bar 2:6fa450212aeb
147 % remove local as global and global as local
147 % remove local as global and global as local
148 adding foo
148 adding foo
149 abort: tag 'localtag' is not a global tag
149 abort: tag 'localtag' is not a global tag
150 abort: tag 'globaltag' is not a local tag
150 abort: tag 'globaltag' is not a local tag
151 tip 1:a0b6fe111088
151 tip 1:a0b6fe111088
152 localtag 0:bbd179dfa0a7 local
152 localtag 0:bbd179dfa0a7 local
153 globaltag 0:bbd179dfa0a7
153 globaltag 0:bbd179dfa0a7
@@ -1,148 +1,148 b''
1 marked working directory as branch foo
1 marked working directory as branch foo
2 % clone repo#foo
2 % clone repo#foo
3 requesting all changes
3 requesting all changes
4 adding changesets
4 adding changesets
5 adding manifests
5 adding manifests
6 adding file changes
6 adding file changes
7 added 2 changesets with 2 changes to 1 files
7 added 2 changesets with 2 changes to 1 files
8 updating to branch foo
8 updating to branch foo
9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 % heads
10 % heads
11 changeset: 1:cd2a86ecc814
11 changeset: 1:cd2a86ecc814
12 branch: foo
12 branch: foo
13 tag: tip
13 tag: tip
14 user: test
14 user: test
15 date: Thu Jan 01 00:00:00 1970 +0000
15 date: Thu Jan 01 00:00:00 1970 +0000
16 summary: change a
16 summary: change a
17
17
18 changeset: 0:1f0dee641bb7
18 changeset: 0:1f0dee641bb7
19 user: test
19 user: test
20 date: Thu Jan 01 00:00:00 1970 +0000
20 date: Thu Jan 01 00:00:00 1970 +0000
21 summary: add a
21 summary: add a
22
22
23 % parents
23 % parents
24 changeset: 1:cd2a86ecc814
24 changeset: 1:cd2a86ecc814
25 branch: foo
25 branch: foo
26 tag: tip
26 tag: tip
27 user: test
27 user: test
28 date: Thu Jan 01 00:00:00 1970 +0000
28 date: Thu Jan 01 00:00:00 1970 +0000
29 summary: change a
29 summary: change a
30
30
31 [paths]
31 [paths]
32 default = #foo
32 default = #foo
33
33
34 % changing original repo
34 % changing original repo
35 changeset: 3:4cd725637392
35 changeset: 3:4cd725637392
36 tag: tip
36 tag: tip
37 parent: 0:1f0dee641bb7
37 parent: 0:1f0dee641bb7
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: add bar
40 summary: add bar
41
41
42 changeset: 2:faba9097cad4
42 changeset: 2:faba9097cad4
43 branch: foo
43 branch: foo
44 user: test
44 user: test
45 date: Thu Jan 01 00:00:00 1970 +0000
45 date: Thu Jan 01 00:00:00 1970 +0000
46 summary: new head of branch foo
46 summary: new head of branch foo
47
47
48 changeset: 1:cd2a86ecc814
48 changeset: 1:cd2a86ecc814
49 branch: foo
49 branch: foo
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:00 1970 +0000
51 date: Thu Jan 01 00:00:00 1970 +0000
52 summary: change a
52 summary: change a
53
53
54 changeset: 0:1f0dee641bb7
54 changeset: 0:1f0dee641bb7
55 user: test
55 user: test
56 date: Thu Jan 01 00:00:00 1970 +0000
56 date: Thu Jan 01 00:00:00 1970 +0000
57 summary: add a
57 summary: add a
58
58
59
59
60 % outgoing
60 % outgoing
61 2:faba9097cad4
61 2:faba9097cad4
62
62
63 % push
63 % push
64 changeset: 2:faba9097cad4
64 changeset: 2:faba9097cad4
65 branch: foo
65 branch: foo
66 tag: tip
66 tag: tip
67 user: test
67 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
68 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: new head of branch foo
69 summary: new head of branch foo
70
70
71 changeset: 0:1f0dee641bb7
71 changeset: 0:1f0dee641bb7
72 user: test
72 user: test
73 date: Thu Jan 01 00:00:00 1970 +0000
73 date: Thu Jan 01 00:00:00 1970 +0000
74 summary: add a
74 summary: add a
75
75
76
76
77 % rolling back
77 % rolling back
78 rolling back push to revision 2
78 rolling back to revision 2 (undo push)
79 % incoming
79 % incoming
80 2:faba9097cad4
80 2:faba9097cad4
81 % pull
81 % pull
82 changeset: 2:faba9097cad4
82 changeset: 2:faba9097cad4
83 branch: foo
83 branch: foo
84 tag: tip
84 tag: tip
85 user: test
85 user: test
86 date: Thu Jan 01 00:00:00 1970 +0000
86 date: Thu Jan 01 00:00:00 1970 +0000
87 summary: new head of branch foo
87 summary: new head of branch foo
88
88
89 changeset: 0:1f0dee641bb7
89 changeset: 0:1f0dee641bb7
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: add a
92 summary: add a
93
93
94
94
95 % pull should not have updated
95 % pull should not have updated
96 1:cd2a86ecc814
96 1:cd2a86ecc814
97 % going back to the default branch
97 % going back to the default branch
98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 changeset: 0:1f0dee641bb7
99 changeset: 0:1f0dee641bb7
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:00 1970 +0000
101 date: Thu Jan 01 00:00:00 1970 +0000
102 summary: add a
102 summary: add a
103
103
104 % no new revs, no update
104 % no new revs, no update
105 0:1f0dee641bb7
105 0:1f0dee641bb7
106 % rollback
106 % rollback
107 rolling back pull to revision 2
107 rolling back to revision 2 (undo pull)
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 0:1f0dee641bb7
109 0:1f0dee641bb7
110 % pull -u takes us back to branch foo
110 % pull -u takes us back to branch foo
111 changeset: 2:faba9097cad4
111 changeset: 2:faba9097cad4
112 branch: foo
112 branch: foo
113 tag: tip
113 tag: tip
114 user: test
114 user: test
115 date: Thu Jan 01 00:00:00 1970 +0000
115 date: Thu Jan 01 00:00:00 1970 +0000
116 summary: new head of branch foo
116 summary: new head of branch foo
117
117
118 % rollback
118 % rollback
119 rolling back pull to revision 2
119 rolling back to revision 2 (undo pull)
120 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 % parents
121 % parents
122 0:1f0dee641bb7
122 0:1f0dee641bb7
123 % heads
123 % heads
124 1:cd2a86ecc814
124 1:cd2a86ecc814
125 0:1f0dee641bb7
125 0:1f0dee641bb7
126 % pull -u -r otherrev url#rev updates to rev
126 % pull -u -r otherrev url#rev updates to rev
127 % parents
127 % parents
128 changeset: 3:4cd725637392
128 changeset: 3:4cd725637392
129 tag: tip
129 tag: tip
130 parent: 0:1f0dee641bb7
130 parent: 0:1f0dee641bb7
131 user: test
131 user: test
132 date: Thu Jan 01 00:00:00 1970 +0000
132 date: Thu Jan 01 00:00:00 1970 +0000
133 summary: add bar
133 summary: add bar
134
134
135 % heads
135 % heads
136 changeset: 3:4cd725637392
136 changeset: 3:4cd725637392
137 tag: tip
137 tag: tip
138 parent: 0:1f0dee641bb7
138 parent: 0:1f0dee641bb7
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: add bar
141 summary: add bar
142
142
143 changeset: 2:faba9097cad4
143 changeset: 2:faba9097cad4
144 branch: foo
144 branch: foo
145 user: test
145 user: test
146 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
147 summary: new head of branch foo
147 summary: new head of branch foo
148
148
General Comments 0
You need to be logged in to leave comments. Login now