##// END OF EJS Templates
strip: don't use "full" and "partial" to describe bundles...
Martin von Zweigbergk -
r29954:769aee32 default
parent child Browse files
Show More
@@ -1,357 +1,358 b''
1 1 # repair.py - functions for repository repair for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 4 # Copyright 2007 Matt Mackall
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from __future__ import absolute_import
10 10
11 11 import errno
12 12 import hashlib
13 13
14 14 from .i18n import _
15 15 from .node import short
16 16 from . import (
17 17 bundle2,
18 18 changegroup,
19 19 error,
20 20 exchange,
21 21 obsolete,
22 22 util,
23 23 )
24 24
25 25 def _bundle(repo, bases, heads, node, suffix, compress=True):
26 26 """create a bundle with the specified revisions as a backup"""
27 27 cgversion = changegroup.safeversion(repo)
28 28
29 29 cg = changegroup.changegroupsubset(repo, bases, heads, 'strip',
30 30 version=cgversion)
31 31 backupdir = "strip-backup"
32 32 vfs = repo.vfs
33 33 if not vfs.isdir(backupdir):
34 34 vfs.mkdir(backupdir)
35 35
36 36 # Include a hash of all the nodes in the filename for uniqueness
37 37 allcommits = repo.set('%ln::%ln', bases, heads)
38 38 allhashes = sorted(c.hex() for c in allcommits)
39 39 totalhash = hashlib.sha1(''.join(allhashes)).hexdigest()
40 40 name = "%s/%s-%s-%s.hg" % (backupdir, short(node), totalhash[:8], suffix)
41 41
42 42 comp = None
43 43 if cgversion != '01':
44 44 bundletype = "HG20"
45 45 if compress:
46 46 comp = 'BZ'
47 47 elif compress:
48 48 bundletype = "HG10BZ"
49 49 else:
50 50 bundletype = "HG10UN"
51 51 return bundle2.writebundle(repo.ui, cg, name, bundletype, vfs,
52 52 compression=comp)
53 53
54 54 def _collectfiles(repo, striprev):
55 55 """find out the filelogs affected by the strip"""
56 56 files = set()
57 57
58 58 for x in xrange(striprev, len(repo)):
59 59 files.update(repo[x].files())
60 60
61 61 return sorted(files)
62 62
63 63 def _collectbrokencsets(repo, files, striprev):
64 64 """return the changesets which will be broken by the truncation"""
65 65 s = set()
66 66 def collectone(revlog):
67 67 _, brokenset = revlog.getstrippoint(striprev)
68 68 s.update([revlog.linkrev(r) for r in brokenset])
69 69
70 70 collectone(repo.manifest)
71 71 for fname in files:
72 72 collectone(repo.file(fname))
73 73
74 74 return s
75 75
76 76 def strip(ui, repo, nodelist, backup=True, topic='backup'):
77 77 # This function operates within a transaction of its own, but does
78 78 # not take any lock on the repo.
79 79 # Simple way to maintain backwards compatibility for this
80 80 # argument.
81 81 if backup in ['none', 'strip']:
82 82 backup = False
83 83
84 84 repo = repo.unfiltered()
85 85 repo.destroying()
86 86
87 87 cl = repo.changelog
88 88 # TODO handle undo of merge sets
89 89 if isinstance(nodelist, str):
90 90 nodelist = [nodelist]
91 91 striplist = [cl.rev(node) for node in nodelist]
92 92 striprev = min(striplist)
93 93
94 94 # Some revisions with rev > striprev may not be descendants of striprev.
95 95 # We have to find these revisions and put them in a bundle, so that
96 96 # we can restore them after the truncations.
97 97 # To create the bundle we use repo.changegroupsubset which requires
98 98 # the list of heads and bases of the set of interesting revisions.
99 99 # (head = revision in the set that has no descendant in the set;
100 100 # base = revision in the set that has no ancestor in the set)
101 101 tostrip = set(striplist)
102 102 for rev in striplist:
103 103 for desc in cl.descendants([rev]):
104 104 tostrip.add(desc)
105 105
106 106 files = _collectfiles(repo, striprev)
107 107 saverevs = _collectbrokencsets(repo, files, striprev)
108 108
109 109 # compute heads
110 110 saveheads = set(saverevs)
111 111 for r in xrange(striprev + 1, len(cl)):
112 112 if r not in tostrip:
113 113 saverevs.add(r)
114 114 saveheads.difference_update(cl.parentrevs(r))
115 115 saveheads.add(r)
116 116 saveheads = [cl.node(r) for r in saveheads]
117 117
118 118 # compute base nodes
119 119 if saverevs:
120 120 descendants = set(cl.descendants(saverevs))
121 121 saverevs.difference_update(descendants)
122 122 savebases = [cl.node(r) for r in saverevs]
123 123 stripbases = [cl.node(r) for r in tostrip]
124 124
125 125 # For a set s, max(parents(s) - s) is the same as max(heads(::s - s)), but
126 126 # is much faster
127 127 newbmtarget = repo.revs('max(parents(%ld) - (%ld))', tostrip, tostrip)
128 128 if newbmtarget:
129 129 newbmtarget = repo[newbmtarget.first()].node()
130 130 else:
131 131 newbmtarget = '.'
132 132
133 133 bm = repo._bookmarks
134 134 updatebm = []
135 135 for m in bm:
136 136 rev = repo[bm[m]].rev()
137 137 if rev in tostrip:
138 138 updatebm.append(m)
139 139
140 140 # create a changegroup for all the branches we need to keep
141 141 backupfile = None
142 142 vfs = repo.vfs
143 143 node = nodelist[-1]
144 144 if backup:
145 145 backupfile = _bundle(repo, stripbases, cl.heads(), node, topic)
146 146 repo.ui.status(_("saved backup bundle to %s\n") %
147 147 vfs.join(backupfile))
148 148 repo.ui.log("backupbundle", "saved backup bundle to %s\n",
149 149 vfs.join(backupfile))
150 chgrpfile = None
150 tmpbundlefile = None
151 151 if saveheads:
152 # do not compress partial bundle if we remove it from disk later
153 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
152 # do not compress temporary bundle if we remove it from disk later
153 tmpbundlefile = _bundle(repo, savebases, saveheads, node, 'temp',
154 154 compress=False)
155 155
156 156 mfst = repo.manifest
157 157
158 158 curtr = repo.currenttransaction()
159 159 if curtr is not None:
160 160 del curtr # avoid carrying reference to transaction for nothing
161 161 msg = _('programming error: cannot strip from inside a transaction')
162 162 raise error.Abort(msg, hint=_('contact your extension maintainer'))
163 163
164 164 try:
165 165 with repo.transaction("strip") as tr:
166 166 offset = len(tr.entries)
167 167
168 168 tr.startgroup()
169 169 cl.strip(striprev, tr)
170 170 mfst.strip(striprev, tr)
171 171 if 'treemanifest' in repo.requirements: # safe but unnecessary
172 172 # otherwise
173 173 for unencoded, encoded, size in repo.store.datafiles():
174 174 if (unencoded.startswith('meta/') and
175 175 unencoded.endswith('00manifest.i')):
176 176 dir = unencoded[5:-12]
177 177 repo.manifest.dirlog(dir).strip(striprev, tr)
178 178 for fn in files:
179 179 repo.file(fn).strip(striprev, tr)
180 180 tr.endgroup()
181 181
182 182 for i in xrange(offset, len(tr.entries)):
183 183 file, troffset, ignore = tr.entries[i]
184 184 repo.svfs(file, 'a').truncate(troffset)
185 185 if troffset == 0:
186 186 repo.store.markremoved(file)
187 187
188 if chgrpfile:
188 if tmpbundlefile:
189 189 ui.note(_("adding branch\n"))
190 f = vfs.open(chgrpfile, "rb")
191 gen = exchange.readbundle(ui, f, chgrpfile, vfs)
190 f = vfs.open(tmpbundlefile, "rb")
191 gen = exchange.readbundle(ui, f, tmpbundlefile, vfs)
192 192 if not repo.ui.verbose:
193 193 # silence internal shuffling chatter
194 194 repo.ui.pushbuffer()
195 195 if isinstance(gen, bundle2.unbundle20):
196 196 with repo.transaction('strip') as tr:
197 197 tr.hookargs = {'source': 'strip',
198 'url': 'bundle:' + vfs.join(chgrpfile)}
198 'url': 'bundle:' + vfs.join(tmpbundlefile)}
199 199 bundle2.applybundle(repo, gen, tr, source='strip',
200 url='bundle:' + vfs.join(chgrpfile))
200 url='bundle:' + vfs.join(tmpbundlefile))
201 201 else:
202 gen.apply(repo, 'strip', 'bundle:' + vfs.join(chgrpfile), True)
202 gen.apply(repo, 'strip', 'bundle:' + vfs.join(tmpbundlefile),
203 True)
203 204 if not repo.ui.verbose:
204 205 repo.ui.popbuffer()
205 206 f.close()
206 207 repo._phasecache.invalidate()
207 208
208 209 for m in updatebm:
209 210 bm[m] = repo[newbmtarget].node()
210 211 lock = tr = None
211 212 try:
212 213 lock = repo.lock()
213 214 tr = repo.transaction('repair')
214 215 bm.recordchange(tr)
215 216 tr.close()
216 217 finally:
217 218 tr.release()
218 219 lock.release()
219 220
220 221 # remove undo files
221 222 for undovfs, undofile in repo.undofiles():
222 223 try:
223 224 undovfs.unlink(undofile)
224 225 except OSError as e:
225 226 if e.errno != errno.ENOENT:
226 227 ui.warn(_('error removing %s: %s\n') %
227 228 (undovfs.join(undofile), str(e)))
228 229
229 230 except: # re-raises
230 231 if backupfile:
231 ui.warn(_("strip failed, full bundle stored in '%s'\n")
232 ui.warn(_("strip failed, backup bundle stored in '%s'\n")
232 233 % vfs.join(backupfile))
233 if chgrpfile:
234 if tmpbundlefile:
234 235 ui.warn(_("strip failed, unrecovered changes stored in '%s'\n")
235 % vfs.join(chgrpfile))
236 % vfs.join(tmpbundlefile))
236 237 ui.warn(_("(fix the problem, then recover the changesets with "
237 "\"hg unbundle '%s'\")\n") % vfs.join(chgrpfile))
238 "\"hg unbundle '%s'\")\n") % vfs.join(tmpbundlefile))
238 239 raise
239 240 else:
240 if chgrpfile:
241 # Remove partial backup only if there were no exceptions
242 vfs.unlink(chgrpfile)
241 if tmpbundlefile:
242 # Remove temporary bundle only if there were no exceptions
243 vfs.unlink(tmpbundlefile)
243 244
244 245 repo.destroyed()
245 246
246 247 def rebuildfncache(ui, repo):
247 248 """Rebuilds the fncache file from repo history.
248 249
249 250 Missing entries will be added. Extra entries will be removed.
250 251 """
251 252 repo = repo.unfiltered()
252 253
253 254 if 'fncache' not in repo.requirements:
254 255 ui.warn(_('(not rebuilding fncache because repository does not '
255 256 'support fncache)\n'))
256 257 return
257 258
258 259 with repo.lock():
259 260 fnc = repo.store.fncache
260 261 # Trigger load of fncache.
261 262 if 'irrelevant' in fnc:
262 263 pass
263 264
264 265 oldentries = set(fnc.entries)
265 266 newentries = set()
266 267 seenfiles = set()
267 268
268 269 repolen = len(repo)
269 270 for rev in repo:
270 271 ui.progress(_('rebuilding'), rev, total=repolen,
271 272 unit=_('changesets'))
272 273
273 274 ctx = repo[rev]
274 275 for f in ctx.files():
275 276 # This is to minimize I/O.
276 277 if f in seenfiles:
277 278 continue
278 279 seenfiles.add(f)
279 280
280 281 i = 'data/%s.i' % f
281 282 d = 'data/%s.d' % f
282 283
283 284 if repo.store._exists(i):
284 285 newentries.add(i)
285 286 if repo.store._exists(d):
286 287 newentries.add(d)
287 288
288 289 ui.progress(_('rebuilding'), None)
289 290
290 291 if 'treemanifest' in repo.requirements: # safe but unnecessary otherwise
291 292 for dir in util.dirs(seenfiles):
292 293 i = 'meta/%s/00manifest.i' % dir
293 294 d = 'meta/%s/00manifest.d' % dir
294 295
295 296 if repo.store._exists(i):
296 297 newentries.add(i)
297 298 if repo.store._exists(d):
298 299 newentries.add(d)
299 300
300 301 addcount = len(newentries - oldentries)
301 302 removecount = len(oldentries - newentries)
302 303 for p in sorted(oldentries - newentries):
303 304 ui.write(_('removing %s\n') % p)
304 305 for p in sorted(newentries - oldentries):
305 306 ui.write(_('adding %s\n') % p)
306 307
307 308 if addcount or removecount:
308 309 ui.write(_('%d items added, %d removed from fncache\n') %
309 310 (addcount, removecount))
310 311 fnc.entries = newentries
311 312 fnc._dirty = True
312 313
313 314 with repo.transaction('fncache') as tr:
314 315 fnc.write(tr)
315 316 else:
316 317 ui.write(_('fncache already up to date\n'))
317 318
318 319 def stripbmrevset(repo, mark):
319 320 """
320 321 The revset to strip when strip is called with -B mark
321 322
322 323 Needs to live here so extensions can use it and wrap it even when strip is
323 324 not enabled or not present on a box.
324 325 """
325 326 return repo.revs("ancestors(bookmark(%s)) - "
326 327 "ancestors(head() and not bookmark(%s)) - "
327 328 "ancestors(bookmark() and not bookmark(%s))",
328 329 mark, mark, mark)
329 330
330 331 def deleteobsmarkers(obsstore, indices):
331 332 """Delete some obsmarkers from obsstore and return how many were deleted
332 333
333 334 'indices' is a list of ints which are the indices
334 335 of the markers to be deleted.
335 336
336 337 Every invocation of this function completely rewrites the obsstore file,
337 338 skipping the markers we want to be removed. The new temporary file is
338 339 created, remaining markers are written there and on .close() this file
339 340 gets atomically renamed to obsstore, thus guaranteeing consistency."""
340 341 if not indices:
341 342 # we don't want to rewrite the obsstore with the same content
342 343 return
343 344
344 345 left = []
345 346 current = obsstore._all
346 347 n = 0
347 348 for i, m in enumerate(current):
348 349 if i in indices:
349 350 n += 1
350 351 continue
351 352 left.append(m)
352 353
353 354 newobsstorefile = obsstore.svfs('obsstore', 'w', atomictemp=True)
354 355 for bytes in obsolete.encodemarkers(left, True, obsstore._version):
355 356 newobsstorefile.write(bytes)
356 357 newobsstorefile.close()
357 358 return n
@@ -1,869 +1,869 b''
1 1 commit hooks can see env vars
2 2 (and post-transaction one are run unlocked)
3 3
4 4
5 5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
6 6 > def showargs(ui, repo, hooktype, **kwargs):
7 7 > ui.write('%s python hook: %s\n' % (hooktype, ','.join(sorted(kwargs))))
8 8 > EOF
9 9
10 10 $ hg init a
11 11 $ cd a
12 12 $ cat > .hg/hgrc <<EOF
13 13 > [hooks]
14 14 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py commit"
15 15 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py commit.b"
16 16 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py precommit"
17 17 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxncommit"
18 18 > pretxncommit.tip = hg -q tip
19 19 > pre-identify = printenv.py pre-identify 1
20 20 > pre-cat = printenv.py pre-cat
21 21 > post-cat = printenv.py post-cat
22 22 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnopen"
23 23 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py pretxnclose"
24 24 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py txnclose"
25 25 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
26 26 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py txnabort"
27 27 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
28 28 > EOF
29 29 $ echo a > a
30 30 $ hg add a
31 31 $ hg commit -m a
32 32 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
33 33 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
34 34 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
35 35 0:cb9a9f314b8b
36 36 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_PHASES_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
37 37 txnclose hook: HG_PHASES_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
38 38 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
39 39 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
40 40
41 41 $ hg clone . ../b
42 42 updating to branch default
43 43 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 44 $ cd ../b
45 45
46 46 changegroup hooks can see env vars
47 47
48 48 $ cat > .hg/hgrc <<EOF
49 49 > [hooks]
50 50 > prechangegroup = printenv.py prechangegroup
51 51 > changegroup = printenv.py changegroup
52 52 > incoming = printenv.py incoming
53 53 > EOF
54 54
55 55 pretxncommit and commit hooks can see both parents of merge
56 56
57 57 $ cd ../a
58 58 $ echo b >> a
59 59 $ hg commit -m a1 -d "1 0"
60 60 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
61 61 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
62 62 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
63 63 1:ab228980c14d
64 64 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
65 65 txnclose hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
66 66 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 67 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
68 68 $ hg update -C 0
69 69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 $ echo b > b
71 71 $ hg add b
72 72 $ hg commit -m b -d '1 0'
73 73 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
74 74 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
75 75 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
76 76 2:ee9deb46ab31
77 77 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
78 78 created new head
79 79 txnclose hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
80 80 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
81 81 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
82 82 $ hg merge 1
83 83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 84 (branch merge, don't forget to commit)
85 85 $ hg commit -m merge -d '2 0'
86 86 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
87 87 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
88 88 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
89 89 3:07f3376c1e65
90 90 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
91 91 txnclose hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
92 92 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
93 93 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
94 94
95 95 test generic hooks
96 96
97 97 $ hg id
98 98 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
99 99 abort: pre-identify hook exited with status 1
100 100 [255]
101 101 $ hg cat b
102 102 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
103 103 b
104 104 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
105 105
106 106 $ cd ../b
107 107 $ hg pull ../a
108 108 pulling from ../a
109 109 searching for changes
110 110 prechangegroup hook: HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
111 111 adding changesets
112 112 adding manifests
113 113 adding file changes
114 114 added 3 changesets with 2 changes to 2 files
115 115 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
116 116 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
117 117 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
118 118 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
119 119 (run 'hg update' to get a working copy)
120 120
121 121 tag hooks can see env vars
122 122
123 123 $ cd ../a
124 124 $ cat >> .hg/hgrc <<EOF
125 125 > pretag = printenv.py pretag
126 126 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py tag"
127 127 > EOF
128 128 $ hg tag -d '3 0' a
129 129 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
130 130 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
131 131 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
132 132 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
133 133 4:539e4b31b6dc
134 134 pretxnclose hook: HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
135 135 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
136 136 txnclose hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
137 137 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
138 138 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
139 139 $ hg tag -l la
140 140 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
141 141 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
142 142
143 143 pretag hook can forbid tagging
144 144
145 145 $ echo "pretag.forbid = printenv.py pretag.forbid 1" >> .hg/hgrc
146 146 $ hg tag -d '4 0' fa
147 147 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
148 148 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
149 149 abort: pretag.forbid hook exited with status 1
150 150 [255]
151 151 $ hg tag -l fla
152 152 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
153 153 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
154 154 abort: pretag.forbid hook exited with status 1
155 155 [255]
156 156
157 157 pretxncommit hook can see changeset, can roll back txn, changeset no
158 158 more there after
159 159
160 160 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
161 161 $ echo "pretxncommit.forbid1 = printenv.py pretxncommit.forbid 1" >> .hg/hgrc
162 162 $ echo z > z
163 163 $ hg add z
164 164 $ hg -q tip
165 165 4:539e4b31b6dc
166 166 $ hg commit -m 'fail' -d '4 0'
167 167 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
168 168 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
169 169 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
170 170 5:6f611f8018c1
171 171 5:6f611f8018c1
172 172 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
173 173 transaction abort!
174 174 txnabort python hook: txnid,txnname
175 175 txnabort hook: HG_TXNID=TXN:* HG_TXNNAME=commit (glob)
176 176 rollback completed
177 177 abort: pretxncommit.forbid1 hook exited with status 1
178 178 [255]
179 179 $ hg -q tip
180 180 4:539e4b31b6dc
181 181
182 182 (Check that no 'changelog.i.a' file were left behind)
183 183
184 184 $ ls -1 .hg/store/
185 185 00changelog.i
186 186 00manifest.i
187 187 data
188 188 fncache
189 189 journal.phaseroots
190 190 phaseroots
191 191 undo
192 192 undo.backup.fncache
193 193 undo.backupfiles
194 194 undo.phaseroots
195 195
196 196
197 197 precommit hook can prevent commit
198 198
199 199 $ echo "precommit.forbid = printenv.py precommit.forbid 1" >> .hg/hgrc
200 200 $ hg commit -m 'fail' -d '4 0'
201 201 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
202 202 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
203 203 abort: precommit.forbid hook exited with status 1
204 204 [255]
205 205 $ hg -q tip
206 206 4:539e4b31b6dc
207 207
208 208 preupdate hook can prevent update
209 209
210 210 $ echo "preupdate = printenv.py preupdate" >> .hg/hgrc
211 211 $ hg update 1
212 212 preupdate hook: HG_PARENT1=ab228980c14d
213 213 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
214 214
215 215 update hook
216 216
217 217 $ echo "update = printenv.py update" >> .hg/hgrc
218 218 $ hg update
219 219 preupdate hook: HG_PARENT1=539e4b31b6dc
220 220 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
221 221 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 222
223 223 pushkey hook
224 224
225 225 $ echo "pushkey = printenv.py pushkey" >> .hg/hgrc
226 226 $ cd ../b
227 227 $ hg bookmark -r null foo
228 228 $ hg push -B foo ../a
229 229 pushing to ../a
230 230 searching for changes
231 231 no changes found
232 232 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=push (glob)
233 233 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_PENDING=$TESTTMP/a HG_SOURCE=push HG_TXNID=TXN:* HG_TXNNAME=push HG_URL=file:$TESTTMP/a (glob)
234 234 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
235 235 txnclose hook: HG_BOOKMARK_MOVED=1 HG_BUNDLE2=1 HG_SOURCE=push HG_TXNID=TXN:* HG_TXNNAME=push HG_URL=file:$TESTTMP/a (glob)
236 236 exporting bookmark foo
237 237 [1]
238 238 $ cd ../a
239 239
240 240 listkeys hook
241 241
242 242 $ echo "listkeys = printenv.py listkeys" >> .hg/hgrc
243 243 $ hg bookmark -r null bar
244 244 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
245 245 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
246 246 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
247 247 $ cd ../b
248 248 $ hg pull -B bar ../a
249 249 pulling from ../a
250 250 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
251 251 no changes found
252 252 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
253 253 adding remote bookmark bar
254 254 $ cd ../a
255 255
256 256 test that prepushkey can prevent incoming keys
257 257
258 258 $ echo "prepushkey = printenv.py prepushkey.forbid 1" >> .hg/hgrc
259 259 $ cd ../b
260 260 $ hg bookmark -r null baz
261 261 $ hg push -B baz ../a
262 262 pushing to ../a
263 263 searching for changes
264 264 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
265 265 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
266 266 no changes found
267 267 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=push (glob)
268 268 prepushkey.forbid hook: HG_BUNDLE2=1 HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_SOURCE=push HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
269 269 pushkey-abort: prepushkey hook exited with status 1
270 270 abort: exporting bookmark baz failed!
271 271 [255]
272 272 $ cd ../a
273 273
274 274 test that prelistkeys can prevent listing keys
275 275
276 276 $ echo "prelistkeys = printenv.py prelistkeys.forbid 1" >> .hg/hgrc
277 277 $ hg bookmark -r null quux
278 278 pretxnopen hook: HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
279 279 pretxnclose hook: HG_BOOKMARK_MOVED=1 HG_PENDING=$TESTTMP/a HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
280 280 txnclose hook: HG_BOOKMARK_MOVED=1 HG_TXNID=TXN:* HG_TXNNAME=bookmark (glob)
281 281 $ cd ../b
282 282 $ hg pull -B quux ../a
283 283 pulling from ../a
284 284 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
285 285 abort: prelistkeys hook exited with status 1
286 286 [255]
287 287 $ cd ../a
288 288 $ rm .hg/hgrc
289 289
290 290 prechangegroup hook can prevent incoming changes
291 291
292 292 $ cd ../b
293 293 $ hg -q tip
294 294 3:07f3376c1e65
295 295 $ cat > .hg/hgrc <<EOF
296 296 > [hooks]
297 297 > prechangegroup.forbid = printenv.py prechangegroup.forbid 1
298 298 > EOF
299 299 $ hg pull ../a
300 300 pulling from ../a
301 301 searching for changes
302 302 prechangegroup.forbid hook: HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
303 303 abort: prechangegroup.forbid hook exited with status 1
304 304 [255]
305 305
306 306 pretxnchangegroup hook can see incoming changes, can roll back txn,
307 307 incoming changes no longer there after
308 308
309 309 $ cat > .hg/hgrc <<EOF
310 310 > [hooks]
311 311 > pretxnchangegroup.forbid0 = hg tip -q
312 312 > pretxnchangegroup.forbid1 = printenv.py pretxnchangegroup.forbid 1
313 313 > EOF
314 314 $ hg pull ../a
315 315 pulling from ../a
316 316 searching for changes
317 317 adding changesets
318 318 adding manifests
319 319 adding file changes
320 320 added 1 changesets with 1 changes to 1 files
321 321 4:539e4b31b6dc
322 322 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=file:$TESTTMP/a (glob)
323 323 transaction abort!
324 324 rollback completed
325 325 abort: pretxnchangegroup.forbid1 hook exited with status 1
326 326 [255]
327 327 $ hg -q tip
328 328 3:07f3376c1e65
329 329
330 330 outgoing hooks can see env vars
331 331
332 332 $ rm .hg/hgrc
333 333 $ cat > ../a/.hg/hgrc <<EOF
334 334 > [hooks]
335 335 > preoutgoing = printenv.py preoutgoing
336 336 > outgoing = printenv.py outgoing
337 337 > EOF
338 338 $ hg pull ../a
339 339 pulling from ../a
340 340 searching for changes
341 341 preoutgoing hook: HG_SOURCE=pull
342 342 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
343 343 adding changesets
344 344 adding manifests
345 345 adding file changes
346 346 added 1 changesets with 1 changes to 1 files
347 347 adding remote bookmark quux
348 348 (run 'hg update' to get a working copy)
349 349 $ hg rollback
350 350 repository tip rolled back to revision 3 (undo pull)
351 351
352 352 preoutgoing hook can prevent outgoing changes
353 353
354 354 $ echo "preoutgoing.forbid = printenv.py preoutgoing.forbid 1" >> ../a/.hg/hgrc
355 355 $ hg pull ../a
356 356 pulling from ../a
357 357 searching for changes
358 358 preoutgoing hook: HG_SOURCE=pull
359 359 preoutgoing.forbid hook: HG_SOURCE=pull
360 360 abort: preoutgoing.forbid hook exited with status 1
361 361 [255]
362 362
363 363 outgoing hooks work for local clones
364 364
365 365 $ cd ..
366 366 $ cat > a/.hg/hgrc <<EOF
367 367 > [hooks]
368 368 > preoutgoing = printenv.py preoutgoing
369 369 > outgoing = printenv.py outgoing
370 370 > EOF
371 371 $ hg clone a c
372 372 preoutgoing hook: HG_SOURCE=clone
373 373 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
374 374 updating to branch default
375 375 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 376 $ rm -rf c
377 377
378 378 preoutgoing hook can prevent outgoing changes for local clones
379 379
380 380 $ echo "preoutgoing.forbid = printenv.py preoutgoing.forbid 1" >> a/.hg/hgrc
381 381 $ hg clone a zzz
382 382 preoutgoing hook: HG_SOURCE=clone
383 383 preoutgoing.forbid hook: HG_SOURCE=clone
384 384 abort: preoutgoing.forbid hook exited with status 1
385 385 [255]
386 386
387 387 $ cd "$TESTTMP/b"
388 388
389 389 $ cat > hooktests.py <<EOF
390 390 > from mercurial import error
391 391 >
392 392 > uncallable = 0
393 393 >
394 394 > def printargs(args):
395 395 > args.pop('ui', None)
396 396 > args.pop('repo', None)
397 397 > a = list(args.items())
398 398 > a.sort()
399 399 > print 'hook args:'
400 400 > for k, v in a:
401 401 > print ' ', k, v
402 402 >
403 403 > def passhook(**args):
404 404 > printargs(args)
405 405 >
406 406 > def failhook(**args):
407 407 > printargs(args)
408 408 > return True
409 409 >
410 410 > class LocalException(Exception):
411 411 > pass
412 412 >
413 413 > def raisehook(**args):
414 414 > raise LocalException('exception from hook')
415 415 >
416 416 > def aborthook(**args):
417 417 > raise error.Abort('raise abort from hook')
418 418 >
419 419 > def brokenhook(**args):
420 420 > return 1 + {}
421 421 >
422 422 > def verbosehook(ui, **args):
423 423 > ui.note('verbose output from hook\n')
424 424 >
425 425 > def printtags(ui, repo, **args):
426 426 > print sorted(repo.tags())
427 427 >
428 428 > class container:
429 429 > unreachable = 1
430 430 > EOF
431 431
432 432 $ cat > syntaxerror.py << EOF
433 433 > (foo
434 434 > EOF
435 435
436 436 test python hooks
437 437
438 438 #if windows
439 439 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
440 440 #else
441 441 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
442 442 #endif
443 443 $ export PYTHONPATH
444 444
445 445 $ echo '[hooks]' > ../a/.hg/hgrc
446 446 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
447 447 $ hg pull ../a 2>&1 | grep 'raised an exception'
448 448 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
449 449
450 450 $ echo '[hooks]' > ../a/.hg/hgrc
451 451 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
452 452 $ hg pull ../a 2>&1 | grep 'raised an exception'
453 453 error: preoutgoing.raise hook raised an exception: exception from hook
454 454
455 455 $ echo '[hooks]' > ../a/.hg/hgrc
456 456 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
457 457 $ hg pull ../a
458 458 pulling from ../a
459 459 searching for changes
460 460 error: preoutgoing.abort hook failed: raise abort from hook
461 461 abort: raise abort from hook
462 462 [255]
463 463
464 464 $ echo '[hooks]' > ../a/.hg/hgrc
465 465 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
466 466 $ hg pull ../a
467 467 pulling from ../a
468 468 searching for changes
469 469 hook args:
470 470 hooktype preoutgoing
471 471 source pull
472 472 abort: preoutgoing.fail hook failed
473 473 [255]
474 474
475 475 $ echo '[hooks]' > ../a/.hg/hgrc
476 476 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
477 477 $ hg pull ../a
478 478 pulling from ../a
479 479 searching for changes
480 480 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
481 481 [255]
482 482
483 483 $ echo '[hooks]' > ../a/.hg/hgrc
484 484 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
485 485 $ hg pull ../a
486 486 pulling from ../a
487 487 searching for changes
488 488 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
489 489 [255]
490 490
491 491 $ echo '[hooks]' > ../a/.hg/hgrc
492 492 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
493 493 $ hg pull ../a
494 494 pulling from ../a
495 495 searching for changes
496 496 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
497 497 [255]
498 498
499 499 $ echo '[hooks]' > ../a/.hg/hgrc
500 500 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
501 501 $ hg pull ../a
502 502 pulling from ../a
503 503 searching for changes
504 504 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
505 505 (run with --traceback for stack trace)
506 506 [255]
507 507
508 508 $ echo '[hooks]' > ../a/.hg/hgrc
509 509 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
510 510 $ hg pull ../a
511 511 pulling from ../a
512 512 searching for changes
513 513 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
514 514 (run with --traceback for stack trace)
515 515 [255]
516 516
517 517 $ echo '[hooks]' > ../a/.hg/hgrc
518 518 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
519 519 $ hg pull ../a
520 520 pulling from ../a
521 521 searching for changes
522 522 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
523 523 (run with --traceback for stack trace)
524 524 [255]
525 525
526 526 The second egrep is to filter out lines like ' ^', which are slightly
527 527 different between Python 2.6 and Python 2.7.
528 528 $ hg pull ../a --traceback 2>&1 | egrep -v '^( +File| [_a-zA-Z*(])' | egrep -v '^( )+(\^)?$'
529 529 pulling from ../a
530 530 searching for changes
531 531 exception from first failed import attempt:
532 532 Traceback (most recent call last):
533 533 SyntaxError: * (glob)
534 534 exception from second failed import attempt:
535 535 Traceback (most recent call last):
536 536 ImportError: No module named hgext_syntaxerror
537 537 Traceback (most recent call last):
538 538 HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
539 539 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
540 540
541 541 $ echo '[hooks]' > ../a/.hg/hgrc
542 542 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
543 543 $ hg pull ../a
544 544 pulling from ../a
545 545 searching for changes
546 546 hook args:
547 547 hooktype preoutgoing
548 548 source pull
549 549 adding changesets
550 550 adding manifests
551 551 adding file changes
552 552 added 1 changesets with 1 changes to 1 files
553 553 adding remote bookmark quux
554 554 (run 'hg update' to get a working copy)
555 555
556 556 post- python hooks that fail to *run* don't cause an abort
557 557 $ rm ../a/.hg/hgrc
558 558 $ echo '[hooks]' > .hg/hgrc
559 559 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
560 560 $ hg pull ../a
561 561 pulling from ../a
562 562 searching for changes
563 563 no changes found
564 564 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
565 565 (run with --traceback for stack trace)
566 566
567 567 but post- python hooks that fail to *load* do
568 568 $ echo '[hooks]' > .hg/hgrc
569 569 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
570 570 $ hg pull ../a
571 571 pulling from ../a
572 572 searching for changes
573 573 no changes found
574 574 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
575 575 [255]
576 576
577 577 $ echo '[hooks]' > .hg/hgrc
578 578 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
579 579 $ hg pull ../a
580 580 pulling from ../a
581 581 searching for changes
582 582 no changes found
583 583 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
584 584 (run with --traceback for stack trace)
585 585 [255]
586 586
587 587 $ echo '[hooks]' > .hg/hgrc
588 588 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
589 589 $ hg pull ../a
590 590 pulling from ../a
591 591 searching for changes
592 592 no changes found
593 593 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
594 594 [255]
595 595
596 596 make sure --traceback works
597 597
598 598 $ echo '[hooks]' > .hg/hgrc
599 599 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
600 600
601 601 $ echo aa > a
602 602 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
603 603 Traceback (most recent call last):
604 604
605 605 $ cd ..
606 606 $ hg init c
607 607 $ cd c
608 608
609 609 $ cat > hookext.py <<EOF
610 610 > def autohook(**args):
611 611 > print "Automatically installed hook"
612 612 >
613 613 > def reposetup(ui, repo):
614 614 > repo.ui.setconfig("hooks", "commit.auto", autohook)
615 615 > EOF
616 616 $ echo '[extensions]' >> .hg/hgrc
617 617 $ echo 'hookext = hookext.py' >> .hg/hgrc
618 618
619 619 $ touch foo
620 620 $ hg add foo
621 621 $ hg ci -d '0 0' -m 'add foo'
622 622 Automatically installed hook
623 623 $ echo >> foo
624 624 $ hg ci --debug -d '0 0' -m 'change foo'
625 625 committing files:
626 626 foo
627 627 committing manifest
628 628 committing changelog
629 629 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
630 630 calling hook commit.auto: hgext_hookext.autohook
631 631 Automatically installed hook
632 632
633 633 $ hg showconfig hooks
634 634 hooks.commit.auto=<function autohook at *> (glob)
635 635
636 636 test python hook configured with python:[file]:[hook] syntax
637 637
638 638 $ cd ..
639 639 $ mkdir d
640 640 $ cd d
641 641 $ hg init repo
642 642 $ mkdir hooks
643 643
644 644 $ cd hooks
645 645 $ cat > testhooks.py <<EOF
646 646 > def testhook(**args):
647 647 > print 'hook works'
648 648 > EOF
649 649 $ echo '[hooks]' > ../repo/.hg/hgrc
650 650 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
651 651
652 652 $ cd ../repo
653 653 $ hg commit -d '0 0'
654 654 hook works
655 655 nothing changed
656 656 [1]
657 657
658 658 $ echo '[hooks]' > .hg/hgrc
659 659 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
660 660 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
661 661
662 662 $ hg up null
663 663 loading update.ne hook failed:
664 664 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
665 665 [255]
666 666
667 667 $ hg id
668 668 loading pre-identify.npmd hook failed:
669 669 abort: No module named repo!
670 670 [255]
671 671
672 672 $ cd ../../b
673 673
674 674 make sure --traceback works on hook import failure
675 675
676 676 $ cat > importfail.py <<EOF
677 677 > import somebogusmodule
678 678 > # dereference something in the module to force demandimport to load it
679 679 > somebogusmodule.whatever
680 680 > EOF
681 681
682 682 $ echo '[hooks]' > .hg/hgrc
683 683 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
684 684
685 685 $ echo a >> a
686 686 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
687 687 exception from first failed import attempt:
688 688 Traceback (most recent call last):
689 689 ImportError: No module named somebogusmodule
690 690 exception from second failed import attempt:
691 691 Traceback (most recent call last):
692 692 ImportError: No module named hgext_importfail
693 693 Traceback (most recent call last):
694 694 HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed
695 695 abort: precommit.importfail hook is invalid: import of "importfail" failed
696 696
697 697 Issue1827: Hooks Update & Commit not completely post operation
698 698
699 699 commit and update hooks should run after command completion. The largefiles
700 700 use demonstrates a recursive wlock, showing the hook doesn't run until the
701 701 final release (and dirstate flush).
702 702
703 703 $ echo '[hooks]' > .hg/hgrc
704 704 $ echo 'commit = hg id' >> .hg/hgrc
705 705 $ echo 'update = hg id' >> .hg/hgrc
706 706 $ echo bb > a
707 707 $ hg ci -ma
708 708 223eafe2750c tip
709 709 $ hg up 0 --config extensions.largefiles=
710 710 cb9a9f314b8b
711 711 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
712 712
713 713 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
714 714 that is passed to pre/post hooks
715 715
716 716 $ echo '[hooks]' > .hg/hgrc
717 717 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
718 718 $ hg id
719 719 cb9a9f314b8b
720 720 $ hg id --verbose
721 721 calling hook pre-identify: hooktests.verbosehook
722 722 verbose output from hook
723 723 cb9a9f314b8b
724 724
725 725 Ensure hooks can be prioritized
726 726
727 727 $ echo '[hooks]' > .hg/hgrc
728 728 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
729 729 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
730 730 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
731 731 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
732 732 $ hg id --verbose
733 733 calling hook pre-identify.b: hooktests.verbosehook
734 734 verbose output from hook
735 735 calling hook pre-identify.a: hooktests.verbosehook
736 736 verbose output from hook
737 737 calling hook pre-identify.c: hooktests.verbosehook
738 738 verbose output from hook
739 739 cb9a9f314b8b
740 740
741 741 new tags must be visible in pretxncommit (issue3210)
742 742
743 743 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
744 744 $ hg tag -f foo
745 745 ['a', 'foo', 'tip']
746 746
747 747 post-init hooks must not crash (issue4983)
748 748 This also creates the `to` repo for the next test block.
749 749
750 750 $ cd ..
751 751 $ cat << EOF >> hgrc-with-post-init-hook
752 752 > [hooks]
753 753 > post-init = printenv.py post-init
754 754 > EOF
755 755 $ HGRCPATH=hgrc-with-post-init-hook hg init to
756 756 post-init hook: HG_ARGS=init to HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''} HG_PATS=['to'] HG_RESULT=0
757 757
758 758 new commits must be visible in pretxnchangegroup (issue3428)
759 759
760 760 $ echo '[hooks]' >> to/.hg/hgrc
761 761 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
762 762 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
763 763 $ echo a >> to/a
764 764 $ hg --cwd to ci -Ama
765 765 adding a
766 766 $ hg clone to from
767 767 updating to branch default
768 768 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
769 769 $ echo aa >> from/a
770 770 $ hg --cwd from ci -mb
771 771 $ hg --cwd from push
772 772 pushing to $TESTTMP/to (glob)
773 773 searching for changes
774 774 changeset: 0:cb9a9f314b8b
775 775 tag: tip
776 776 user: test
777 777 date: Thu Jan 01 00:00:00 1970 +0000
778 778 summary: a
779 779
780 780 adding changesets
781 781 adding manifests
782 782 adding file changes
783 783 added 1 changesets with 1 changes to 1 files
784 784 changeset: 1:9836a07b9b9d
785 785 tag: tip
786 786 user: test
787 787 date: Thu Jan 01 00:00:00 1970 +0000
788 788 summary: b
789 789
790 790
791 791 pretxnclose hook failure should abort the transaction
792 792
793 793 $ hg init txnfailure
794 794 $ cd txnfailure
795 795 $ touch a && hg commit -Aqm a
796 796 $ cat >> .hg/hgrc <<EOF
797 797 > [hooks]
798 798 > pretxnclose.error = exit 1
799 799 > EOF
800 800 $ hg strip -r 0 --config extensions.strip=
801 801 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
802 802 saved backup bundle to * (glob)
803 803 transaction abort!
804 804 rollback completed
805 strip failed, full bundle stored in * (glob)
805 strip failed, backup bundle stored in * (glob)
806 806 abort: pretxnclose.error hook exited with status 1
807 807 [255]
808 808 $ hg recover
809 809 no interrupted transaction available
810 810 [1]
811 811 $ cd ..
812 812
813 813 Hook from untrusted hgrc are reported as failure
814 814 ================================================
815 815
816 816 $ cat << EOF > $TESTTMP/untrusted.py
817 817 > from mercurial import scmutil, util
818 818 > def uisetup(ui):
819 819 > class untrustedui(ui.__class__):
820 820 > def _trusted(self, fp, f):
821 821 > if util.normpath(fp.name).endswith('untrusted/.hg/hgrc'):
822 822 > return False
823 823 > return super(untrustedui, self)._trusted(fp, f)
824 824 > ui.__class__ = untrustedui
825 825 > EOF
826 826 $ cat << EOF >> $HGRCPATH
827 827 > [extensions]
828 828 > untrusted=$TESTTMP/untrusted.py
829 829 > EOF
830 830 $ hg init untrusted
831 831 $ cd untrusted
832 832
833 833 Non-blocking hook
834 834 -----------------
835 835
836 836 $ cat << EOF >> .hg/hgrc
837 837 > [hooks]
838 838 > txnclose.testing=echo txnclose hook called
839 839 > EOF
840 840 $ touch a && hg commit -Aqm a
841 841 warning: untrusted hook txnclose not executed
842 842 $ hg log
843 843 changeset: 0:3903775176ed
844 844 tag: tip
845 845 user: test
846 846 date: Thu Jan 01 00:00:00 1970 +0000
847 847 summary: a
848 848
849 849
850 850 Non-blocking hook
851 851 -----------------
852 852
853 853 $ cat << EOF >> .hg/hgrc
854 854 > [hooks]
855 855 > pretxnclose.testing=echo pre-txnclose hook called
856 856 > EOF
857 857 $ touch b && hg commit -Aqm a
858 858 transaction abort!
859 859 rollback completed
860 860 abort: untrusted hook pretxnclose not executed
861 861 (see 'hg help config.trusted')
862 862 [255]
863 863 $ hg log
864 864 changeset: 0:3903775176ed
865 865 tag: tip
866 866 user: test
867 867 date: Thu Jan 01 00:00:00 1970 +0000
868 868 summary: a
869 869
@@ -1,139 +1,139 b''
1 1 #require unix-permissions no-root
2 2
3 3 $ cat > $TESTTMP/dumpjournal.py <<EOF
4 4 > import sys
5 5 > for entry in sys.stdin.read().split('\n'):
6 6 > if entry:
7 7 > print entry.split('\x00')[0]
8 8 > EOF
9 9
10 10 $ echo "[extensions]" >> $HGRCPATH
11 11 $ echo "mq=">> $HGRCPATH
12 12
13 13 $ teststrip() {
14 14 > hg -q up -C $1
15 15 > echo % before update $1, strip $2
16 16 > hg parents
17 17 > chmod -$3 $4
18 18 > hg strip $2 2>&1 | sed 's/\(bundle\).*/\1/' | sed 's/Permission denied.*\.hg\/store\/\(.*\)/Permission denied \.hg\/store\/\1/'
19 19 > echo % after update $1, strip $2
20 20 > chmod +$3 $4
21 21 > hg verify
22 22 > echo % journal contents
23 23 > if [ -f .hg/store/journal ]; then
24 24 > cat .hg/store/journal | python $TESTTMP/dumpjournal.py
25 25 > else
26 26 > echo "(no journal)"
27 27 > fi
28 28 > ls .hg/store/journal >/dev/null 2>&1 && hg recover
29 29 > ls .hg/strip-backup/* >/dev/null 2>&1 && hg unbundle -q .hg/strip-backup/*
30 30 > rm -rf .hg/strip-backup
31 31 > }
32 32
33 33 $ hg init test
34 34 $ cd test
35 35 $ echo a > a
36 36 $ hg -q ci -m "a" -A
37 37 $ echo b > b
38 38 $ hg -q ci -m "b" -A
39 39 $ echo b2 >> b
40 40 $ hg -q ci -m "b2" -A
41 41 $ echo c > c
42 42 $ hg -q ci -m "c" -A
43 43 $ teststrip 0 2 w .hg/store/data/b.i
44 44 % before update 0, strip 2
45 45 changeset: 0:cb9a9f314b8b
46 46 user: test
47 47 date: Thu Jan 01 00:00:00 1970 +0000
48 48 summary: a
49 49
50 50 saved backup bundle
51 51 transaction abort!
52 52 failed to truncate data/b.i
53 53 rollback failed - please run hg recover
54 strip failed, full bundle
54 strip failed, backup bundle
55 55 abort: Permission denied .hg/store/data/b.i
56 56 % after update 0, strip 2
57 57 abandoned transaction found - run hg recover
58 58 checking changesets
59 59 checking manifests
60 60 crosschecking files in changesets and manifests
61 61 checking files
62 62 b@?: rev 1 points to nonexistent changeset 2
63 63 (expected 1)
64 64 b@?: 736c29771fba not in manifests
65 65 warning: orphan revlog 'data/c.i'
66 66 2 files, 2 changesets, 3 total revisions
67 67 2 warnings encountered!
68 68 2 integrity errors encountered!
69 69 % journal contents
70 70 00changelog.i
71 71 00manifest.i
72 72 data/b.i
73 73 data/c.i
74 74 rolling back interrupted transaction
75 75 checking changesets
76 76 checking manifests
77 77 crosschecking files in changesets and manifests
78 78 checking files
79 79 2 files, 2 changesets, 2 total revisions
80 80 $ teststrip 0 2 r .hg/store/data/b.i
81 81 % before update 0, strip 2
82 82 changeset: 0:cb9a9f314b8b
83 83 user: test
84 84 date: Thu Jan 01 00:00:00 1970 +0000
85 85 summary: a
86 86
87 87 abort: Permission denied .hg/store/data/b.i
88 88 % after update 0, strip 2
89 89 checking changesets
90 90 checking manifests
91 91 crosschecking files in changesets and manifests
92 92 checking files
93 93 3 files, 4 changesets, 4 total revisions
94 94 % journal contents
95 95 (no journal)
96 96 $ teststrip 0 2 w .hg/store/00manifest.i
97 97 % before update 0, strip 2
98 98 changeset: 0:cb9a9f314b8b
99 99 user: test
100 100 date: Thu Jan 01 00:00:00 1970 +0000
101 101 summary: a
102 102
103 103 saved backup bundle
104 104 transaction abort!
105 105 failed to truncate 00manifest.i
106 106 rollback failed - please run hg recover
107 strip failed, full bundle
107 strip failed, backup bundle
108 108 abort: Permission denied .hg/store/00manifest.i
109 109 % after update 0, strip 2
110 110 abandoned transaction found - run hg recover
111 111 checking changesets
112 112 checking manifests
113 113 manifest@?: rev 2 points to nonexistent changeset 2
114 114 manifest@?: 3362547cdf64 not in changesets
115 115 manifest@?: rev 3 points to nonexistent changeset 3
116 116 manifest@?: 265a85892ecb not in changesets
117 117 crosschecking files in changesets and manifests
118 118 c@3: in manifest but not in changeset
119 119 checking files
120 120 b@?: rev 1 points to nonexistent changeset 2
121 121 (expected 1)
122 122 c@?: rev 0 points to nonexistent changeset 3
123 123 3 files, 2 changesets, 4 total revisions
124 124 1 warnings encountered!
125 125 7 integrity errors encountered!
126 126 (first damaged changeset appears to be 3)
127 127 % journal contents
128 128 00changelog.i
129 129 00manifest.i
130 130 data/b.i
131 131 data/c.i
132 132 rolling back interrupted transaction
133 133 checking changesets
134 134 checking manifests
135 135 crosschecking files in changesets and manifests
136 136 checking files
137 137 2 files, 2 changesets, 2 total revisions
138 138
139 139 $ cd ..
@@ -1,938 +1,938 b''
1 1 $ echo "[format]" >> $HGRCPATH
2 2 $ echo "usegeneraldelta=yes" >> $HGRCPATH
3 3 $ echo "[extensions]" >> $HGRCPATH
4 4 $ echo "strip=" >> $HGRCPATH
5 5
6 6 $ restore() {
7 7 > hg unbundle -q .hg/strip-backup/*
8 8 > rm .hg/strip-backup/*
9 9 > }
10 10 $ teststrip() {
11 11 > hg up -C $1
12 12 > echo % before update $1, strip $2
13 13 > hg parents
14 14 > hg --traceback strip $2
15 15 > echo % after update $1, strip $2
16 16 > hg parents
17 17 > restore
18 18 > }
19 19
20 20 $ hg init test
21 21 $ cd test
22 22
23 23 $ echo foo > bar
24 24 $ hg ci -Ama
25 25 adding bar
26 26
27 27 $ echo more >> bar
28 28 $ hg ci -Amb
29 29
30 30 $ echo blah >> bar
31 31 $ hg ci -Amc
32 32
33 33 $ hg up 1
34 34 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 35 $ echo blah >> bar
36 36 $ hg ci -Amd
37 37 created new head
38 38
39 39 $ echo final >> bar
40 40 $ hg ci -Ame
41 41
42 42 $ hg log
43 43 changeset: 4:443431ffac4f
44 44 tag: tip
45 45 user: test
46 46 date: Thu Jan 01 00:00:00 1970 +0000
47 47 summary: e
48 48
49 49 changeset: 3:65bd5f99a4a3
50 50 parent: 1:ef3a871183d7
51 51 user: test
52 52 date: Thu Jan 01 00:00:00 1970 +0000
53 53 summary: d
54 54
55 55 changeset: 2:264128213d29
56 56 user: test
57 57 date: Thu Jan 01 00:00:00 1970 +0000
58 58 summary: c
59 59
60 60 changeset: 1:ef3a871183d7
61 61 user: test
62 62 date: Thu Jan 01 00:00:00 1970 +0000
63 63 summary: b
64 64
65 65 changeset: 0:9ab35a2d17cb
66 66 user: test
67 67 date: Thu Jan 01 00:00:00 1970 +0000
68 68 summary: a
69 69
70 70
71 71 $ teststrip 4 4
72 72 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 73 % before update 4, strip 4
74 74 changeset: 4:443431ffac4f
75 75 tag: tip
76 76 user: test
77 77 date: Thu Jan 01 00:00:00 1970 +0000
78 78 summary: e
79 79
80 80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 81 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
82 82 % after update 4, strip 4
83 83 changeset: 3:65bd5f99a4a3
84 84 tag: tip
85 85 parent: 1:ef3a871183d7
86 86 user: test
87 87 date: Thu Jan 01 00:00:00 1970 +0000
88 88 summary: d
89 89
90 90 $ teststrip 4 3
91 91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 92 % before update 4, strip 3
93 93 changeset: 4:443431ffac4f
94 94 tag: tip
95 95 user: test
96 96 date: Thu Jan 01 00:00:00 1970 +0000
97 97 summary: e
98 98
99 99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 100 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
101 101 % after update 4, strip 3
102 102 changeset: 1:ef3a871183d7
103 103 user: test
104 104 date: Thu Jan 01 00:00:00 1970 +0000
105 105 summary: b
106 106
107 107 $ teststrip 1 4
108 108 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 109 % before update 1, strip 4
110 110 changeset: 1:ef3a871183d7
111 111 user: test
112 112 date: Thu Jan 01 00:00:00 1970 +0000
113 113 summary: b
114 114
115 115 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
116 116 % after update 1, strip 4
117 117 changeset: 1:ef3a871183d7
118 118 user: test
119 119 date: Thu Jan 01 00:00:00 1970 +0000
120 120 summary: b
121 121
122 122 $ teststrip 4 2
123 123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 124 % before update 4, strip 2
125 125 changeset: 4:443431ffac4f
126 126 tag: tip
127 127 user: test
128 128 date: Thu Jan 01 00:00:00 1970 +0000
129 129 summary: e
130 130
131 131 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
132 132 % after update 4, strip 2
133 133 changeset: 3:443431ffac4f
134 134 tag: tip
135 135 user: test
136 136 date: Thu Jan 01 00:00:00 1970 +0000
137 137 summary: e
138 138
139 139 $ teststrip 4 1
140 140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 141 % before update 4, strip 1
142 142 changeset: 4:264128213d29
143 143 tag: tip
144 144 parent: 1:ef3a871183d7
145 145 user: test
146 146 date: Thu Jan 01 00:00:00 1970 +0000
147 147 summary: c
148 148
149 149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 150 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
151 151 % after update 4, strip 1
152 152 changeset: 0:9ab35a2d17cb
153 153 tag: tip
154 154 user: test
155 155 date: Thu Jan 01 00:00:00 1970 +0000
156 156 summary: a
157 157
158 158 $ teststrip null 4
159 159 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
160 160 % before update null, strip 4
161 161 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
162 162 % after update null, strip 4
163 163
164 164 $ hg log
165 165 changeset: 4:264128213d29
166 166 tag: tip
167 167 parent: 1:ef3a871183d7
168 168 user: test
169 169 date: Thu Jan 01 00:00:00 1970 +0000
170 170 summary: c
171 171
172 172 changeset: 3:443431ffac4f
173 173 user: test
174 174 date: Thu Jan 01 00:00:00 1970 +0000
175 175 summary: e
176 176
177 177 changeset: 2:65bd5f99a4a3
178 178 user: test
179 179 date: Thu Jan 01 00:00:00 1970 +0000
180 180 summary: d
181 181
182 182 changeset: 1:ef3a871183d7
183 183 user: test
184 184 date: Thu Jan 01 00:00:00 1970 +0000
185 185 summary: b
186 186
187 187 changeset: 0:9ab35a2d17cb
188 188 user: test
189 189 date: Thu Jan 01 00:00:00 1970 +0000
190 190 summary: a
191 191
192 192 $ hg up -C 4
193 193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 194 $ hg parents
195 195 changeset: 4:264128213d29
196 196 tag: tip
197 197 parent: 1:ef3a871183d7
198 198 user: test
199 199 date: Thu Jan 01 00:00:00 1970 +0000
200 200 summary: c
201 201
202 202
203 203 $ hg --traceback strip 4
204 204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 205 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg (glob)
206 206 $ hg parents
207 207 changeset: 1:ef3a871183d7
208 208 user: test
209 209 date: Thu Jan 01 00:00:00 1970 +0000
210 210 summary: b
211 211
212 212 $ hg debugbundle .hg/strip-backup/*
213 213 Stream params: sortdict([('Compression', 'BZ')])
214 214 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
215 215 264128213d290d868c54642d13aeaa3675551a78
216 216 $ hg pull .hg/strip-backup/*
217 217 pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg
218 218 searching for changes
219 219 adding changesets
220 220 adding manifests
221 221 adding file changes
222 222 added 1 changesets with 0 changes to 0 files (+1 heads)
223 223 (run 'hg heads' to see heads, 'hg merge' to merge)
224 224 $ rm .hg/strip-backup/*
225 225 $ hg log --graph
226 226 o changeset: 4:264128213d29
227 227 | tag: tip
228 228 | parent: 1:ef3a871183d7
229 229 | user: test
230 230 | date: Thu Jan 01 00:00:00 1970 +0000
231 231 | summary: c
232 232 |
233 233 | o changeset: 3:443431ffac4f
234 234 | | user: test
235 235 | | date: Thu Jan 01 00:00:00 1970 +0000
236 236 | | summary: e
237 237 | |
238 238 | o changeset: 2:65bd5f99a4a3
239 239 |/ user: test
240 240 | date: Thu Jan 01 00:00:00 1970 +0000
241 241 | summary: d
242 242 |
243 243 @ changeset: 1:ef3a871183d7
244 244 | user: test
245 245 | date: Thu Jan 01 00:00:00 1970 +0000
246 246 | summary: b
247 247 |
248 248 o changeset: 0:9ab35a2d17cb
249 249 user: test
250 250 date: Thu Jan 01 00:00:00 1970 +0000
251 251 summary: a
252 252
253 253 $ hg up -C 2
254 254 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 255 $ hg merge 4
256 256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 257 (branch merge, don't forget to commit)
258 258
259 259 before strip of merge parent
260 260
261 261 $ hg parents
262 262 changeset: 2:65bd5f99a4a3
263 263 user: test
264 264 date: Thu Jan 01 00:00:00 1970 +0000
265 265 summary: d
266 266
267 267 changeset: 4:264128213d29
268 268 tag: tip
269 269 parent: 1:ef3a871183d7
270 270 user: test
271 271 date: Thu Jan 01 00:00:00 1970 +0000
272 272 summary: c
273 273
274 274 $ hg strip 4
275 275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 276 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
277 277
278 278 after strip of merge parent
279 279
280 280 $ hg parents
281 281 changeset: 1:ef3a871183d7
282 282 user: test
283 283 date: Thu Jan 01 00:00:00 1970 +0000
284 284 summary: b
285 285
286 286 $ restore
287 287
288 288 $ hg up
289 289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 290 1 other heads for branch "default"
291 291 $ hg log -G
292 292 @ changeset: 4:264128213d29
293 293 | tag: tip
294 294 | parent: 1:ef3a871183d7
295 295 | user: test
296 296 | date: Thu Jan 01 00:00:00 1970 +0000
297 297 | summary: c
298 298 |
299 299 | o changeset: 3:443431ffac4f
300 300 | | user: test
301 301 | | date: Thu Jan 01 00:00:00 1970 +0000
302 302 | | summary: e
303 303 | |
304 304 | o changeset: 2:65bd5f99a4a3
305 305 |/ user: test
306 306 | date: Thu Jan 01 00:00:00 1970 +0000
307 307 | summary: d
308 308 |
309 309 o changeset: 1:ef3a871183d7
310 310 | user: test
311 311 | date: Thu Jan 01 00:00:00 1970 +0000
312 312 | summary: b
313 313 |
314 314 o changeset: 0:9ab35a2d17cb
315 315 user: test
316 316 date: Thu Jan 01 00:00:00 1970 +0000
317 317 summary: a
318 318
319 319
320 320 2 is parent of 3, only one strip should happen
321 321
322 322 $ hg strip "roots(2)" 3
323 323 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
324 324 $ hg log -G
325 325 @ changeset: 2:264128213d29
326 326 | tag: tip
327 327 | user: test
328 328 | date: Thu Jan 01 00:00:00 1970 +0000
329 329 | summary: c
330 330 |
331 331 o changeset: 1:ef3a871183d7
332 332 | user: test
333 333 | date: Thu Jan 01 00:00:00 1970 +0000
334 334 | summary: b
335 335 |
336 336 o changeset: 0:9ab35a2d17cb
337 337 user: test
338 338 date: Thu Jan 01 00:00:00 1970 +0000
339 339 summary: a
340 340
341 341 $ restore
342 342 $ hg log -G
343 343 o changeset: 4:443431ffac4f
344 344 | tag: tip
345 345 | user: test
346 346 | date: Thu Jan 01 00:00:00 1970 +0000
347 347 | summary: e
348 348 |
349 349 o changeset: 3:65bd5f99a4a3
350 350 | parent: 1:ef3a871183d7
351 351 | user: test
352 352 | date: Thu Jan 01 00:00:00 1970 +0000
353 353 | summary: d
354 354 |
355 355 | @ changeset: 2:264128213d29
356 356 |/ user: test
357 357 | date: Thu Jan 01 00:00:00 1970 +0000
358 358 | summary: c
359 359 |
360 360 o changeset: 1:ef3a871183d7
361 361 | user: test
362 362 | date: Thu Jan 01 00:00:00 1970 +0000
363 363 | summary: b
364 364 |
365 365 o changeset: 0:9ab35a2d17cb
366 366 user: test
367 367 date: Thu Jan 01 00:00:00 1970 +0000
368 368 summary: a
369 369
370 370 Failed hook while applying "saveheads" bundle.
371 371
372 372 $ hg strip 2 --config hooks.pretxnchangegroup.bad=false
373 373 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 374 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
375 375 transaction abort!
376 376 rollback completed
377 strip failed, full bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
377 strip failed, backup bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
378 378 strip failed, unrecovered changes stored in '$TESTTMP/test/.hg/strip-backup/*-temp.hg' (glob)
379 379 (fix the problem, then recover the changesets with "hg unbundle '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)
380 380 abort: pretxnchangegroup.bad hook exited with status 1
381 381 [255]
382 382 $ restore
383 383 $ hg log -G
384 384 o changeset: 4:443431ffac4f
385 385 | tag: tip
386 386 | user: test
387 387 | date: Thu Jan 01 00:00:00 1970 +0000
388 388 | summary: e
389 389 |
390 390 o changeset: 3:65bd5f99a4a3
391 391 | parent: 1:ef3a871183d7
392 392 | user: test
393 393 | date: Thu Jan 01 00:00:00 1970 +0000
394 394 | summary: d
395 395 |
396 396 | o changeset: 2:264128213d29
397 397 |/ user: test
398 398 | date: Thu Jan 01 00:00:00 1970 +0000
399 399 | summary: c
400 400 |
401 401 @ changeset: 1:ef3a871183d7
402 402 | user: test
403 403 | date: Thu Jan 01 00:00:00 1970 +0000
404 404 | summary: b
405 405 |
406 406 o changeset: 0:9ab35a2d17cb
407 407 user: test
408 408 date: Thu Jan 01 00:00:00 1970 +0000
409 409 summary: a
410 410
411 411
412 412 2 different branches: 2 strips
413 413
414 414 $ hg strip 2 4
415 415 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
416 416 $ hg log -G
417 417 o changeset: 2:65bd5f99a4a3
418 418 | tag: tip
419 419 | user: test
420 420 | date: Thu Jan 01 00:00:00 1970 +0000
421 421 | summary: d
422 422 |
423 423 @ changeset: 1:ef3a871183d7
424 424 | user: test
425 425 | date: Thu Jan 01 00:00:00 1970 +0000
426 426 | summary: b
427 427 |
428 428 o changeset: 0:9ab35a2d17cb
429 429 user: test
430 430 date: Thu Jan 01 00:00:00 1970 +0000
431 431 summary: a
432 432
433 433 $ restore
434 434
435 435 2 different branches and a common ancestor: 1 strip
436 436
437 437 $ hg strip 1 "2|4"
438 438 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
439 439 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
440 440 $ restore
441 441
442 442 verify fncache is kept up-to-date
443 443
444 444 $ touch a
445 445 $ hg ci -qAm a
446 446 $ cat .hg/store/fncache | sort
447 447 data/a.i
448 448 data/bar.i
449 449 $ hg strip tip
450 450 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
451 451 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
452 452 $ cat .hg/store/fncache
453 453 data/bar.i
454 454
455 455 stripping an empty revset
456 456
457 457 $ hg strip "1 and not 1"
458 458 abort: empty revision set
459 459 [255]
460 460
461 461 remove branchy history for qimport tests
462 462
463 463 $ hg strip 3
464 464 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
465 465
466 466
467 467 strip of applied mq should cleanup status file
468 468
469 469 $ echo "mq=" >> $HGRCPATH
470 470 $ hg up -C 3
471 471 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 472 $ echo fooagain >> bar
473 473 $ hg ci -mf
474 474 $ hg qimport -r tip:2
475 475
476 476 applied patches before strip
477 477
478 478 $ hg qapplied
479 479 d
480 480 e
481 481 f
482 482
483 483 stripping revision in queue
484 484
485 485 $ hg strip 3
486 486 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
487 487 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
488 488
489 489 applied patches after stripping rev in queue
490 490
491 491 $ hg qapplied
492 492 d
493 493
494 494 stripping ancestor of queue
495 495
496 496 $ hg strip 1
497 497 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
498 498 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
499 499
500 500 applied patches after stripping ancestor of queue
501 501
502 502 $ hg qapplied
503 503
504 504 Verify strip protects against stripping wc parent when there are uncommitted mods
505 505
506 506 $ echo b > b
507 507 $ echo bb > bar
508 508 $ hg add b
509 509 $ hg ci -m 'b'
510 510 $ hg log --graph
511 511 @ changeset: 1:76dcf9fab855
512 512 | tag: tip
513 513 | user: test
514 514 | date: Thu Jan 01 00:00:00 1970 +0000
515 515 | summary: b
516 516 |
517 517 o changeset: 0:9ab35a2d17cb
518 518 user: test
519 519 date: Thu Jan 01 00:00:00 1970 +0000
520 520 summary: a
521 521
522 522 $ hg up 0
523 523 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
524 524 $ echo c > bar
525 525 $ hg up -t false
526 526 merging bar
527 527 merging bar failed!
528 528 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
529 529 use 'hg resolve' to retry unresolved file merges
530 530 [1]
531 531 $ hg sum
532 532 parent: 1:76dcf9fab855 tip
533 533 b
534 534 branch: default
535 535 commit: 1 modified, 1 unknown, 1 unresolved
536 536 update: (current)
537 537 phases: 2 draft
538 538 mq: 3 unapplied
539 539
540 540 $ echo c > b
541 541 $ hg strip tip
542 542 abort: local changes found
543 543 [255]
544 544 $ hg strip tip --keep
545 545 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
546 546 $ hg log --graph
547 547 @ changeset: 0:9ab35a2d17cb
548 548 tag: tip
549 549 user: test
550 550 date: Thu Jan 01 00:00:00 1970 +0000
551 551 summary: a
552 552
553 553 $ hg status
554 554 M bar
555 555 ? b
556 556 ? bar.orig
557 557
558 558 $ rm bar.orig
559 559 $ hg sum
560 560 parent: 0:9ab35a2d17cb tip
561 561 a
562 562 branch: default
563 563 commit: 1 modified, 1 unknown
564 564 update: (current)
565 565 phases: 1 draft
566 566 mq: 3 unapplied
567 567
568 568 Strip adds, removes, modifies with --keep
569 569
570 570 $ touch b
571 571 $ hg add b
572 572 $ hg commit -mb
573 573 $ touch c
574 574
575 575 ... with a clean working dir
576 576
577 577 $ hg add c
578 578 $ hg rm bar
579 579 $ hg commit -mc
580 580 $ hg status
581 581 $ hg strip --keep tip
582 582 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
583 583 $ hg status
584 584 ! bar
585 585 ? c
586 586
587 587 ... with a dirty working dir
588 588
589 589 $ hg add c
590 590 $ hg rm bar
591 591 $ hg commit -mc
592 592 $ hg status
593 593 $ echo b > b
594 594 $ echo d > d
595 595 $ hg strip --keep tip
596 596 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
597 597 $ hg status
598 598 M b
599 599 ! bar
600 600 ? c
601 601 ? d
602 602
603 603 ... after updating the dirstate
604 604 $ hg add c
605 605 $ hg commit -mc
606 606 $ hg rm c
607 607 $ hg commit -mc
608 608 $ hg strip --keep '.^' -q
609 609 $ cd ..
610 610
611 611 stripping many nodes on a complex graph (issue3299)
612 612
613 613 $ hg init issue3299
614 614 $ cd issue3299
615 615 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
616 616 $ hg strip 'not ancestors(x)'
617 617 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
618 618
619 619 test hg strip -B bookmark
620 620
621 621 $ cd ..
622 622 $ hg init bookmarks
623 623 $ cd bookmarks
624 624 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
625 625 $ hg bookmark -r 'a' 'todelete'
626 626 $ hg bookmark -r 'b' 'B'
627 627 $ hg bookmark -r 'b' 'nostrip'
628 628 $ hg bookmark -r 'c' 'delete'
629 629 $ hg bookmark -r 'd' 'multipledelete1'
630 630 $ hg bookmark -r 'e' 'multipledelete2'
631 631 $ hg bookmark -r 'f' 'singlenode1'
632 632 $ hg bookmark -r 'f' 'singlenode2'
633 633 $ hg up -C todelete
634 634 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
635 635 (activating bookmark todelete)
636 636 $ hg strip -B nostrip
637 637 bookmark 'nostrip' deleted
638 638 abort: empty revision set
639 639 [255]
640 640 $ hg strip -B todelete
641 641 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
642 642 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
643 643 bookmark 'todelete' deleted
644 644 $ hg id -ir dcbb326fdec2
645 645 abort: unknown revision 'dcbb326fdec2'!
646 646 [255]
647 647 $ hg id -ir d62d843c9a01
648 648 d62d843c9a01
649 649 $ hg bookmarks
650 650 B 9:ff43616e5d0f
651 651 delete 6:2702dd0c91e7
652 652 multipledelete1 11:e46a4836065c
653 653 multipledelete2 12:b4594d867745
654 654 singlenode1 13:43227190fef8
655 655 singlenode2 13:43227190fef8
656 656 $ hg strip -B multipledelete1 -B multipledelete2
657 657 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg (glob)
658 658 bookmark 'multipledelete1' deleted
659 659 bookmark 'multipledelete2' deleted
660 660 $ hg id -ir e46a4836065c
661 661 abort: unknown revision 'e46a4836065c'!
662 662 [255]
663 663 $ hg id -ir b4594d867745
664 664 abort: unknown revision 'b4594d867745'!
665 665 [255]
666 666 $ hg strip -B singlenode1 -B singlenode2
667 667 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg (glob)
668 668 bookmark 'singlenode1' deleted
669 669 bookmark 'singlenode2' deleted
670 670 $ hg id -ir 43227190fef8
671 671 abort: unknown revision '43227190fef8'!
672 672 [255]
673 673 $ hg strip -B unknownbookmark
674 674 abort: bookmark 'unknownbookmark' not found
675 675 [255]
676 676 $ hg strip -B unknownbookmark1 -B unknownbookmark2
677 677 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
678 678 [255]
679 679 $ hg strip -B delete -B unknownbookmark
680 680 abort: bookmark 'unknownbookmark' not found
681 681 [255]
682 682 $ hg strip -B delete
683 683 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
684 684 bookmark 'delete' deleted
685 685 $ hg id -ir 6:2702dd0c91e7
686 686 abort: unknown revision '2702dd0c91e7'!
687 687 [255]
688 688 $ hg update B
689 689 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
690 690 (activating bookmark B)
691 691 $ echo a > a
692 692 $ hg add a
693 693 $ hg strip -B B
694 694 abort: local changes found
695 695 [255]
696 696 $ hg bookmarks
697 697 * B 6:ff43616e5d0f
698 698
699 699 Make sure no one adds back a -b option:
700 700
701 701 $ hg strip -b tip
702 702 hg strip: option -b not recognized
703 703 hg strip [-k] [-f] [-B bookmark] [-r] REV...
704 704
705 705 strip changesets and all their descendants from the repository
706 706
707 707 (use "hg help -e strip" to show help for the strip extension)
708 708
709 709 options ([+] can be repeated):
710 710
711 711 -r --rev REV [+] strip specified revision (optional, can specify
712 712 revisions without this option)
713 713 -f --force force removal of changesets, discard uncommitted
714 714 changes (no backup)
715 715 --no-backup no backups
716 716 -k --keep do not modify working directory during strip
717 717 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
718 718 --mq operate on patch repository
719 719
720 720 (use "hg strip -h" to show more help)
721 721 [255]
722 722
723 723 $ cd ..
724 724
725 725 Verify bundles don't get overwritten:
726 726
727 727 $ hg init doublebundle
728 728 $ cd doublebundle
729 729 $ touch a
730 730 $ hg commit -Aqm a
731 731 $ touch b
732 732 $ hg commit -Aqm b
733 733 $ hg strip -r 0
734 734 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
735 735 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob)
736 736 $ ls .hg/strip-backup
737 737 3903775176ed-e68910bd-backup.hg
738 738 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
739 739 $ hg strip -r 0
740 740 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob)
741 741 $ ls .hg/strip-backup
742 742 3903775176ed-54390173-backup.hg
743 743 3903775176ed-e68910bd-backup.hg
744 744 $ cd ..
745 745
746 746 Test that we only bundle the stripped changesets (issue4736)
747 747 ------------------------------------------------------------
748 748
749 749 initialization (previous repo is empty anyway)
750 750
751 751 $ hg init issue4736
752 752 $ cd issue4736
753 753 $ echo a > a
754 754 $ hg add a
755 755 $ hg commit -m commitA
756 756 $ echo b > b
757 757 $ hg add b
758 758 $ hg commit -m commitB
759 759 $ echo c > c
760 760 $ hg add c
761 761 $ hg commit -m commitC
762 762 $ hg up 'desc(commitB)'
763 763 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
764 764 $ echo d > d
765 765 $ hg add d
766 766 $ hg commit -m commitD
767 767 created new head
768 768 $ hg up 'desc(commitC)'
769 769 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
770 770 $ hg merge 'desc(commitD)'
771 771 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
772 772 (branch merge, don't forget to commit)
773 773 $ hg ci -m 'mergeCD'
774 774 $ hg log -G
775 775 @ changeset: 4:d8db9d137221
776 776 |\ tag: tip
777 777 | | parent: 2:5c51d8d6557d
778 778 | | parent: 3:6625a5168474
779 779 | | user: test
780 780 | | date: Thu Jan 01 00:00:00 1970 +0000
781 781 | | summary: mergeCD
782 782 | |
783 783 | o changeset: 3:6625a5168474
784 784 | | parent: 1:eca11cf91c71
785 785 | | user: test
786 786 | | date: Thu Jan 01 00:00:00 1970 +0000
787 787 | | summary: commitD
788 788 | |
789 789 o | changeset: 2:5c51d8d6557d
790 790 |/ user: test
791 791 | date: Thu Jan 01 00:00:00 1970 +0000
792 792 | summary: commitC
793 793 |
794 794 o changeset: 1:eca11cf91c71
795 795 | user: test
796 796 | date: Thu Jan 01 00:00:00 1970 +0000
797 797 | summary: commitB
798 798 |
799 799 o changeset: 0:105141ef12d0
800 800 user: test
801 801 date: Thu Jan 01 00:00:00 1970 +0000
802 802 summary: commitA
803 803
804 804
805 805 Check bundle behavior:
806 806
807 807 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
808 808 2 changesets found
809 809 $ hg log -r 'bundle()' -R ../issue4736.hg
810 810 changeset: 3:6625a5168474
811 811 parent: 1:eca11cf91c71
812 812 user: test
813 813 date: Thu Jan 01 00:00:00 1970 +0000
814 814 summary: commitD
815 815
816 816 changeset: 4:d8db9d137221
817 817 tag: tip
818 818 parent: 2:5c51d8d6557d
819 819 parent: 3:6625a5168474
820 820 user: test
821 821 date: Thu Jan 01 00:00:00 1970 +0000
822 822 summary: mergeCD
823 823
824 824
825 825 check strip behavior
826 826
827 827 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
828 828 resolving manifests
829 829 branchmerge: False, force: True, partial: False
830 830 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
831 831 c: other deleted -> r
832 832 removing c
833 833 d: other deleted -> r
834 834 removing d
835 835 starting 4 threads for background file closing (?)
836 836 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
837 837 2 changesets found
838 838 list of changesets:
839 839 6625a516847449b6f0fa3737b9ba56e9f0f3032c
840 840 d8db9d1372214336d2b5570f20ee468d2c72fa8b
841 841 bundle2-output-bundle: "HG20", (1 params) 1 parts total
842 842 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
843 843 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
844 844 invalid branchheads cache (served): tip differs
845 845 truncating cache/rbc-revs-v1 to 24
846 846 $ hg log -G
847 847 o changeset: 2:5c51d8d6557d
848 848 | tag: tip
849 849 | user: test
850 850 | date: Thu Jan 01 00:00:00 1970 +0000
851 851 | summary: commitC
852 852 |
853 853 @ changeset: 1:eca11cf91c71
854 854 | user: test
855 855 | date: Thu Jan 01 00:00:00 1970 +0000
856 856 | summary: commitB
857 857 |
858 858 o changeset: 0:105141ef12d0
859 859 user: test
860 860 date: Thu Jan 01 00:00:00 1970 +0000
861 861 summary: commitA
862 862
863 863
864 864 strip backup content
865 865
866 866 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
867 867 changeset: 3:6625a5168474
868 868 parent: 1:eca11cf91c71
869 869 user: test
870 870 date: Thu Jan 01 00:00:00 1970 +0000
871 871 summary: commitD
872 872
873 873 changeset: 4:d8db9d137221
874 874 tag: tip
875 875 parent: 2:5c51d8d6557d
876 876 parent: 3:6625a5168474
877 877 user: test
878 878 date: Thu Jan 01 00:00:00 1970 +0000
879 879 summary: mergeCD
880 880
881 881 Check that the phase cache is properly invalidated after a strip with bookmark.
882 882
883 883 $ cat > ../stripstalephasecache.py << EOF
884 884 > from mercurial import extensions, localrepo
885 885 > def transactioncallback(orig, repo, desc, *args, **kwargs):
886 886 > def test(transaction):
887 887 > # observe cache inconsistency
888 888 > try:
889 889 > [repo.changelog.node(r) for r in repo.revs("not public()")]
890 890 > except IndexError:
891 891 > repo.ui.status("Index error!\n")
892 892 > transaction = orig(repo, desc, *args, **kwargs)
893 893 > # warm up the phase cache
894 894 > list(repo.revs("not public()"))
895 895 > if desc != 'strip':
896 896 > transaction.addpostclose("phase invalidation test", test)
897 897 > return transaction
898 898 > def extsetup(ui):
899 899 > extensions.wrapfunction(localrepo.localrepository, "transaction",
900 900 > transactioncallback)
901 901 > EOF
902 902 $ hg up -C 2
903 903 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
904 904 $ echo k > k
905 905 $ hg add k
906 906 $ hg commit -m commitK
907 907 $ echo l > l
908 908 $ hg add l
909 909 $ hg commit -m commitL
910 910 $ hg book -r tip blah
911 911 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
912 912 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
913 913 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg (glob)
914 914 $ hg up -C 1
915 915 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
916 916
917 917 Error during post-close callback of the strip transaction
918 918 (They should be gracefully handled and reported)
919 919
920 920 $ cat > ../crashstrip.py << EOF
921 921 > from mercurial import error
922 922 > def reposetup(ui, repo):
923 923 > class crashstriprepo(repo.__class__):
924 924 > def transaction(self, desc, *args, **kwargs):
925 925 > tr = super(crashstriprepo, self).transaction(self, desc, *args, **kwargs)
926 926 > if desc == 'strip':
927 927 > def crash(tra): raise error.Abort('boom')
928 928 > tr.addpostclose('crash', crash)
929 929 > return tr
930 930 > repo.__class__ = crashstriprepo
931 931 > EOF
932 932 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
933 933 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob)
934 strip failed, full bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
934 strip failed, backup bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
935 935 abort: boom
936 936 [255]
937 937
938 938
General Comments 0
You need to be logged in to leave comments. Login now