##// END OF EJS Templates
strip: invalidate phase cache after stripping changeset (issue5235)...
Laurent Charignon -
r29196:bf7b8157 stable
parent child Browse files
Show More
@@ -1,345 +1,346 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
13 13 from .i18n import _
14 14 from .node import short
15 15 from . import (
16 16 bundle2,
17 17 changegroup,
18 18 error,
19 19 exchange,
20 20 obsolete,
21 21 util,
22 22 )
23 23
24 24 def _bundle(repo, bases, heads, node, suffix, compress=True):
25 25 """create a bundle with the specified revisions as a backup"""
26 26 cgversion = changegroup.safeversion(repo)
27 27
28 28 cg = changegroup.changegroupsubset(repo, bases, heads, 'strip',
29 29 version=cgversion)
30 30 backupdir = "strip-backup"
31 31 vfs = repo.vfs
32 32 if not vfs.isdir(backupdir):
33 33 vfs.mkdir(backupdir)
34 34
35 35 # Include a hash of all the nodes in the filename for uniqueness
36 36 allcommits = repo.set('%ln::%ln', bases, heads)
37 37 allhashes = sorted(c.hex() for c in allcommits)
38 38 totalhash = util.sha1(''.join(allhashes)).hexdigest()
39 39 name = "%s/%s-%s-%s.hg" % (backupdir, short(node), totalhash[:8], suffix)
40 40
41 41 comp = None
42 42 if cgversion != '01':
43 43 bundletype = "HG20"
44 44 if compress:
45 45 comp = 'BZ'
46 46 elif compress:
47 47 bundletype = "HG10BZ"
48 48 else:
49 49 bundletype = "HG10UN"
50 50 return bundle2.writebundle(repo.ui, cg, name, bundletype, vfs,
51 51 compression=comp)
52 52
53 53 def _collectfiles(repo, striprev):
54 54 """find out the filelogs affected by the strip"""
55 55 files = set()
56 56
57 57 for x in xrange(striprev, len(repo)):
58 58 files.update(repo[x].files())
59 59
60 60 return sorted(files)
61 61
62 62 def _collectbrokencsets(repo, files, striprev):
63 63 """return the changesets which will be broken by the truncation"""
64 64 s = set()
65 65 def collectone(revlog):
66 66 _, brokenset = revlog.getstrippoint(striprev)
67 67 s.update([revlog.linkrev(r) for r in brokenset])
68 68
69 69 collectone(repo.manifest)
70 70 for fname in files:
71 71 collectone(repo.file(fname))
72 72
73 73 return s
74 74
75 75 def strip(ui, repo, nodelist, backup=True, topic='backup'):
76 76 # This function operates within a transaction of its own, but does
77 77 # not take any lock on the repo.
78 78 # Simple way to maintain backwards compatibility for this
79 79 # argument.
80 80 if backup in ['none', 'strip']:
81 81 backup = False
82 82
83 83 repo = repo.unfiltered()
84 84 repo.destroying()
85 85
86 86 cl = repo.changelog
87 87 # TODO handle undo of merge sets
88 88 if isinstance(nodelist, str):
89 89 nodelist = [nodelist]
90 90 striplist = [cl.rev(node) for node in nodelist]
91 91 striprev = min(striplist)
92 92
93 93 # Some revisions with rev > striprev may not be descendants of striprev.
94 94 # We have to find these revisions and put them in a bundle, so that
95 95 # we can restore them after the truncations.
96 96 # To create the bundle we use repo.changegroupsubset which requires
97 97 # the list of heads and bases of the set of interesting revisions.
98 98 # (head = revision in the set that has no descendant in the set;
99 99 # base = revision in the set that has no ancestor in the set)
100 100 tostrip = set(striplist)
101 101 for rev in striplist:
102 102 for desc in cl.descendants([rev]):
103 103 tostrip.add(desc)
104 104
105 105 files = _collectfiles(repo, striprev)
106 106 saverevs = _collectbrokencsets(repo, files, striprev)
107 107
108 108 # compute heads
109 109 saveheads = set(saverevs)
110 110 for r in xrange(striprev + 1, len(cl)):
111 111 if r not in tostrip:
112 112 saverevs.add(r)
113 113 saveheads.difference_update(cl.parentrevs(r))
114 114 saveheads.add(r)
115 115 saveheads = [cl.node(r) for r in saveheads]
116 116
117 117 # compute base nodes
118 118 if saverevs:
119 119 descendants = set(cl.descendants(saverevs))
120 120 saverevs.difference_update(descendants)
121 121 savebases = [cl.node(r) for r in saverevs]
122 122 stripbases = [cl.node(r) for r in tostrip]
123 123
124 124 # For a set s, max(parents(s) - s) is the same as max(heads(::s - s)), but
125 125 # is much faster
126 126 newbmtarget = repo.revs('max(parents(%ld) - (%ld))', tostrip, tostrip)
127 127 if newbmtarget:
128 128 newbmtarget = repo[newbmtarget.first()].node()
129 129 else:
130 130 newbmtarget = '.'
131 131
132 132 bm = repo._bookmarks
133 133 updatebm = []
134 134 for m in bm:
135 135 rev = repo[bm[m]].rev()
136 136 if rev in tostrip:
137 137 updatebm.append(m)
138 138
139 139 # create a changegroup for all the branches we need to keep
140 140 backupfile = None
141 141 vfs = repo.vfs
142 142 node = nodelist[-1]
143 143 if backup:
144 144 backupfile = _bundle(repo, stripbases, cl.heads(), node, topic)
145 145 repo.ui.status(_("saved backup bundle to %s\n") %
146 146 vfs.join(backupfile))
147 147 repo.ui.log("backupbundle", "saved backup bundle to %s\n",
148 148 vfs.join(backupfile))
149 149 if saveheads or savebases:
150 150 # do not compress partial bundle if we remove it from disk later
151 151 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
152 152 compress=False)
153 153
154 154 mfst = repo.manifest
155 155
156 156 curtr = repo.currenttransaction()
157 157 if curtr is not None:
158 158 del curtr # avoid carrying reference to transaction for nothing
159 159 msg = _('programming error: cannot strip from inside a transaction')
160 160 raise error.Abort(msg, hint=_('contact your extension maintainer'))
161 161
162 162 try:
163 163 with repo.transaction("strip") as tr:
164 164 offset = len(tr.entries)
165 165
166 166 tr.startgroup()
167 167 cl.strip(striprev, tr)
168 168 mfst.strip(striprev, tr)
169 169 for fn in files:
170 170 repo.file(fn).strip(striprev, tr)
171 171 tr.endgroup()
172 172
173 173 for i in xrange(offset, len(tr.entries)):
174 174 file, troffset, ignore = tr.entries[i]
175 175 repo.svfs(file, 'a').truncate(troffset)
176 176 if troffset == 0:
177 177 repo.store.markremoved(file)
178 178
179 179 if saveheads or savebases:
180 180 ui.note(_("adding branch\n"))
181 181 f = vfs.open(chgrpfile, "rb")
182 182 gen = exchange.readbundle(ui, f, chgrpfile, vfs)
183 183 if not repo.ui.verbose:
184 184 # silence internal shuffling chatter
185 185 repo.ui.pushbuffer()
186 186 if isinstance(gen, bundle2.unbundle20):
187 187 with repo.transaction('strip') as tr:
188 188 tr.hookargs = {'source': 'strip',
189 189 'url': 'bundle:' + vfs.join(chgrpfile)}
190 190 bundle2.applybundle(repo, gen, tr, source='strip',
191 191 url='bundle:' + vfs.join(chgrpfile))
192 192 else:
193 193 gen.apply(repo, 'strip', 'bundle:' + vfs.join(chgrpfile), True)
194 194 if not repo.ui.verbose:
195 195 repo.ui.popbuffer()
196 196 f.close()
197 repo._phasecache.invalidate()
197 198
198 199 for m in updatebm:
199 200 bm[m] = repo[newbmtarget].node()
200 201 lock = tr = None
201 202 try:
202 203 lock = repo.lock()
203 204 tr = repo.transaction('repair')
204 205 bm.recordchange(tr)
205 206 tr.close()
206 207 finally:
207 208 tr.release()
208 209 lock.release()
209 210
210 211 # remove undo files
211 212 for undovfs, undofile in repo.undofiles():
212 213 try:
213 214 undovfs.unlink(undofile)
214 215 except OSError as e:
215 216 if e.errno != errno.ENOENT:
216 217 ui.warn(_('error removing %s: %s\n') %
217 218 (undovfs.join(undofile), str(e)))
218 219
219 220 except: # re-raises
220 221 if backupfile:
221 222 ui.warn(_("strip failed, full bundle stored in '%s'\n")
222 223 % vfs.join(backupfile))
223 224 elif saveheads:
224 225 ui.warn(_("strip failed, partial bundle stored in '%s'\n")
225 226 % vfs.join(chgrpfile))
226 227 raise
227 228 else:
228 229 if saveheads or savebases:
229 230 # Remove partial backup only if there were no exceptions
230 231 vfs.unlink(chgrpfile)
231 232
232 233 repo.destroyed()
233 234
234 235 def rebuildfncache(ui, repo):
235 236 """Rebuilds the fncache file from repo history.
236 237
237 238 Missing entries will be added. Extra entries will be removed.
238 239 """
239 240 repo = repo.unfiltered()
240 241
241 242 if 'fncache' not in repo.requirements:
242 243 ui.warn(_('(not rebuilding fncache because repository does not '
243 244 'support fncache)\n'))
244 245 return
245 246
246 247 with repo.lock():
247 248 fnc = repo.store.fncache
248 249 # Trigger load of fncache.
249 250 if 'irrelevant' in fnc:
250 251 pass
251 252
252 253 oldentries = set(fnc.entries)
253 254 newentries = set()
254 255 seenfiles = set()
255 256
256 257 repolen = len(repo)
257 258 for rev in repo:
258 259 ui.progress(_('rebuilding'), rev, total=repolen,
259 260 unit=_('changesets'))
260 261
261 262 ctx = repo[rev]
262 263 for f in ctx.files():
263 264 # This is to minimize I/O.
264 265 if f in seenfiles:
265 266 continue
266 267 seenfiles.add(f)
267 268
268 269 i = 'data/%s.i' % f
269 270 d = 'data/%s.d' % f
270 271
271 272 if repo.store._exists(i):
272 273 newentries.add(i)
273 274 if repo.store._exists(d):
274 275 newentries.add(d)
275 276
276 277 ui.progress(_('rebuilding'), None)
277 278
278 279 if 'treemanifest' in repo.requirements: # safe but unnecessary otherwise
279 280 for dir in util.dirs(seenfiles):
280 281 i = 'meta/%s/00manifest.i' % dir
281 282 d = 'meta/%s/00manifest.d' % dir
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 addcount = len(newentries - oldentries)
289 290 removecount = len(oldentries - newentries)
290 291 for p in sorted(oldentries - newentries):
291 292 ui.write(_('removing %s\n') % p)
292 293 for p in sorted(newentries - oldentries):
293 294 ui.write(_('adding %s\n') % p)
294 295
295 296 if addcount or removecount:
296 297 ui.write(_('%d items added, %d removed from fncache\n') %
297 298 (addcount, removecount))
298 299 fnc.entries = newentries
299 300 fnc._dirty = True
300 301
301 302 with repo.transaction('fncache') as tr:
302 303 fnc.write(tr)
303 304 else:
304 305 ui.write(_('fncache already up to date\n'))
305 306
306 307 def stripbmrevset(repo, mark):
307 308 """
308 309 The revset to strip when strip is called with -B mark
309 310
310 311 Needs to live here so extensions can use it and wrap it even when strip is
311 312 not enabled or not present on a box.
312 313 """
313 314 return repo.revs("ancestors(bookmark(%s)) - "
314 315 "ancestors(head() and not bookmark(%s)) - "
315 316 "ancestors(bookmark() and not bookmark(%s))",
316 317 mark, mark, mark)
317 318
318 319 def deleteobsmarkers(obsstore, indices):
319 320 """Delete some obsmarkers from obsstore and return how many were deleted
320 321
321 322 'indices' is a list of ints which are the indices
322 323 of the markers to be deleted.
323 324
324 325 Every invocation of this function completely rewrites the obsstore file,
325 326 skipping the markers we want to be removed. The new temporary file is
326 327 created, remaining markers are written there and on .close() this file
327 328 gets atomically renamed to obsstore, thus guaranteeing consistency."""
328 329 if not indices:
329 330 # we don't want to rewrite the obsstore with the same content
330 331 return
331 332
332 333 left = []
333 334 current = obsstore._all
334 335 n = 0
335 336 for i, m in enumerate(current):
336 337 if i in indices:
337 338 n += 1
338 339 continue
339 340 left.append(m)
340 341
341 342 newobsstorefile = obsstore.svfs('obsstore', 'w', atomictemp=True)
342 343 for bytes in obsolete.encodemarkers(left, True, obsstore._version):
343 344 newobsstorefile.write(bytes)
344 345 newobsstorefile.close()
345 346 return n
@@ -1,863 +1,898 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: {'Compression': 'BZ'}
214 214 changegroup -- "{'version': '02'}"
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
371 371 2 different branches: 2 strips
372 372
373 373 $ hg strip 2 4
374 374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 375 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
376 376 $ hg log -G
377 377 o changeset: 2:65bd5f99a4a3
378 378 | tag: tip
379 379 | user: test
380 380 | date: Thu Jan 01 00:00:00 1970 +0000
381 381 | summary: d
382 382 |
383 383 @ changeset: 1:ef3a871183d7
384 384 | user: test
385 385 | date: Thu Jan 01 00:00:00 1970 +0000
386 386 | summary: b
387 387 |
388 388 o changeset: 0:9ab35a2d17cb
389 389 user: test
390 390 date: Thu Jan 01 00:00:00 1970 +0000
391 391 summary: a
392 392
393 393 $ restore
394 394
395 395 2 different branches and a common ancestor: 1 strip
396 396
397 397 $ hg strip 1 "2|4"
398 398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 399 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
400 400 $ restore
401 401
402 402 verify fncache is kept up-to-date
403 403
404 404 $ touch a
405 405 $ hg ci -qAm a
406 406 $ cat .hg/store/fncache | sort
407 407 data/a.i
408 408 data/bar.i
409 409 $ hg strip tip
410 410 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
411 411 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
412 412 $ cat .hg/store/fncache
413 413 data/bar.i
414 414
415 415 stripping an empty revset
416 416
417 417 $ hg strip "1 and not 1"
418 418 abort: empty revision set
419 419 [255]
420 420
421 421 remove branchy history for qimport tests
422 422
423 423 $ hg strip 3
424 424 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
425 425
426 426
427 427 strip of applied mq should cleanup status file
428 428
429 429 $ echo "mq=" >> $HGRCPATH
430 430 $ hg up -C 3
431 431 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 432 $ echo fooagain >> bar
433 433 $ hg ci -mf
434 434 $ hg qimport -r tip:2
435 435
436 436 applied patches before strip
437 437
438 438 $ hg qapplied
439 439 d
440 440 e
441 441 f
442 442
443 443 stripping revision in queue
444 444
445 445 $ hg strip 3
446 446 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 447 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
448 448
449 449 applied patches after stripping rev in queue
450 450
451 451 $ hg qapplied
452 452 d
453 453
454 454 stripping ancestor of queue
455 455
456 456 $ hg strip 1
457 457 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
458 458 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
459 459
460 460 applied patches after stripping ancestor of queue
461 461
462 462 $ hg qapplied
463 463
464 464 Verify strip protects against stripping wc parent when there are uncommitted mods
465 465
466 466 $ echo b > b
467 467 $ echo bb > bar
468 468 $ hg add b
469 469 $ hg ci -m 'b'
470 470 $ hg log --graph
471 471 @ changeset: 1:76dcf9fab855
472 472 | tag: tip
473 473 | user: test
474 474 | date: Thu Jan 01 00:00:00 1970 +0000
475 475 | summary: b
476 476 |
477 477 o changeset: 0:9ab35a2d17cb
478 478 user: test
479 479 date: Thu Jan 01 00:00:00 1970 +0000
480 480 summary: a
481 481
482 482 $ hg up 0
483 483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 484 $ echo c > bar
485 485 $ hg up -t false
486 486 merging bar
487 487 merging bar failed!
488 488 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
489 489 use 'hg resolve' to retry unresolved file merges
490 490 [1]
491 491 $ hg sum
492 492 parent: 1:76dcf9fab855 tip
493 493 b
494 494 branch: default
495 495 commit: 1 modified, 1 unknown, 1 unresolved
496 496 update: (current)
497 497 phases: 2 draft
498 498 mq: 3 unapplied
499 499
500 500 $ echo c > b
501 501 $ hg strip tip
502 502 abort: local changes found
503 503 [255]
504 504 $ hg strip tip --keep
505 505 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
506 506 $ hg log --graph
507 507 @ changeset: 0:9ab35a2d17cb
508 508 tag: tip
509 509 user: test
510 510 date: Thu Jan 01 00:00:00 1970 +0000
511 511 summary: a
512 512
513 513 $ hg status
514 514 M bar
515 515 ? b
516 516 ? bar.orig
517 517
518 518 $ rm bar.orig
519 519 $ hg sum
520 520 parent: 0:9ab35a2d17cb tip
521 521 a
522 522 branch: default
523 523 commit: 1 modified, 1 unknown
524 524 update: (current)
525 525 phases: 1 draft
526 526 mq: 3 unapplied
527 527
528 528 Strip adds, removes, modifies with --keep
529 529
530 530 $ touch b
531 531 $ hg add b
532 532 $ hg commit -mb
533 533 $ touch c
534 534
535 535 ... with a clean working dir
536 536
537 537 $ hg add c
538 538 $ hg rm bar
539 539 $ hg commit -mc
540 540 $ hg status
541 541 $ hg strip --keep tip
542 542 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
543 543 $ hg status
544 544 ! bar
545 545 ? c
546 546
547 547 ... with a dirty working dir
548 548
549 549 $ hg add c
550 550 $ hg rm bar
551 551 $ hg commit -mc
552 552 $ hg status
553 553 $ echo b > b
554 554 $ echo d > d
555 555 $ hg strip --keep tip
556 556 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
557 557 $ hg status
558 558 M b
559 559 ! bar
560 560 ? c
561 561 ? d
562 562
563 563 ... after updating the dirstate
564 564 $ hg add c
565 565 $ hg commit -mc
566 566 $ hg rm c
567 567 $ hg commit -mc
568 568 $ hg strip --keep '.^' -q
569 569 $ cd ..
570 570
571 571 stripping many nodes on a complex graph (issue3299)
572 572
573 573 $ hg init issue3299
574 574 $ cd issue3299
575 575 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
576 576 $ hg strip 'not ancestors(x)'
577 577 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
578 578
579 579 test hg strip -B bookmark
580 580
581 581 $ cd ..
582 582 $ hg init bookmarks
583 583 $ cd bookmarks
584 584 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
585 585 $ hg bookmark -r 'a' 'todelete'
586 586 $ hg bookmark -r 'b' 'B'
587 587 $ hg bookmark -r 'b' 'nostrip'
588 588 $ hg bookmark -r 'c' 'delete'
589 589 $ hg bookmark -r 'd' 'multipledelete1'
590 590 $ hg bookmark -r 'e' 'multipledelete2'
591 591 $ hg bookmark -r 'f' 'singlenode1'
592 592 $ hg bookmark -r 'f' 'singlenode2'
593 593 $ hg up -C todelete
594 594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 595 (activating bookmark todelete)
596 596 $ hg strip -B nostrip
597 597 bookmark 'nostrip' deleted
598 598 abort: empty revision set
599 599 [255]
600 600 $ hg strip -B todelete
601 601 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
602 602 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
603 603 bookmark 'todelete' deleted
604 604 $ hg id -ir dcbb326fdec2
605 605 abort: unknown revision 'dcbb326fdec2'!
606 606 [255]
607 607 $ hg id -ir d62d843c9a01
608 608 d62d843c9a01
609 609 $ hg bookmarks
610 610 B 9:ff43616e5d0f
611 611 delete 6:2702dd0c91e7
612 612 multipledelete1 11:e46a4836065c
613 613 multipledelete2 12:b4594d867745
614 614 singlenode1 13:43227190fef8
615 615 singlenode2 13:43227190fef8
616 616 $ hg strip -B multipledelete1 -B multipledelete2
617 617 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg (glob)
618 618 bookmark 'multipledelete1' deleted
619 619 bookmark 'multipledelete2' deleted
620 620 $ hg id -ir e46a4836065c
621 621 abort: unknown revision 'e46a4836065c'!
622 622 [255]
623 623 $ hg id -ir b4594d867745
624 624 abort: unknown revision 'b4594d867745'!
625 625 [255]
626 626 $ hg strip -B singlenode1 -B singlenode2
627 627 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg (glob)
628 628 bookmark 'singlenode1' deleted
629 629 bookmark 'singlenode2' deleted
630 630 $ hg id -ir 43227190fef8
631 631 abort: unknown revision '43227190fef8'!
632 632 [255]
633 633 $ hg strip -B unknownbookmark
634 634 abort: bookmark 'unknownbookmark' not found
635 635 [255]
636 636 $ hg strip -B unknownbookmark1 -B unknownbookmark2
637 637 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
638 638 [255]
639 639 $ hg strip -B delete -B unknownbookmark
640 640 abort: bookmark 'unknownbookmark' not found
641 641 [255]
642 642 $ hg strip -B delete
643 643 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
644 644 bookmark 'delete' deleted
645 645 $ hg id -ir 6:2702dd0c91e7
646 646 abort: unknown revision '2702dd0c91e7'!
647 647 [255]
648 648 $ hg update B
649 649 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
650 650 (activating bookmark B)
651 651 $ echo a > a
652 652 $ hg add a
653 653 $ hg strip -B B
654 654 abort: local changes found
655 655 [255]
656 656 $ hg bookmarks
657 657 * B 6:ff43616e5d0f
658 658
659 659 Make sure no one adds back a -b option:
660 660
661 661 $ hg strip -b tip
662 662 hg strip: option -b not recognized
663 663 hg strip [-k] [-f] [-B bookmark] [-r] REV...
664 664
665 665 strip changesets and all their descendants from the repository
666 666
667 667 (use "hg help -e strip" to show help for the strip extension)
668 668
669 669 options ([+] can be repeated):
670 670
671 671 -r --rev REV [+] strip specified revision (optional, can specify
672 672 revisions without this option)
673 673 -f --force force removal of changesets, discard uncommitted
674 674 changes (no backup)
675 675 --no-backup no backups
676 676 -k --keep do not modify working directory during strip
677 677 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
678 678 --mq operate on patch repository
679 679
680 680 (use "hg strip -h" to show more help)
681 681 [255]
682 682
683 683 $ cd ..
684 684
685 685 Verify bundles don't get overwritten:
686 686
687 687 $ hg init doublebundle
688 688 $ cd doublebundle
689 689 $ touch a
690 690 $ hg commit -Aqm a
691 691 $ touch b
692 692 $ hg commit -Aqm b
693 693 $ hg strip -r 0
694 694 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
695 695 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob)
696 696 $ ls .hg/strip-backup
697 697 3903775176ed-e68910bd-backup.hg
698 698 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
699 699 $ hg strip -r 0
700 700 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob)
701 701 $ ls .hg/strip-backup
702 702 3903775176ed-54390173-backup.hg
703 703 3903775176ed-e68910bd-backup.hg
704 704 $ cd ..
705 705
706 706 Test that we only bundle the stripped changesets (issue4736)
707 707 ------------------------------------------------------------
708 708
709 709 initialization (previous repo is empty anyway)
710 710
711 711 $ hg init issue4736
712 712 $ cd issue4736
713 713 $ echo a > a
714 714 $ hg add a
715 715 $ hg commit -m commitA
716 716 $ echo b > b
717 717 $ hg add b
718 718 $ hg commit -m commitB
719 719 $ echo c > c
720 720 $ hg add c
721 721 $ hg commit -m commitC
722 722 $ hg up 'desc(commitB)'
723 723 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
724 724 $ echo d > d
725 725 $ hg add d
726 726 $ hg commit -m commitD
727 727 created new head
728 728 $ hg up 'desc(commitC)'
729 729 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
730 730 $ hg merge 'desc(commitD)'
731 731 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
732 732 (branch merge, don't forget to commit)
733 733 $ hg ci -m 'mergeCD'
734 734 $ hg log -G
735 735 @ changeset: 4:d8db9d137221
736 736 |\ tag: tip
737 737 | | parent: 2:5c51d8d6557d
738 738 | | parent: 3:6625a5168474
739 739 | | user: test
740 740 | | date: Thu Jan 01 00:00:00 1970 +0000
741 741 | | summary: mergeCD
742 742 | |
743 743 | o changeset: 3:6625a5168474
744 744 | | parent: 1:eca11cf91c71
745 745 | | user: test
746 746 | | date: Thu Jan 01 00:00:00 1970 +0000
747 747 | | summary: commitD
748 748 | |
749 749 o | changeset: 2:5c51d8d6557d
750 750 |/ user: test
751 751 | date: Thu Jan 01 00:00:00 1970 +0000
752 752 | summary: commitC
753 753 |
754 754 o changeset: 1:eca11cf91c71
755 755 | user: test
756 756 | date: Thu Jan 01 00:00:00 1970 +0000
757 757 | summary: commitB
758 758 |
759 759 o changeset: 0:105141ef12d0
760 760 user: test
761 761 date: Thu Jan 01 00:00:00 1970 +0000
762 762 summary: commitA
763 763
764 764
765 765 Check bundle behavior:
766 766
767 767 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
768 768 2 changesets found
769 769 $ hg log -r 'bundle()' -R ../issue4736.hg
770 770 changeset: 3:6625a5168474
771 771 parent: 1:eca11cf91c71
772 772 user: test
773 773 date: Thu Jan 01 00:00:00 1970 +0000
774 774 summary: commitD
775 775
776 776 changeset: 4:d8db9d137221
777 777 tag: tip
778 778 parent: 2:5c51d8d6557d
779 779 parent: 3:6625a5168474
780 780 user: test
781 781 date: Thu Jan 01 00:00:00 1970 +0000
782 782 summary: mergeCD
783 783
784 784
785 785 check strip behavior
786 786
787 787 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
788 788 resolving manifests
789 789 branchmerge: False, force: True, partial: False
790 790 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
791 791 c: other deleted -> r
792 792 removing c
793 793 d: other deleted -> r
794 794 removing d
795 795 starting 4 threads for background file closing (?)
796 796 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
797 797 2 changesets found
798 798 list of changesets:
799 799 6625a516847449b6f0fa3737b9ba56e9f0f3032c
800 800 d8db9d1372214336d2b5570f20ee468d2c72fa8b
801 801 bundle2-output-bundle: "HG20", (1 params) 1 parts total
802 802 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
803 803 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
804 804 invalid branchheads cache (served): tip differs
805 805 truncating cache/rbc-revs-v1 to 24
806 806 $ hg log -G
807 807 o changeset: 2:5c51d8d6557d
808 808 | tag: tip
809 809 | user: test
810 810 | date: Thu Jan 01 00:00:00 1970 +0000
811 811 | summary: commitC
812 812 |
813 813 @ changeset: 1:eca11cf91c71
814 814 | user: test
815 815 | date: Thu Jan 01 00:00:00 1970 +0000
816 816 | summary: commitB
817 817 |
818 818 o changeset: 0:105141ef12d0
819 819 user: test
820 820 date: Thu Jan 01 00:00:00 1970 +0000
821 821 summary: commitA
822 822
823 823
824 824 strip backup content
825 825
826 826 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
827 827 changeset: 3:6625a5168474
828 828 parent: 1:eca11cf91c71
829 829 user: test
830 830 date: Thu Jan 01 00:00:00 1970 +0000
831 831 summary: commitD
832 832
833 833 changeset: 4:d8db9d137221
834 834 tag: tip
835 835 parent: 2:5c51d8d6557d
836 836 parent: 3:6625a5168474
837 837 user: test
838 838 date: Thu Jan 01 00:00:00 1970 +0000
839 839 summary: mergeCD
840 840
841 Check that the phase cache is properly invalidated after a strip with bookmark.
842
843 $ cat > ../stripstalephasecache.py << EOF
844 > from mercurial import extensions, localrepo
845 > def transactioncallback(orig, repo, desc, *args, **kwargs):
846 > def test(transaction):
847 > # observe cache inconsistency
848 > try:
849 > [repo.changelog.node(r) for r in repo.revs("not public()")]
850 > except IndexError:
851 > repo.ui.status("Index error!\n")
852 > transaction = orig(repo, desc, *args, **kwargs)
853 > # warm up the phase cache
854 > list(repo.revs("not public()"))
855 > if desc != 'strip':
856 > transaction.addpostclose("phase invalidation test", test)
857 > return transaction
858 > def extsetup(ui):
859 > extensions.wrapfunction(localrepo.localrepository, "transaction",
860 > transactioncallback)
861 > EOF
862 $ hg up -C 2
863 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
864 $ echo k > k
865 $ hg add k
866 $ hg commit -m commitK
867 $ echo l > l
868 $ hg add l
869 $ hg commit -m commitL
870 $ hg book -r tip blah
871 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
872 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
873 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg (glob)
874 $ hg up -C 1
875 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
841 876
842 877 Error during post-close callback of the strip transaction
843 878 (They should be gracefully handled and reported)
844 879
845 880 $ cat > ../crashstrip.py << EOF
846 881 > from mercurial import error
847 882 > def reposetup(ui, repo):
848 883 > class crashstriprepo(repo.__class__):
849 884 > def transaction(self, desc, *args, **kwargs):
850 885 > tr = super(crashstriprepo, self).transaction(self, desc, *args, **kwargs)
851 886 > if desc == 'strip':
852 887 > def crash(tra): raise error.Abort('boom')
853 888 > tr.addpostclose('crash', crash)
854 889 > return tr
855 890 > repo.__class__ = crashstriprepo
856 891 > EOF
857 892 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
858 893 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob)
859 894 strip failed, full bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
860 895 abort: boom
861 896 [255]
862 897
863 898
General Comments 0
You need to be logged in to leave comments. Login now