##// END OF EJS Templates
drawdag: include files from both parents in merge commits...
Martin von Zweigbergk -
r33558:0103e718 default
parent child Browse files
Show More
@@ -1,354 +1,363 b''
1 1 # drawdag.py - convert ASCII revision DAG to actual changesets
2 2 #
3 3 # Copyright 2016 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7 """
8 8 create changesets from an ASCII graph for testing purpose.
9 9
10 10 For example, given the following input::
11 11
12 12 c d
13 13 |/
14 14 b
15 15 |
16 16 a
17 17
18 18 4 changesets and 4 local tags will be created.
19 19 `hg log -G -T "{rev} {desc} (tag: {tags})"` will output::
20 20
21 21 o 3 d (tag: d tip)
22 22 |
23 23 | o 2 c (tag: c)
24 24 |/
25 25 o 1 b (tag: b)
26 26 |
27 27 o 0 a (tag: a)
28 28
29 29 For root nodes (nodes without parents) in the graph, they can be revsets
30 30 pointing to existing nodes. The ASCII graph could also have disconnected
31 31 components with same names referring to the same changeset.
32 32
33 33 Therefore, given the repo having the 4 changesets (and tags) above, with the
34 34 following ASCII graph as input::
35 35
36 36 foo bar bar foo
37 37 | / | |
38 38 ancestor(c,d) a baz
39 39
40 40 The result (`hg log -G -T "{desc}"`) will look like::
41 41
42 42 o foo
43 43 |\
44 44 +---o bar
45 45 | | |
46 46 | o | baz
47 47 | /
48 48 +---o d
49 49 | |
50 50 +---o c
51 51 | |
52 52 o | b
53 53 |/
54 54 o a
55 55
56 56 Note that if you take the above `hg log` output directly as input. It will work
57 57 as expected - the result would be an isomorphic graph::
58 58
59 59 o foo
60 60 |\
61 61 | | o d
62 62 | |/
63 63 | | o c
64 64 | |/
65 65 | | o bar
66 66 | |/|
67 67 | o | b
68 68 | |/
69 69 o / baz
70 70 /
71 71 o a
72 72
73 73 This is because 'o' is specially handled in the input: instead of using 'o' as
74 74 the node name, the word to the right will be used.
75 75
76 76 Some special comments could have side effects:
77 77
78 78 - Create obsmarkers
79 79 # replace: A -> B -> C -> D # chained 1 to 1 replacements
80 80 # split: A -> B, C # 1 to many
81 81 # prune: A, B, C # many to nothing
82 82 """
83 83 from __future__ import absolute_import, print_function
84 84
85 85 import collections
86 86 import itertools
87 87
88 88 from mercurial.i18n import _
89 89 from mercurial import (
90 90 context,
91 91 error,
92 92 node,
93 93 obsolete,
94 94 registrar,
95 95 scmutil,
96 96 tags as tagsmod,
97 97 )
98 98
99 99 cmdtable = {}
100 100 command = registrar.command(cmdtable)
101 101
102 102 _pipechars = '\\/+-|'
103 103 _nonpipechars = ''.join(chr(i) for i in xrange(33, 127)
104 104 if chr(i) not in _pipechars)
105 105
106 106 def _isname(ch):
107 107 """char -> bool. return True if ch looks like part of a name, False
108 108 otherwise"""
109 109 return ch in _nonpipechars
110 110
111 111 def _parseasciigraph(text):
112 112 """str -> {str : [str]}. convert the ASCII graph to edges"""
113 113 lines = text.splitlines()
114 114 edges = collections.defaultdict(list) # {node: []}
115 115
116 116 def get(y, x):
117 117 """(int, int) -> char. give a coordinate, return the char. return a
118 118 space for anything out of range"""
119 119 if x < 0 or y < 0:
120 120 return ' '
121 121 try:
122 122 return lines[y][x]
123 123 except IndexError:
124 124 return ' '
125 125
126 126 def getname(y, x):
127 127 """(int, int) -> str. like get(y, x) but concatenate left and right
128 128 parts. if name is an 'o', try to replace it to the right"""
129 129 result = ''
130 130 for i in itertools.count(0):
131 131 ch = get(y, x - i)
132 132 if not _isname(ch):
133 133 break
134 134 result = ch + result
135 135 for i in itertools.count(1):
136 136 ch = get(y, x + i)
137 137 if not _isname(ch):
138 138 break
139 139 result += ch
140 140 if result == 'o':
141 141 # special handling, find the name to the right
142 142 result = ''
143 143 for i in itertools.count(2):
144 144 ch = get(y, x + i)
145 145 if ch == ' ' or ch in _pipechars:
146 146 if result or x + i >= len(lines[y]):
147 147 break
148 148 else:
149 149 result += ch
150 150 return result or 'o'
151 151 return result
152 152
153 153 def parents(y, x):
154 154 """(int, int) -> [str]. follow the ASCII edges at given position,
155 155 return a list of parents"""
156 156 visited = {(y, x)}
157 157 visit = []
158 158 result = []
159 159
160 160 def follow(y, x, expected):
161 161 """conditionally append (y, x) to visit array, if it's a char
162 162 in excepted. 'o' in expected means an '_isname' test.
163 163 if '-' (or '+') is not in excepted, and get(y, x) is '-' (or '+'),
164 164 the next line (y + 1, x) will be checked instead."""
165 165 ch = get(y, x)
166 166 if any(ch == c and c not in expected for c in '-+'):
167 167 y += 1
168 168 return follow(y + 1, x, expected)
169 169 if ch in expected or ('o' in expected and _isname(ch)):
170 170 visit.append((y, x))
171 171
172 172 # -o- # starting point:
173 173 # /|\ # follow '-' (horizontally), and '/|\' (to the bottom)
174 174 follow(y + 1, x, '|')
175 175 follow(y + 1, x - 1, '/')
176 176 follow(y + 1, x + 1, '\\')
177 177 follow(y, x - 1, '-')
178 178 follow(y, x + 1, '-')
179 179
180 180 while visit:
181 181 y, x = visit.pop()
182 182 if (y, x) in visited:
183 183 continue
184 184 visited.add((y, x))
185 185 ch = get(y, x)
186 186 if _isname(ch):
187 187 result.append(getname(y, x))
188 188 continue
189 189 elif ch == '|':
190 190 follow(y + 1, x, '/|o')
191 191 follow(y + 1, x - 1, '/')
192 192 follow(y + 1, x + 1, '\\')
193 193 elif ch == '+':
194 194 follow(y, x - 1, '-')
195 195 follow(y, x + 1, '-')
196 196 follow(y + 1, x - 1, '/')
197 197 follow(y + 1, x + 1, '\\')
198 198 follow(y + 1, x, '|')
199 199 elif ch == '\\':
200 200 follow(y + 1, x + 1, '\\|o')
201 201 elif ch == '/':
202 202 follow(y + 1, x - 1, '/|o')
203 203 elif ch == '-':
204 204 follow(y, x - 1, '-+o')
205 205 follow(y, x + 1, '-+o')
206 206 return result
207 207
208 208 for y, line in enumerate(lines):
209 209 for x, ch in enumerate(line):
210 210 if ch == '#': # comment
211 211 break
212 212 if _isname(ch):
213 213 edges[getname(y, x)] += parents(y, x)
214 214
215 215 return dict(edges)
216 216
217 217 class simplefilectx(object):
218 218 def __init__(self, path, data):
219 219 self._data = data
220 220 self._path = path
221 221
222 222 def data(self):
223 223 return self._data
224 224
225 225 def filenode(self):
226 226 return None
227 227
228 228 def path(self):
229 229 return self._path
230 230
231 231 def renamed(self):
232 232 return None
233 233
234 234 def flags(self):
235 235 return ''
236 236
237 237 class simplecommitctx(context.committablectx):
238 def __init__(self, repo, name, parentctxs, added=None):
238 def __init__(self, repo, name, parentctxs, added):
239 239 opts = {
240 'changes': scmutil.status([], added or [], [], [], [], [], []),
240 'changes': scmutil.status([], list(added), [], [], [], [], []),
241 241 'date': '0 0',
242 242 'extra': {'branch': 'default'},
243 243 }
244 244 super(simplecommitctx, self).__init__(self, name, **opts)
245 245 self._repo = repo
246 self._name = name
246 self._added = added
247 247 self._parents = parentctxs
248 self._parents.sort(key=lambda c: c.node())
249 248 while len(self._parents) < 2:
250 249 self._parents.append(repo[node.nullid])
251 250
252 251 def filectx(self, key):
253 return simplefilectx(key, self._name)
252 return simplefilectx(key, self._added[key])
254 253
255 254 def commit(self):
256 255 return self._repo.commitctx(self)
257 256
258 257 def _walkgraph(edges):
259 258 """yield node, parents in topologically order"""
260 259 visible = set(edges.keys())
261 260 remaining = {} # {str: [str]}
262 261 for k, vs in edges.iteritems():
263 262 for v in vs:
264 263 if v not in remaining:
265 264 remaining[v] = []
266 265 remaining[k] = vs[:]
267 266 while remaining:
268 267 leafs = [k for k, v in remaining.items() if not v]
269 268 if not leafs:
270 269 raise error.Abort(_('the graph has cycles'))
271 270 for leaf in sorted(leafs):
272 271 if leaf in visible:
273 272 yield leaf, edges[leaf]
274 273 del remaining[leaf]
275 274 for k, v in remaining.iteritems():
276 275 if leaf in v:
277 276 v.remove(leaf)
278 277
279 278 @command('debugdrawdag', [])
280 279 def debugdrawdag(ui, repo, **opts):
281 280 """read an ASCII graph from stdin and create changesets
282 281
283 282 The ASCII graph is like what :hg:`log -G` outputs, with each `o` replaced
284 283 to the name of the node. The command will create dummy changesets and local
285 284 tags with those names to make the dummy changesets easier to be referred
286 285 to.
287 286
288 287 If the name of a node is a single character 'o', It will be replaced by the
289 288 word to the right. This makes it easier to reuse
290 289 :hg:`log -G -T '{desc}'` outputs.
291 290
292 291 For root (no parents) nodes, revset can be used to query existing repo.
293 292 Note that the revset cannot have confusing characters which can be seen as
294 293 the part of the graph edges, like `|/+-\`.
295 294 """
296 295 text = ui.fin.read()
297 296
298 297 # parse the graph and make sure len(parents) <= 2 for each node
299 298 edges = _parseasciigraph(text)
300 299 for k, v in edges.iteritems():
301 300 if len(v) > 2:
302 301 raise error.Abort(_('%s: too many parents: %s')
303 302 % (k, ' '.join(v)))
304 303
305 304 committed = {None: node.nullid} # {name: node}
306 305
307 306 # for leaf nodes, try to find existing nodes in repo
308 307 for name, parents in edges.iteritems():
309 308 if len(parents) == 0:
310 309 try:
311 310 committed[name] = scmutil.revsingle(repo, name)
312 311 except error.RepoLookupError:
313 312 pass
314 313
315 314 # commit in topological order
316 315 for name, parents in _walkgraph(edges):
317 316 if name in committed:
318 317 continue
319 318 pctxs = [repo[committed[n]] for n in parents]
320 ctx = simplecommitctx(repo, name, pctxs, [name])
319 pctxs.sort(key=lambda c: c.node())
320 added = {}
321 if len(parents) > 1:
322 # If it's a merge, take the files and contents from the parents
323 for f in pctxs[1].manifest():
324 if f not in pctxs[0].manifest():
325 added[f] = pctxs[1][f].data()
326 else:
327 # If it's not a merge, add a single file
328 added[name] = name
329 ctx = simplecommitctx(repo, name, pctxs, added)
321 330 n = ctx.commit()
322 331 committed[name] = n
323 332 tagsmod.tag(repo, name, n, message=None, user=None, date=None,
324 333 local=True)
325 334
326 335 # handle special comments
327 336 with repo.wlock(), repo.lock(), repo.transaction('drawdag'):
328 337 getctx = lambda x: repo.unfiltered()[committed[x.strip()]]
329 338 for line in text.splitlines():
330 339 if ' # ' not in line:
331 340 continue
332 341
333 342 rels = [] # obsolete relationships
334 343 comment = line.split(' # ', 1)[1].split(' # ')[0].strip()
335 344 args = comment.split(':', 1)
336 345 if len(args) <= 1:
337 346 continue
338 347
339 348 cmd = args[0].strip()
340 349 arg = args[1].strip()
341 350
342 351 if cmd in ('replace', 'rebase', 'amend'):
343 352 nodes = [getctx(m) for m in arg.split('->')]
344 353 for i in range(len(nodes) - 1):
345 354 rels.append((nodes[i], (nodes[i + 1],)))
346 355 elif cmd in ('split',):
347 356 pre, succs = arg.split('->')
348 357 succs = succs.split(',')
349 358 rels.append((getctx(pre), (getctx(s) for s in succs)))
350 359 elif cmd in ('prune',):
351 360 for n in arg.split(','):
352 361 rels.append((getctx(n), ()))
353 362 if rels:
354 363 obsolete.createmarkers(repo, rels, date=(0, 0), operation=cmd)
@@ -1,285 +1,285 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [experimental]
3 3 > bundle-phases=yes
4 4 > [extensions]
5 5 > strip=
6 6 > drawdag=$TESTDIR/drawdag.py
7 7 > EOF
8 8
9 9 Set up repo with linear history
10 10 $ hg init linear
11 11 $ cd linear
12 12 $ hg debugdrawdag <<'EOF'
13 13 > E
14 14 > |
15 15 > D
16 16 > |
17 17 > C
18 18 > |
19 19 > B
20 20 > |
21 21 > A
22 22 > EOF
23 23 $ hg phase --public A
24 24 $ hg phase --force --secret D
25 25 $ hg log -G -T '{desc} {phase}\n'
26 26 o E secret
27 27 |
28 28 o D secret
29 29 |
30 30 o C draft
31 31 |
32 32 o B draft
33 33 |
34 34 o A public
35 35
36 36 Phases are restored when unbundling
37 37 $ hg bundle --base B -r E bundle
38 38 3 changesets found
39 39 $ hg debugbundle bundle
40 40 Stream params: sortdict([('Compression', 'BZ')])
41 41 changegroup -- "sortdict([('version', '02'), ('nbchanges', '3'), ('targetphase', '2')])"
42 42 26805aba1e600a82e93661149f2313866a221a7b
43 43 f585351a92f85104bff7c284233c338b10eb1df7
44 44 9bc730a19041f9ec7cb33c626e811aa233efb18c
45 45 phase-heads -- 'sortdict()'
46 46 26805aba1e600a82e93661149f2313866a221a7b draft
47 47 $ hg strip --no-backup C
48 48 $ hg unbundle -q bundle
49 49 $ rm bundle
50 50 $ hg log -G -T '{desc} {phase}\n'
51 51 o E secret
52 52 |
53 53 o D secret
54 54 |
55 55 o C draft
56 56 |
57 57 o B draft
58 58 |
59 59 o A public
60 60
61 61 Root revision's phase is preserved
62 62 $ hg bundle -a bundle
63 63 5 changesets found
64 64 $ hg strip --no-backup A
65 65 $ hg unbundle -q bundle
66 66 $ rm bundle
67 67 $ hg log -G -T '{desc} {phase}\n'
68 68 o E secret
69 69 |
70 70 o D secret
71 71 |
72 72 o C draft
73 73 |
74 74 o B draft
75 75 |
76 76 o A public
77 77
78 78 Completely public history can be restored
79 79 $ hg phase --public E
80 80 $ hg bundle -a bundle
81 81 5 changesets found
82 82 $ hg strip --no-backup A
83 83 $ hg unbundle -q bundle
84 84 $ rm bundle
85 85 $ hg log -G -T '{desc} {phase}\n'
86 86 o E public
87 87 |
88 88 o D public
89 89 |
90 90 o C public
91 91 |
92 92 o B public
93 93 |
94 94 o A public
95 95
96 96 Direct transition from public to secret can be restored
97 97 $ hg phase --secret --force D
98 98 $ hg bundle -a bundle
99 99 5 changesets found
100 100 $ hg strip --no-backup A
101 101 $ hg unbundle -q bundle
102 102 $ rm bundle
103 103 $ hg log -G -T '{desc} {phase}\n'
104 104 o E secret
105 105 |
106 106 o D secret
107 107 |
108 108 o C public
109 109 |
110 110 o B public
111 111 |
112 112 o A public
113 113
114 114 Revisions within bundle preserve their phase even if parent changes its phase
115 115 $ hg phase --draft --force B
116 116 $ hg bundle --base B -r E bundle
117 117 3 changesets found
118 118 $ hg strip --no-backup C
119 119 $ hg phase --public B
120 120 $ hg unbundle -q bundle
121 121 $ rm bundle
122 122 $ hg log -G -T '{desc} {phase}\n'
123 123 o E secret
124 124 |
125 125 o D secret
126 126 |
127 127 o C draft
128 128 |
129 129 o B public
130 130 |
131 131 o A public
132 132
133 133 Phase of ancestors of stripped node get advanced to accommodate child
134 134 $ hg bundle --base B -r E bundle
135 135 3 changesets found
136 136 $ hg strip --no-backup C
137 137 $ hg phase --force --secret B
138 138 $ hg unbundle -q bundle
139 139 $ rm bundle
140 140 $ hg log -G -T '{desc} {phase}\n'
141 141 o E secret
142 142 |
143 143 o D secret
144 144 |
145 145 o C draft
146 146 |
147 147 o B draft
148 148 |
149 149 o A public
150 150
151 151 Unbundling advances phases of changesets even if they were already in the repo.
152 152 To test that, create a bundle of everything in draft phase and then unbundle
153 153 to see that secret becomes draft, but public remains public.
154 154 $ hg phase --draft --force A
155 155 $ hg phase --draft E
156 156 $ hg bundle -a bundle
157 157 5 changesets found
158 158 $ hg phase --public A
159 159 $ hg phase --secret --force E
160 160 $ hg unbundle -q bundle
161 161 $ rm bundle
162 162 $ hg log -G -T '{desc} {phase}\n'
163 163 o E draft
164 164 |
165 165 o D draft
166 166 |
167 167 o C draft
168 168 |
169 169 o B draft
170 170 |
171 171 o A public
172 172
173 173 Unbundling change in the middle of a stack does not affect later changes
174 174 $ hg strip --no-backup E
175 175 $ hg phase --secret --force D
176 176 $ hg log -G -T '{desc} {phase}\n'
177 177 o D secret
178 178 |
179 179 o C draft
180 180 |
181 181 o B draft
182 182 |
183 183 o A public
184 184
185 185 $ hg bundle --base A -r B bundle
186 186 1 changesets found
187 187 $ hg unbundle -q bundle
188 188 $ rm bundle
189 189 $ hg log -G -T '{desc} {phase}\n'
190 190 o D secret
191 191 |
192 192 o C draft
193 193 |
194 194 o B draft
195 195 |
196 196 o A public
197 197
198 198
199 199 $ cd ..
200 200
201 201 Set up repo with non-linear history
202 202 $ hg init non-linear
203 203 $ cd non-linear
204 204 $ hg debugdrawdag <<'EOF'
205 205 > D E
206 206 > |\|
207 207 > B C
208 208 > |/
209 209 > A
210 210 > EOF
211 211 $ hg phase --public C
212 212 $ hg phase --force --secret B
213 213 $ hg log -G -T '{node|short} {desc} {phase}\n'
214 214 o 03ca77807e91 E draft
215 215 |
216 | o 215e7b0814e1 D secret
216 | o 4e4f9194f9f1 D secret
217 217 |/|
218 218 o | dc0947a82db8 C public
219 219 | |
220 220 | o 112478962961 B secret
221 221 |/
222 222 o 426bada5c675 A public
223 223
224 224
225 225 Restore bundle of entire repo
226 226 $ hg bundle -a bundle
227 227 5 changesets found
228 228 $ hg debugbundle bundle
229 229 Stream params: sortdict([('Compression', 'BZ')])
230 230 changegroup -- "sortdict([('version', '02'), ('nbchanges', '5'), ('targetphase', '2')])"
231 231 426bada5c67598ca65036d57d9e4b64b0c1ce7a0
232 232 112478962961147124edd43549aedd1a335e44bf
233 233 dc0947a82db884575bb76ea10ac97b08536bfa03
234 215e7b0814e1cac8e2614e7284f2a5dc266b4323
234 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
235 235 03ca77807e919db8807c3749086dc36fb478cac0
236 236 phase-heads -- 'sortdict()'
237 237 dc0947a82db884575bb76ea10ac97b08536bfa03 public
238 238 03ca77807e919db8807c3749086dc36fb478cac0 draft
239 239 $ hg strip --no-backup A
240 240 $ hg unbundle -q bundle
241 241 $ rm bundle
242 242 $ hg log -G -T '{node|short} {desc} {phase}\n'
243 243 o 03ca77807e91 E draft
244 244 |
245 | o 215e7b0814e1 D secret
245 | o 4e4f9194f9f1 D secret
246 246 |/|
247 247 o | dc0947a82db8 C public
248 248 | |
249 249 | o 112478962961 B secret
250 250 |/
251 251 o 426bada5c675 A public
252 252
253 253
254 254 $ hg bundle --base 'A + C' -r D bundle
255 255 2 changesets found
256 256 $ hg debugbundle bundle
257 257 Stream params: sortdict([('Compression', 'BZ')])
258 258 changegroup -- "sortdict([('version', '02'), ('nbchanges', '2'), ('targetphase', '2')])"
259 259 112478962961147124edd43549aedd1a335e44bf
260 215e7b0814e1cac8e2614e7284f2a5dc266b4323
260 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
261 261 phase-heads -- 'sortdict()'
262 262 $ rm bundle
263 263
264 264 $ hg bundle --base A -r D bundle
265 265 3 changesets found
266 266 $ hg debugbundle bundle
267 267 Stream params: sortdict([('Compression', 'BZ')])
268 268 changegroup -- "sortdict([('version', '02'), ('nbchanges', '3'), ('targetphase', '2')])"
269 269 112478962961147124edd43549aedd1a335e44bf
270 270 dc0947a82db884575bb76ea10ac97b08536bfa03
271 215e7b0814e1cac8e2614e7284f2a5dc266b4323
271 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
272 272 phase-heads -- 'sortdict()'
273 273 dc0947a82db884575bb76ea10ac97b08536bfa03 public
274 274 $ rm bundle
275 275
276 276 $ hg bundle --base 'B + C' -r 'D + E' bundle
277 277 2 changesets found
278 278 $ hg debugbundle bundle
279 279 Stream params: sortdict([('Compression', 'BZ')])
280 280 changegroup -- "sortdict([('version', '02'), ('nbchanges', '2'), ('targetphase', '2')])"
281 215e7b0814e1cac8e2614e7284f2a5dc266b4323
281 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
282 282 03ca77807e919db8807c3749086dc36fb478cac0
283 283 phase-heads -- 'sortdict()'
284 284 03ca77807e919db8807c3749086dc36fb478cac0 draft
285 285 $ rm bundle
@@ -1,222 +1,234 b''
1 1 $ cat >> $HGRCPATH<<EOF
2 2 > [extensions]
3 3 > drawdag=$TESTDIR/drawdag.py
4 4 > [experimental]
5 5 > evolution=all
6 6 > EOF
7 7
8 8 $ reinit () {
9 9 > rm -rf .hg && hg init
10 10 > }
11 11
12 12 $ hg init
13 13
14 14 Test what said in drawdag.py docstring
15 15
16 16 $ hg debugdrawdag <<'EOS'
17 17 > c d
18 18 > |/
19 19 > b
20 20 > |
21 21 > a
22 22 > EOS
23 23
24 24 $ hg log -G -T '{rev} {desc} ({tags})'
25 25 o 3 d (d tip)
26 26 |
27 27 | o 2 c (c)
28 28 |/
29 29 o 1 b (b)
30 30 |
31 31 o 0 a (a)
32 32
33 33 $ hg debugdrawdag <<'EOS'
34 34 > foo bar bar foo
35 35 > | / | |
36 36 > ancestor(c,d) a baz
37 37 > EOS
38 38
39 39 $ hg log -G -T '{desc}'
40 40 o foo
41 41 |\
42 42 +---o bar
43 43 | | |
44 44 | o | baz
45 45 | /
46 46 +---o d
47 47 | |
48 48 +---o c
49 49 | |
50 50 o | b
51 51 |/
52 52 o a
53 53
54 54 $ reinit
55 55
56 56 $ hg debugdrawdag <<'EOS'
57 57 > o foo
58 58 > |\
59 59 > +---o bar
60 60 > | | |
61 61 > | o | baz
62 62 > | /
63 63 > +---o d
64 64 > | |
65 65 > +---o c
66 66 > | |
67 67 > o | b
68 68 > |/
69 69 > o a
70 70 > EOS
71 71
72 72 $ hg log -G -T '{desc}'
73 73 o foo
74 74 |\
75 75 | | o d
76 76 | |/
77 77 | | o c
78 78 | |/
79 79 | | o bar
80 80 | |/|
81 81 | o | b
82 82 | |/
83 83 o / baz
84 84 /
85 85 o a
86 86
87 87 $ reinit
88 88
89 89 $ hg debugdrawdag <<'EOS'
90 90 > o foo
91 91 > |\
92 92 > | | o d
93 93 > | |/
94 94 > | | o c
95 95 > | |/
96 96 > | | o bar
97 97 > | |/|
98 98 > | o | b
99 99 > | |/
100 100 > o / baz
101 101 > /
102 102 > o a
103 103 > EOS
104 104
105 105 $ hg log -G -T '{desc}'
106 106 o foo
107 107 |\
108 108 | | o d
109 109 | |/
110 110 | | o c
111 111 | |/
112 112 | | o bar
113 113 | |/|
114 114 | o | b
115 115 | |/
116 116 o / baz
117 117 /
118 118 o a
119 119
120 $ hg manifest -r a
121 a
122 $ hg manifest -r b
123 a
124 b
125 $ hg manifest -r bar
126 a
127 b
128 $ hg manifest -r foo
129 a
130 b
131 baz
120 132
121 133 Edges existed in repo are no-ops
122 134
123 135 $ reinit
124 136 $ hg debugdrawdag <<'EOS'
125 137 > B C C
126 138 > | | |
127 139 > A A B
128 140 > EOS
129 141
130 142 $ hg log -G -T '{desc}'
131 143 o C
132 144 |\
133 145 | o B
134 146 |/
135 147 o A
136 148
137 149
138 150 $ hg debugdrawdag <<'EOS'
139 151 > C D C
140 152 > | | |
141 153 > B B A
142 154 > EOS
143 155
144 156 $ hg log -G -T '{desc}'
145 157 o D
146 158 |
147 159 | o C
148 160 |/|
149 161 o | B
150 162 |/
151 163 o A
152 164
153 165
154 166 Node with more than 2 parents are disallowed
155 167
156 168 $ hg debugdrawdag <<'EOS'
157 169 > A
158 170 > /|\
159 171 > D B C
160 172 > EOS
161 173 abort: A: too many parents: C D B
162 174 [255]
163 175
164 176 Cycles are disallowed
165 177
166 178 $ hg debugdrawdag <<'EOS'
167 179 > A
168 180 > |
169 181 > A
170 182 > EOS
171 183 abort: the graph has cycles
172 184 [255]
173 185
174 186 $ hg debugdrawdag <<'EOS'
175 187 > A
176 188 > |
177 189 > B
178 190 > |
179 191 > A
180 192 > EOS
181 193 abort: the graph has cycles
182 194 [255]
183 195
184 196 Create obsmarkers via comments
185 197
186 198 $ reinit
187 199
188 200 $ hg debugdrawdag <<'EOS'
189 201 > G
190 202 > |
191 203 > I D C F # split: B -> E, F, G
192 204 > \ \| | # replace: C -> D -> H
193 205 > H B E # prune: F, I
194 206 > \|/
195 207 > A
196 208 > EOS
197 209
198 210 $ hg log -r 'sort(all(), topo)' -G --hidden -T '{desc} {node}'
199 211 o G 711f53bbef0bebd12eb6f0511d5e2e998b984846
200 212 |
201 213 x F 64a8289d249234b9886244d379f15e6b650b28e3
202 214 |
203 215 o E 7fb047a69f220c21711122dfd94305a9efb60cba
204 216 |
205 217 | x D be0ef73c17ade3fc89dc41701eb9fc3a91b58282
206 218 | |
207 219 | | x C 26805aba1e600a82e93661149f2313866a221a7b
208 220 | |/
209 221 | x B 112478962961147124edd43549aedd1a335e44bf
210 222 |/
211 223 | x I 58e6b987bf7045fcd9c54f496396ca1d1fc81047
212 224 | |
213 225 | o H 575c4b5ec114d64b681d33f8792853568bfb2b2c
214 226 |/
215 227 o A 426bada5c67598ca65036d57d9e4b64b0c1ce7a0
216 228
217 229 $ hg debugobsolete
218 230 112478962961147124edd43549aedd1a335e44bf 7fb047a69f220c21711122dfd94305a9efb60cba 64a8289d249234b9886244d379f15e6b650b28e3 711f53bbef0bebd12eb6f0511d5e2e998b984846 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
219 231 26805aba1e600a82e93661149f2313866a221a7b be0ef73c17ade3fc89dc41701eb9fc3a91b58282 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
220 232 be0ef73c17ade3fc89dc41701eb9fc3a91b58282 575c4b5ec114d64b681d33f8792853568bfb2b2c 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
221 233 64a8289d249234b9886244d379f15e6b650b28e3 0 {7fb047a69f220c21711122dfd94305a9efb60cba} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
222 234 58e6b987bf7045fcd9c54f496396ca1d1fc81047 0 {575c4b5ec114d64b681d33f8792853568bfb2b2c} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -1,381 +1,381 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}: {desc}"
11 11 > EOF
12 12
13 13 $ rebasewithdag() {
14 14 > N=`$PYTHON -c "print($N+1)"`
15 15 > hg init repo$N && cd repo$N
16 16 > hg debugdrawdag
17 17 > hg rebase "$@" > _rebasetmp
18 18 > r=$?
19 19 > grep -v 'saved backup bundle' _rebasetmp
20 20 > [ $r -eq 0 ] && hg tglog
21 21 > cd ..
22 22 > return $r
23 23 > }
24 24
25 25 Single branching point, without merge:
26 26
27 27 $ rebasewithdag -b D -d Z <<'EOS'
28 28 > D E
29 29 > |/
30 30 > Z B C # C: branching point, E should be picked
31 31 > \|/ # B should not be picked
32 32 > A
33 33 > |
34 34 > R
35 35 > EOS
36 36 rebasing 3:d6003a550c2c "C" (C)
37 37 rebasing 5:4526cf523425 "D" (D)
38 38 rebasing 6:b296604d9846 "E" (E tip)
39 39 o 6: E
40 40 |
41 41 | o 5: D
42 42 |/
43 43 o 4: C
44 44 |
45 45 o 3: Z
46 46 |
47 47 | o 2: B
48 48 |/
49 49 o 1: A
50 50 |
51 51 o 0: R
52 52
53 53 Multiple branching points caused by selecting a single merge changeset:
54 54
55 55 $ rebasewithdag -b E -d Z <<'EOS'
56 56 > E
57 57 > /|
58 58 > B C D # B, C: multiple branching points
59 59 > | |/ # D should not be picked
60 60 > Z | /
61 61 > \|/
62 62 > A
63 63 > |
64 64 > R
65 65 > EOS
66 66 rebasing 2:c1e6b162678d "B" (B)
67 67 rebasing 3:d6003a550c2c "C" (C)
68 rebasing 6:5251e0cb7302 "E" (E tip)
68 rebasing 6:54c8f00cb91c "E" (E tip)
69 69 o 6: E
70 70 |\
71 71 | o 5: C
72 72 | |
73 73 o | 4: B
74 74 |/
75 75 o 3: Z
76 76 |
77 77 | o 2: D
78 78 |/
79 79 o 1: A
80 80 |
81 81 o 0: R
82 82
83 83 Rebase should not extend the "--base" revset using "descendants":
84 84
85 85 $ rebasewithdag -b B -d Z <<'EOS'
86 86 > E
87 87 > /|
88 88 > Z B C # descendants(B) = B+E. With E, C will be included incorrectly
89 89 > \|/
90 90 > A
91 91 > |
92 92 > R
93 93 > EOS
94 94 rebasing 2:c1e6b162678d "B" (B)
95 rebasing 5:5251e0cb7302 "E" (E tip)
95 rebasing 5:54c8f00cb91c "E" (E tip)
96 96 o 5: E
97 97 |\
98 98 | o 4: B
99 99 | |
100 100 | o 3: Z
101 101 | |
102 102 o | 2: C
103 103 |/
104 104 o 1: A
105 105 |
106 106 o 0: R
107 107
108 108 Rebase should not simplify the "--base" revset using "roots":
109 109
110 110 $ rebasewithdag -b B+E -d Z <<'EOS'
111 111 > E
112 112 > /|
113 113 > Z B C # roots(B+E) = B. Without E, C will be missed incorrectly
114 114 > \|/
115 115 > A
116 116 > |
117 117 > R
118 118 > EOS
119 119 rebasing 2:c1e6b162678d "B" (B)
120 120 rebasing 3:d6003a550c2c "C" (C)
121 rebasing 5:5251e0cb7302 "E" (E tip)
121 rebasing 5:54c8f00cb91c "E" (E tip)
122 122 o 5: E
123 123 |\
124 124 | o 4: C
125 125 | |
126 126 o | 3: B
127 127 |/
128 128 o 2: Z
129 129 |
130 130 o 1: A
131 131 |
132 132 o 0: R
133 133
134 134 The destination is one of the two branching points of a merge:
135 135
136 136 $ rebasewithdag -b F -d Z <<'EOS'
137 137 > F
138 138 > / \
139 139 > E D
140 140 > / /
141 141 > Z C
142 142 > \ /
143 143 > B
144 144 > |
145 145 > A
146 146 > EOS
147 147 nothing to rebase
148 148 [1]
149 149
150 150 Multiple branching points caused by multiple bases (issue5420):
151 151
152 152 $ rebasewithdag -b E1+E2+C2+B1 -d Z <<'EOS'
153 153 > Z E2
154 154 > | /
155 155 > F E1 C2
156 156 > |/ /
157 157 > E C1 B2
158 158 > |/ /
159 159 > C B1
160 160 > |/
161 161 > B
162 162 > |
163 163 > A
164 164 > |
165 165 > R
166 166 > EOS
167 167 rebasing 3:a113dbaa660a "B1" (B1)
168 168 rebasing 5:06ce7b1cc8c2 "B2" (B2)
169 169 rebasing 6:0ac98cce32d3 "C1" (C1)
170 170 rebasing 8:781512f5e33d "C2" (C2)
171 171 rebasing 9:428d8c18f641 "E1" (E1)
172 172 rebasing 11:e1bf82f6b6df "E2" (E2)
173 173 o 12: E2
174 174 |
175 175 o 11: E1
176 176 |
177 177 | o 10: C2
178 178 | |
179 179 | o 9: C1
180 180 |/
181 181 | o 8: B2
182 182 | |
183 183 | o 7: B1
184 184 |/
185 185 o 6: Z
186 186 |
187 187 o 5: F
188 188 |
189 189 o 4: E
190 190 |
191 191 o 3: C
192 192 |
193 193 o 2: B
194 194 |
195 195 o 1: A
196 196 |
197 197 o 0: R
198 198
199 199 Multiple branching points with multiple merges:
200 200
201 201 $ rebasewithdag -b G+P -d Z <<'EOS'
202 202 > G H P
203 203 > |\ /| |\
204 204 > F E D M N
205 205 > \|/| /| |\
206 206 > Z C B I J K L
207 207 > \|/ |/ |/
208 208 > A A A
209 209 > EOS
210 210 rebasing 2:dc0947a82db8 "C" (C)
211 rebasing 8:215e7b0814e1 "D" (D)
211 rebasing 8:4e4f9194f9f1 "D" (D)
212 212 rebasing 9:03ca77807e91 "E" (E)
213 213 rebasing 10:afc707c82df0 "F" (F)
214 rebasing 13:018caa673317 "G" (G)
215 rebasing 14:4f710fbd68cb "H" (H)
214 rebasing 13:690dfff91e9e "G" (G)
215 rebasing 14:2893b886bb10 "H" (H)
216 216 rebasing 3:08ebfeb61bac "I" (I)
217 217 rebasing 4:a0a5005cec67 "J" (J)
218 218 rebasing 5:83780307a7e8 "K" (K)
219 219 rebasing 6:e131637a1cb6 "L" (L)
220 rebasing 11:d6fe3d11d95d "M" (M)
221 rebasing 12:fa1e02269063 "N" (N)
222 rebasing 15:448b1a498430 "P" (P tip)
220 rebasing 11:d1f6d0c3c7e4 "M" (M)
221 rebasing 12:7aaec6f81888 "N" (N)
222 rebasing 15:325bc8f1760d "P" (P tip)
223 223 o 15: P
224 224 |\
225 225 | o 14: N
226 226 | |\
227 227 o \ \ 13: M
228 228 |\ \ \
229 229 | | | o 12: L
230 230 | | | |
231 231 | | o | 11: K
232 232 | | |/
233 233 | o / 10: J
234 234 | |/
235 235 o / 9: I
236 236 |/
237 237 | o 8: H
238 238 | |\
239 239 | | | o 7: G
240 240 | | |/|
241 241 | | | o 6: F
242 242 | | | |
243 243 | | o | 5: E
244 244 | | |/
245 245 | o | 4: D
246 246 | |\|
247 247 +---o 3: C
248 248 | |
249 249 o | 2: Z
250 250 | |
251 251 | o 1: B
252 252 |/
253 253 o 0: A
254 254
255 255 Slightly more complex merge case (mentioned in https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-November/091074.html):
256 256
257 257 $ rebasewithdag -b A3+B3 -d Z <<'EOF'
258 258 > Z C1 A3 B3
259 259 > | / / \ / \
260 260 > M3 C0 A1 A2 B1 B2
261 261 > | / | | | |
262 262 > M2 M1 C1 C1 M3
263 263 > |
264 264 > M1
265 265 > |
266 266 > M0
267 267 > EOF
268 268 rebasing 4:8817fae53c94 "C0" (C0)
269 269 rebasing 6:06ca5dfe3b5b "B2" (B2)
270 270 rebasing 7:73508237b032 "C1" (C1)
271 271 rebasing 9:fdb955e2faed "A2" (A2)
272 rebasing 11:1b2f368c3cb5 "A3" (A3)
272 rebasing 11:4e449bd1a643 "A3" (A3)
273 273 rebasing 10:0a33b0519128 "B1" (B1)
274 rebasing 12:bd6a37b5b67a "B3" (B3 tip)
274 rebasing 12:209327807c3a "B3" (B3 tip)
275 275 o 12: B3
276 276 |\
277 277 | o 11: B1
278 278 | |
279 279 | | o 10: A3
280 280 | | |\
281 281 | +---o 9: A2
282 282 | | |
283 283 | o | 8: C1
284 284 | | |
285 285 o | | 7: B2
286 286 | | |
287 287 | o | 6: C0
288 288 |/ /
289 289 o | 5: Z
290 290 | |
291 291 o | 4: M3
292 292 | |
293 293 o | 3: M2
294 294 | |
295 295 | o 2: A1
296 296 |/
297 297 o 1: M1
298 298 |
299 299 o 0: M0
300 300
301 301 Disconnected graph:
302 302
303 303 $ rebasewithdag -b B -d Z <<'EOS'
304 304 > B
305 305 > |
306 306 > Z A
307 307 > EOS
308 308 nothing to rebase from 112478962961 to 48b9aae0607f
309 309 [1]
310 310
311 311 Multiple roots. Roots are ancestors of dest:
312 312
313 313 $ rebasewithdag -b B+D -d Z <<'EOF'
314 314 > D Z B
315 315 > \|\|
316 316 > C A
317 317 > EOF
318 318 rebasing 2:112478962961 "B" (B)
319 319 rebasing 3:b70f76719894 "D" (D)
320 320 o 4: D
321 321 |
322 322 | o 3: B
323 323 |/
324 324 o 2: Z
325 325 |\
326 326 | o 1: C
327 327 |
328 328 o 0: A
329 329
330 330 Multiple roots. One root is not an ancestor of dest:
331 331
332 332 $ rebasewithdag -b B+D -d Z <<'EOF'
333 333 > Z B D
334 334 > \|\|
335 335 > A C
336 336 > EOF
337 nothing to rebase from 86d01f49c0d9+b70f76719894 to 262e37e34f63
337 nothing to rebase from f675d5a1c6a4+b70f76719894 to 262e37e34f63
338 338 [1]
339 339
340 340 Multiple roots. One root is not an ancestor of dest. Select using a merge:
341 341
342 342 $ rebasewithdag -b E -d Z <<'EOF'
343 343 > E
344 344 > |\
345 345 > Z B D
346 346 > \|\|
347 347 > A C
348 348 > EOF
349 rebasing 2:86d01f49c0d9 "B" (B)
350 rebasing 5:539a0ff83ea9 "E" (E tip)
349 rebasing 2:f675d5a1c6a4 "B" (B)
350 rebasing 5:f68696fe6af8 "E" (E tip)
351 351 o 5: E
352 352 |\
353 353 | o 4: B
354 354 | |\
355 355 | | o 3: Z
356 356 | | |
357 357 o | | 2: D
358 358 |/ /
359 359 o / 1: C
360 360 /
361 361 o 0: A
362 362
363 363 Multiple roots. Two children share two parents while dest has only one parent:
364 364
365 365 $ rebasewithdag -b B+D -d Z <<'EOF'
366 366 > Z B D
367 367 > \|\|\
368 368 > A C A
369 369 > EOF
370 rebasing 2:86d01f49c0d9 "B" (B)
371 rebasing 3:b7df2ca01aa8 "D" (D)
370 rebasing 2:f675d5a1c6a4 "B" (B)
371 rebasing 3:c2a779e13b56 "D" (D)
372 372 o 4: D
373 373 |\
374 374 +---o 3: B
375 375 | |/
376 376 | o 2: Z
377 377 | |
378 378 o | 1: C
379 379 /
380 380 o 0: A
381 381
@@ -1,1099 +1,1099 b''
1 1 $ echo "[format]" >> $HGRCPATH
2 2 $ echo "usegeneraldelta=yes" >> $HGRCPATH
3 3 $ echo "[extensions]" >> $HGRCPATH
4 4 $ echo "strip=" >> $HGRCPATH
5 5 $ echo "drawdag=$TESTDIR/drawdag.py" >> $HGRCPATH
6 6
7 7 $ restore() {
8 8 > hg unbundle -q .hg/strip-backup/*
9 9 > rm .hg/strip-backup/*
10 10 > }
11 11 $ teststrip() {
12 12 > hg up -C $1
13 13 > echo % before update $1, strip $2
14 14 > hg parents
15 15 > hg --traceback strip $2
16 16 > echo % after update $1, strip $2
17 17 > hg parents
18 18 > restore
19 19 > }
20 20
21 21 $ hg init test
22 22 $ cd test
23 23
24 24 $ echo foo > bar
25 25 $ hg ci -Ama
26 26 adding bar
27 27
28 28 $ echo more >> bar
29 29 $ hg ci -Amb
30 30
31 31 $ echo blah >> bar
32 32 $ hg ci -Amc
33 33
34 34 $ hg up 1
35 35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 36 $ echo blah >> bar
37 37 $ hg ci -Amd
38 38 created new head
39 39
40 40 $ echo final >> bar
41 41 $ hg ci -Ame
42 42
43 43 $ hg log
44 44 changeset: 4:443431ffac4f
45 45 tag: tip
46 46 user: test
47 47 date: Thu Jan 01 00:00:00 1970 +0000
48 48 summary: e
49 49
50 50 changeset: 3:65bd5f99a4a3
51 51 parent: 1:ef3a871183d7
52 52 user: test
53 53 date: Thu Jan 01 00:00:00 1970 +0000
54 54 summary: d
55 55
56 56 changeset: 2:264128213d29
57 57 user: test
58 58 date: Thu Jan 01 00:00:00 1970 +0000
59 59 summary: c
60 60
61 61 changeset: 1:ef3a871183d7
62 62 user: test
63 63 date: Thu Jan 01 00:00:00 1970 +0000
64 64 summary: b
65 65
66 66 changeset: 0:9ab35a2d17cb
67 67 user: test
68 68 date: Thu Jan 01 00:00:00 1970 +0000
69 69 summary: a
70 70
71 71
72 72 $ teststrip 4 4
73 73 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
74 74 % before update 4, strip 4
75 75 changeset: 4:443431ffac4f
76 76 tag: tip
77 77 user: test
78 78 date: Thu Jan 01 00:00:00 1970 +0000
79 79 summary: e
80 80
81 81 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 82 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
83 83 % after update 4, strip 4
84 84 changeset: 3:65bd5f99a4a3
85 85 tag: tip
86 86 parent: 1:ef3a871183d7
87 87 user: test
88 88 date: Thu Jan 01 00:00:00 1970 +0000
89 89 summary: d
90 90
91 91 $ teststrip 4 3
92 92 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 93 % before update 4, strip 3
94 94 changeset: 4:443431ffac4f
95 95 tag: tip
96 96 user: test
97 97 date: Thu Jan 01 00:00:00 1970 +0000
98 98 summary: e
99 99
100 100 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
101 101 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
102 102 % after update 4, strip 3
103 103 changeset: 1:ef3a871183d7
104 104 user: test
105 105 date: Thu Jan 01 00:00:00 1970 +0000
106 106 summary: b
107 107
108 108 $ teststrip 1 4
109 109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 110 % before update 1, strip 4
111 111 changeset: 1:ef3a871183d7
112 112 user: test
113 113 date: Thu Jan 01 00:00:00 1970 +0000
114 114 summary: b
115 115
116 116 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
117 117 % after update 1, strip 4
118 118 changeset: 1:ef3a871183d7
119 119 user: test
120 120 date: Thu Jan 01 00:00:00 1970 +0000
121 121 summary: b
122 122
123 123 $ teststrip 4 2
124 124 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 125 % before update 4, strip 2
126 126 changeset: 4:443431ffac4f
127 127 tag: tip
128 128 user: test
129 129 date: Thu Jan 01 00:00:00 1970 +0000
130 130 summary: e
131 131
132 132 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
133 133 % after update 4, strip 2
134 134 changeset: 3:443431ffac4f
135 135 tag: tip
136 136 user: test
137 137 date: Thu Jan 01 00:00:00 1970 +0000
138 138 summary: e
139 139
140 140 $ teststrip 4 1
141 141 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 142 % before update 4, strip 1
143 143 changeset: 4:264128213d29
144 144 tag: tip
145 145 parent: 1:ef3a871183d7
146 146 user: test
147 147 date: Thu Jan 01 00:00:00 1970 +0000
148 148 summary: c
149 149
150 150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 151 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
152 152 % after update 4, strip 1
153 153 changeset: 0:9ab35a2d17cb
154 154 tag: tip
155 155 user: test
156 156 date: Thu Jan 01 00:00:00 1970 +0000
157 157 summary: a
158 158
159 159 $ teststrip null 4
160 160 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
161 161 % before update null, strip 4
162 162 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
163 163 % after update null, strip 4
164 164
165 165 $ hg log
166 166 changeset: 4:264128213d29
167 167 tag: tip
168 168 parent: 1:ef3a871183d7
169 169 user: test
170 170 date: Thu Jan 01 00:00:00 1970 +0000
171 171 summary: c
172 172
173 173 changeset: 3:443431ffac4f
174 174 user: test
175 175 date: Thu Jan 01 00:00:00 1970 +0000
176 176 summary: e
177 177
178 178 changeset: 2:65bd5f99a4a3
179 179 user: test
180 180 date: Thu Jan 01 00:00:00 1970 +0000
181 181 summary: d
182 182
183 183 changeset: 1:ef3a871183d7
184 184 user: test
185 185 date: Thu Jan 01 00:00:00 1970 +0000
186 186 summary: b
187 187
188 188 changeset: 0:9ab35a2d17cb
189 189 user: test
190 190 date: Thu Jan 01 00:00:00 1970 +0000
191 191 summary: a
192 192
193 193 $ hg up -C 4
194 194 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
195 195 $ hg parents
196 196 changeset: 4:264128213d29
197 197 tag: tip
198 198 parent: 1:ef3a871183d7
199 199 user: test
200 200 date: Thu Jan 01 00:00:00 1970 +0000
201 201 summary: c
202 202
203 203
204 204 $ hg --traceback strip 4
205 205 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 206 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg (glob)
207 207 $ hg parents
208 208 changeset: 1:ef3a871183d7
209 209 user: test
210 210 date: Thu Jan 01 00:00:00 1970 +0000
211 211 summary: b
212 212
213 213 $ hg debugbundle .hg/strip-backup/*
214 214 Stream params: sortdict([('Compression', 'BZ')])
215 215 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
216 216 264128213d290d868c54642d13aeaa3675551a78
217 217 phase-heads -- 'sortdict()'
218 218 264128213d290d868c54642d13aeaa3675551a78 draft
219 219 $ hg pull .hg/strip-backup/*
220 220 pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg
221 221 searching for changes
222 222 adding changesets
223 223 adding manifests
224 224 adding file changes
225 225 added 1 changesets with 0 changes to 0 files (+1 heads)
226 226 (run 'hg heads' to see heads, 'hg merge' to merge)
227 227 $ rm .hg/strip-backup/*
228 228 $ hg log --graph
229 229 o changeset: 4:264128213d29
230 230 | tag: tip
231 231 | parent: 1:ef3a871183d7
232 232 | user: test
233 233 | date: Thu Jan 01 00:00:00 1970 +0000
234 234 | summary: c
235 235 |
236 236 | o changeset: 3:443431ffac4f
237 237 | | user: test
238 238 | | date: Thu Jan 01 00:00:00 1970 +0000
239 239 | | summary: e
240 240 | |
241 241 | o changeset: 2:65bd5f99a4a3
242 242 |/ user: test
243 243 | date: Thu Jan 01 00:00:00 1970 +0000
244 244 | summary: d
245 245 |
246 246 @ changeset: 1:ef3a871183d7
247 247 | user: test
248 248 | date: Thu Jan 01 00:00:00 1970 +0000
249 249 | summary: b
250 250 |
251 251 o changeset: 0:9ab35a2d17cb
252 252 user: test
253 253 date: Thu Jan 01 00:00:00 1970 +0000
254 254 summary: a
255 255
256 256 $ hg up -C 2
257 257 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 258 $ hg merge 4
259 259 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
260 260 (branch merge, don't forget to commit)
261 261
262 262 before strip of merge parent
263 263
264 264 $ hg parents
265 265 changeset: 2:65bd5f99a4a3
266 266 user: test
267 267 date: Thu Jan 01 00:00:00 1970 +0000
268 268 summary: d
269 269
270 270 changeset: 4:264128213d29
271 271 tag: tip
272 272 parent: 1:ef3a871183d7
273 273 user: test
274 274 date: Thu Jan 01 00:00:00 1970 +0000
275 275 summary: c
276 276
277 277 $ hg strip 4
278 278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 279 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
280 280
281 281 after strip of merge parent
282 282
283 283 $ hg parents
284 284 changeset: 1:ef3a871183d7
285 285 user: test
286 286 date: Thu Jan 01 00:00:00 1970 +0000
287 287 summary: b
288 288
289 289 $ restore
290 290
291 291 $ hg up
292 292 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
293 293 updated to "264128213d29: c"
294 294 1 other heads for branch "default"
295 295 $ hg log -G
296 296 @ changeset: 4:264128213d29
297 297 | tag: tip
298 298 | parent: 1:ef3a871183d7
299 299 | user: test
300 300 | date: Thu Jan 01 00:00:00 1970 +0000
301 301 | summary: c
302 302 |
303 303 | o changeset: 3:443431ffac4f
304 304 | | user: test
305 305 | | date: Thu Jan 01 00:00:00 1970 +0000
306 306 | | summary: e
307 307 | |
308 308 | o changeset: 2:65bd5f99a4a3
309 309 |/ user: test
310 310 | date: Thu Jan 01 00:00:00 1970 +0000
311 311 | summary: d
312 312 |
313 313 o changeset: 1:ef3a871183d7
314 314 | user: test
315 315 | date: Thu Jan 01 00:00:00 1970 +0000
316 316 | summary: b
317 317 |
318 318 o changeset: 0:9ab35a2d17cb
319 319 user: test
320 320 date: Thu Jan 01 00:00:00 1970 +0000
321 321 summary: a
322 322
323 323
324 324 2 is parent of 3, only one strip should happen
325 325
326 326 $ hg strip "roots(2)" 3
327 327 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
328 328 $ hg log -G
329 329 @ changeset: 2:264128213d29
330 330 | tag: tip
331 331 | user: test
332 332 | date: Thu Jan 01 00:00:00 1970 +0000
333 333 | summary: c
334 334 |
335 335 o changeset: 1:ef3a871183d7
336 336 | user: test
337 337 | date: Thu Jan 01 00:00:00 1970 +0000
338 338 | summary: b
339 339 |
340 340 o changeset: 0:9ab35a2d17cb
341 341 user: test
342 342 date: Thu Jan 01 00:00:00 1970 +0000
343 343 summary: a
344 344
345 345 $ restore
346 346 $ hg log -G
347 347 o changeset: 4:443431ffac4f
348 348 | tag: tip
349 349 | user: test
350 350 | date: Thu Jan 01 00:00:00 1970 +0000
351 351 | summary: e
352 352 |
353 353 o changeset: 3:65bd5f99a4a3
354 354 | parent: 1:ef3a871183d7
355 355 | user: test
356 356 | date: Thu Jan 01 00:00:00 1970 +0000
357 357 | summary: d
358 358 |
359 359 | @ changeset: 2:264128213d29
360 360 |/ user: test
361 361 | date: Thu Jan 01 00:00:00 1970 +0000
362 362 | summary: c
363 363 |
364 364 o changeset: 1:ef3a871183d7
365 365 | user: test
366 366 | date: Thu Jan 01 00:00:00 1970 +0000
367 367 | summary: b
368 368 |
369 369 o changeset: 0:9ab35a2d17cb
370 370 user: test
371 371 date: Thu Jan 01 00:00:00 1970 +0000
372 372 summary: a
373 373
374 374 Failed hook while applying "saveheads" bundle.
375 375
376 376 $ hg strip 2 --config hooks.pretxnchangegroup.bad=false
377 377 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 378 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
379 379 transaction abort!
380 380 rollback completed
381 381 strip failed, backup bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
382 382 strip failed, unrecovered changes stored in '$TESTTMP/test/.hg/strip-backup/*-temp.hg' (glob)
383 383 (fix the problem, then recover the changesets with "hg unbundle '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)
384 384 abort: pretxnchangegroup.bad hook exited with status 1
385 385 [255]
386 386 $ restore
387 387 $ hg log -G
388 388 o changeset: 4:443431ffac4f
389 389 | tag: tip
390 390 | user: test
391 391 | date: Thu Jan 01 00:00:00 1970 +0000
392 392 | summary: e
393 393 |
394 394 o changeset: 3:65bd5f99a4a3
395 395 | parent: 1:ef3a871183d7
396 396 | user: test
397 397 | date: Thu Jan 01 00:00:00 1970 +0000
398 398 | summary: d
399 399 |
400 400 | o changeset: 2:264128213d29
401 401 |/ user: test
402 402 | date: Thu Jan 01 00:00:00 1970 +0000
403 403 | summary: c
404 404 |
405 405 @ changeset: 1:ef3a871183d7
406 406 | user: test
407 407 | date: Thu Jan 01 00:00:00 1970 +0000
408 408 | summary: b
409 409 |
410 410 o changeset: 0:9ab35a2d17cb
411 411 user: test
412 412 date: Thu Jan 01 00:00:00 1970 +0000
413 413 summary: a
414 414
415 415
416 416 2 different branches: 2 strips
417 417
418 418 $ hg strip 2 4
419 419 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
420 420 $ hg log -G
421 421 o changeset: 2:65bd5f99a4a3
422 422 | tag: tip
423 423 | user: test
424 424 | date: Thu Jan 01 00:00:00 1970 +0000
425 425 | summary: d
426 426 |
427 427 @ changeset: 1:ef3a871183d7
428 428 | user: test
429 429 | date: Thu Jan 01 00:00:00 1970 +0000
430 430 | summary: b
431 431 |
432 432 o changeset: 0:9ab35a2d17cb
433 433 user: test
434 434 date: Thu Jan 01 00:00:00 1970 +0000
435 435 summary: a
436 436
437 437 $ restore
438 438
439 439 2 different branches and a common ancestor: 1 strip
440 440
441 441 $ hg strip 1 "2|4"
442 442 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 443 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
444 444 $ restore
445 445
446 446 verify fncache is kept up-to-date
447 447
448 448 $ touch a
449 449 $ hg ci -qAm a
450 450 $ cat .hg/store/fncache | sort
451 451 data/a.i
452 452 data/bar.i
453 453 $ hg strip tip
454 454 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
455 455 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
456 456 $ cat .hg/store/fncache
457 457 data/bar.i
458 458
459 459 stripping an empty revset
460 460
461 461 $ hg strip "1 and not 1"
462 462 abort: empty revision set
463 463 [255]
464 464
465 465 remove branchy history for qimport tests
466 466
467 467 $ hg strip 3
468 468 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
469 469
470 470
471 471 strip of applied mq should cleanup status file
472 472
473 473 $ echo "mq=" >> $HGRCPATH
474 474 $ hg up -C 3
475 475 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
476 476 $ echo fooagain >> bar
477 477 $ hg ci -mf
478 478 $ hg qimport -r tip:2
479 479
480 480 applied patches before strip
481 481
482 482 $ hg qapplied
483 483 d
484 484 e
485 485 f
486 486
487 487 stripping revision in queue
488 488
489 489 $ hg strip 3
490 490 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
491 491 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
492 492
493 493 applied patches after stripping rev in queue
494 494
495 495 $ hg qapplied
496 496 d
497 497
498 498 stripping ancestor of queue
499 499
500 500 $ hg strip 1
501 501 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
502 502 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
503 503
504 504 applied patches after stripping ancestor of queue
505 505
506 506 $ hg qapplied
507 507
508 508 Verify strip protects against stripping wc parent when there are uncommitted mods
509 509
510 510 $ echo b > b
511 511 $ echo bb > bar
512 512 $ hg add b
513 513 $ hg ci -m 'b'
514 514 $ hg log --graph
515 515 @ changeset: 1:76dcf9fab855
516 516 | tag: tip
517 517 | user: test
518 518 | date: Thu Jan 01 00:00:00 1970 +0000
519 519 | summary: b
520 520 |
521 521 o changeset: 0:9ab35a2d17cb
522 522 user: test
523 523 date: Thu Jan 01 00:00:00 1970 +0000
524 524 summary: a
525 525
526 526 $ hg up 0
527 527 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
528 528 $ echo c > bar
529 529 $ hg up -t false
530 530 merging bar
531 531 merging bar failed!
532 532 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
533 533 use 'hg resolve' to retry unresolved file merges
534 534 [1]
535 535 $ hg sum
536 536 parent: 1:76dcf9fab855 tip
537 537 b
538 538 branch: default
539 539 commit: 1 modified, 1 unknown, 1 unresolved
540 540 update: (current)
541 541 phases: 2 draft
542 542 mq: 3 unapplied
543 543
544 544 $ echo c > b
545 545 $ hg strip tip
546 546 abort: local changes found
547 547 [255]
548 548 $ hg strip tip --keep
549 549 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
550 550 $ hg log --graph
551 551 @ changeset: 0:9ab35a2d17cb
552 552 tag: tip
553 553 user: test
554 554 date: Thu Jan 01 00:00:00 1970 +0000
555 555 summary: a
556 556
557 557 $ hg status
558 558 M bar
559 559 ? b
560 560 ? bar.orig
561 561
562 562 $ rm bar.orig
563 563 $ hg sum
564 564 parent: 0:9ab35a2d17cb tip
565 565 a
566 566 branch: default
567 567 commit: 1 modified, 1 unknown
568 568 update: (current)
569 569 phases: 1 draft
570 570 mq: 3 unapplied
571 571
572 572 Strip adds, removes, modifies with --keep
573 573
574 574 $ touch b
575 575 $ hg add b
576 576 $ hg commit -mb
577 577 $ touch c
578 578
579 579 ... with a clean working dir
580 580
581 581 $ hg add c
582 582 $ hg rm bar
583 583 $ hg commit -mc
584 584 $ hg status
585 585 $ hg strip --keep tip
586 586 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
587 587 $ hg status
588 588 ! bar
589 589 ? c
590 590
591 591 ... with a dirty working dir
592 592
593 593 $ hg add c
594 594 $ hg rm bar
595 595 $ hg commit -mc
596 596 $ hg status
597 597 $ echo b > b
598 598 $ echo d > d
599 599 $ hg strip --keep tip
600 600 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
601 601 $ hg status
602 602 M b
603 603 ! bar
604 604 ? c
605 605 ? d
606 606
607 607 ... after updating the dirstate
608 608 $ hg add c
609 609 $ hg commit -mc
610 610 $ hg rm c
611 611 $ hg commit -mc
612 612 $ hg strip --keep '.^' -q
613 613 $ cd ..
614 614
615 615 stripping many nodes on a complex graph (issue3299)
616 616
617 617 $ hg init issue3299
618 618 $ cd issue3299
619 619 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
620 620 $ hg strip 'not ancestors(x)'
621 621 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
622 622
623 623 test hg strip -B bookmark
624 624
625 625 $ cd ..
626 626 $ hg init bookmarks
627 627 $ cd bookmarks
628 628 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
629 629 $ hg bookmark -r 'a' 'todelete'
630 630 $ hg bookmark -r 'b' 'B'
631 631 $ hg bookmark -r 'b' 'nostrip'
632 632 $ hg bookmark -r 'c' 'delete'
633 633 $ hg bookmark -r 'd' 'multipledelete1'
634 634 $ hg bookmark -r 'e' 'multipledelete2'
635 635 $ hg bookmark -r 'f' 'singlenode1'
636 636 $ hg bookmark -r 'f' 'singlenode2'
637 637 $ hg up -C todelete
638 638 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
639 639 (activating bookmark todelete)
640 640 $ hg strip -B nostrip
641 641 bookmark 'nostrip' deleted
642 642 abort: empty revision set
643 643 [255]
644 644 $ hg strip -B todelete
645 645 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
646 646 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
647 647 bookmark 'todelete' deleted
648 648 $ hg id -ir dcbb326fdec2
649 649 abort: unknown revision 'dcbb326fdec2'!
650 650 [255]
651 651 $ hg id -ir d62d843c9a01
652 652 d62d843c9a01
653 653 $ hg bookmarks
654 654 B 9:ff43616e5d0f
655 655 delete 6:2702dd0c91e7
656 656 multipledelete1 11:e46a4836065c
657 657 multipledelete2 12:b4594d867745
658 658 singlenode1 13:43227190fef8
659 659 singlenode2 13:43227190fef8
660 660 $ hg strip -B multipledelete1 -B multipledelete2
661 661 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg (glob)
662 662 bookmark 'multipledelete1' deleted
663 663 bookmark 'multipledelete2' deleted
664 664 $ hg id -ir e46a4836065c
665 665 abort: unknown revision 'e46a4836065c'!
666 666 [255]
667 667 $ hg id -ir b4594d867745
668 668 abort: unknown revision 'b4594d867745'!
669 669 [255]
670 670 $ hg strip -B singlenode1 -B singlenode2
671 671 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg (glob)
672 672 bookmark 'singlenode1' deleted
673 673 bookmark 'singlenode2' deleted
674 674 $ hg id -ir 43227190fef8
675 675 abort: unknown revision '43227190fef8'!
676 676 [255]
677 677 $ hg strip -B unknownbookmark
678 678 abort: bookmark 'unknownbookmark' not found
679 679 [255]
680 680 $ hg strip -B unknownbookmark1 -B unknownbookmark2
681 681 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
682 682 [255]
683 683 $ hg strip -B delete -B unknownbookmark
684 684 abort: bookmark 'unknownbookmark' not found
685 685 [255]
686 686 $ hg strip -B delete
687 687 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
688 688 bookmark 'delete' deleted
689 689 $ hg id -ir 6:2702dd0c91e7
690 690 abort: unknown revision '2702dd0c91e7'!
691 691 [255]
692 692 $ hg update B
693 693 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
694 694 (activating bookmark B)
695 695 $ echo a > a
696 696 $ hg add a
697 697 $ hg strip -B B
698 698 abort: local changes found
699 699 [255]
700 700 $ hg bookmarks
701 701 * B 6:ff43616e5d0f
702 702
703 703 Make sure no one adds back a -b option:
704 704
705 705 $ hg strip -b tip
706 706 hg strip: option -b not recognized
707 707 hg strip [-k] [-f] [-B bookmark] [-r] REV...
708 708
709 709 strip changesets and all their descendants from the repository
710 710
711 711 (use 'hg help -e strip' to show help for the strip extension)
712 712
713 713 options ([+] can be repeated):
714 714
715 715 -r --rev REV [+] strip specified revision (optional, can specify
716 716 revisions without this option)
717 717 -f --force force removal of changesets, discard uncommitted
718 718 changes (no backup)
719 719 --no-backup no backups
720 720 -k --keep do not modify working directory during strip
721 721 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
722 722 --mq operate on patch repository
723 723
724 724 (use 'hg strip -h' to show more help)
725 725 [255]
726 726
727 727 $ cd ..
728 728
729 729 Verify bundles don't get overwritten:
730 730
731 731 $ hg init doublebundle
732 732 $ cd doublebundle
733 733 $ touch a
734 734 $ hg commit -Aqm a
735 735 $ touch b
736 736 $ hg commit -Aqm b
737 737 $ hg strip -r 0
738 738 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
739 739 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob)
740 740 $ ls .hg/strip-backup
741 741 3903775176ed-e68910bd-backup.hg
742 742 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
743 743 $ hg strip -r 0
744 744 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob)
745 745 $ ls .hg/strip-backup
746 746 3903775176ed-54390173-backup.hg
747 747 3903775176ed-e68910bd-backup.hg
748 748 $ cd ..
749 749
750 750 Test that we only bundle the stripped changesets (issue4736)
751 751 ------------------------------------------------------------
752 752
753 753 initialization (previous repo is empty anyway)
754 754
755 755 $ hg init issue4736
756 756 $ cd issue4736
757 757 $ echo a > a
758 758 $ hg add a
759 759 $ hg commit -m commitA
760 760 $ echo b > b
761 761 $ hg add b
762 762 $ hg commit -m commitB
763 763 $ echo c > c
764 764 $ hg add c
765 765 $ hg commit -m commitC
766 766 $ hg up 'desc(commitB)'
767 767 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
768 768 $ echo d > d
769 769 $ hg add d
770 770 $ hg commit -m commitD
771 771 created new head
772 772 $ hg up 'desc(commitC)'
773 773 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
774 774 $ hg merge 'desc(commitD)'
775 775 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
776 776 (branch merge, don't forget to commit)
777 777 $ hg ci -m 'mergeCD'
778 778 $ hg log -G
779 779 @ changeset: 4:d8db9d137221
780 780 |\ tag: tip
781 781 | | parent: 2:5c51d8d6557d
782 782 | | parent: 3:6625a5168474
783 783 | | user: test
784 784 | | date: Thu Jan 01 00:00:00 1970 +0000
785 785 | | summary: mergeCD
786 786 | |
787 787 | o changeset: 3:6625a5168474
788 788 | | parent: 1:eca11cf91c71
789 789 | | user: test
790 790 | | date: Thu Jan 01 00:00:00 1970 +0000
791 791 | | summary: commitD
792 792 | |
793 793 o | changeset: 2:5c51d8d6557d
794 794 |/ user: test
795 795 | date: Thu Jan 01 00:00:00 1970 +0000
796 796 | summary: commitC
797 797 |
798 798 o changeset: 1:eca11cf91c71
799 799 | user: test
800 800 | date: Thu Jan 01 00:00:00 1970 +0000
801 801 | summary: commitB
802 802 |
803 803 o changeset: 0:105141ef12d0
804 804 user: test
805 805 date: Thu Jan 01 00:00:00 1970 +0000
806 806 summary: commitA
807 807
808 808
809 809 Check bundle behavior:
810 810
811 811 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
812 812 2 changesets found
813 813 $ hg log -r 'bundle()' -R ../issue4736.hg
814 814 changeset: 3:6625a5168474
815 815 parent: 1:eca11cf91c71
816 816 user: test
817 817 date: Thu Jan 01 00:00:00 1970 +0000
818 818 summary: commitD
819 819
820 820 changeset: 4:d8db9d137221
821 821 tag: tip
822 822 parent: 2:5c51d8d6557d
823 823 parent: 3:6625a5168474
824 824 user: test
825 825 date: Thu Jan 01 00:00:00 1970 +0000
826 826 summary: mergeCD
827 827
828 828
829 829 check strip behavior
830 830
831 831 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
832 832 resolving manifests
833 833 branchmerge: False, force: True, partial: False
834 834 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
835 835 c: other deleted -> r
836 836 removing c
837 837 d: other deleted -> r
838 838 removing d
839 839 starting 4 threads for background file closing (?)
840 840 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
841 841 2 changesets found
842 842 list of changesets:
843 843 6625a516847449b6f0fa3737b9ba56e9f0f3032c
844 844 d8db9d1372214336d2b5570f20ee468d2c72fa8b
845 845 bundle2-output-bundle: "HG20", (1 params) 2 parts total
846 846 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
847 847 bundle2-output-part: "phase-heads" 24 bytes payload
848 848 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
849 849 updating the branch cache
850 850 invalid branchheads cache (served): tip differs
851 851 truncating cache/rbc-revs-v1 to 24
852 852 $ hg log -G
853 853 o changeset: 2:5c51d8d6557d
854 854 | tag: tip
855 855 | user: test
856 856 | date: Thu Jan 01 00:00:00 1970 +0000
857 857 | summary: commitC
858 858 |
859 859 @ changeset: 1:eca11cf91c71
860 860 | user: test
861 861 | date: Thu Jan 01 00:00:00 1970 +0000
862 862 | summary: commitB
863 863 |
864 864 o changeset: 0:105141ef12d0
865 865 user: test
866 866 date: Thu Jan 01 00:00:00 1970 +0000
867 867 summary: commitA
868 868
869 869
870 870 strip backup content
871 871
872 872 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
873 873 changeset: 3:6625a5168474
874 874 parent: 1:eca11cf91c71
875 875 user: test
876 876 date: Thu Jan 01 00:00:00 1970 +0000
877 877 summary: commitD
878 878
879 879 changeset: 4:d8db9d137221
880 880 tag: tip
881 881 parent: 2:5c51d8d6557d
882 882 parent: 3:6625a5168474
883 883 user: test
884 884 date: Thu Jan 01 00:00:00 1970 +0000
885 885 summary: mergeCD
886 886
887 887 Check that the phase cache is properly invalidated after a strip with bookmark.
888 888
889 889 $ cat > ../stripstalephasecache.py << EOF
890 890 > from mercurial import extensions, localrepo
891 891 > def transactioncallback(orig, repo, desc, *args, **kwargs):
892 892 > def test(transaction):
893 893 > # observe cache inconsistency
894 894 > try:
895 895 > [repo.changelog.node(r) for r in repo.revs("not public()")]
896 896 > except IndexError:
897 897 > repo.ui.status("Index error!\n")
898 898 > transaction = orig(repo, desc, *args, **kwargs)
899 899 > # warm up the phase cache
900 900 > list(repo.revs("not public()"))
901 901 > if desc != 'strip':
902 902 > transaction.addpostclose("phase invalidation test", test)
903 903 > return transaction
904 904 > def extsetup(ui):
905 905 > extensions.wrapfunction(localrepo.localrepository, "transaction",
906 906 > transactioncallback)
907 907 > EOF
908 908 $ hg up -C 2
909 909 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
910 910 $ echo k > k
911 911 $ hg add k
912 912 $ hg commit -m commitK
913 913 $ echo l > l
914 914 $ hg add l
915 915 $ hg commit -m commitL
916 916 $ hg book -r tip blah
917 917 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
918 918 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
919 919 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg (glob)
920 920 $ hg up -C 1
921 921 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
922 922
923 923 Error during post-close callback of the strip transaction
924 924 (They should be gracefully handled and reported)
925 925
926 926 $ cat > ../crashstrip.py << EOF
927 927 > from mercurial import error
928 928 > def reposetup(ui, repo):
929 929 > class crashstriprepo(repo.__class__):
930 930 > def transaction(self, desc, *args, **kwargs):
931 931 > tr = super(crashstriprepo, self).transaction(desc, *args, **kwargs)
932 932 > if desc == 'strip':
933 933 > def crash(tra): raise error.Abort('boom')
934 934 > tr.addpostclose('crash', crash)
935 935 > return tr
936 936 > repo.__class__ = crashstriprepo
937 937 > EOF
938 938 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
939 939 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob)
940 940 strip failed, backup bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
941 941 abort: boom
942 942 [255]
943 943
944 944 Use delayedstrip to strip inside a transaction
945 945
946 946 $ cd $TESTTMP
947 947 $ hg init delayedstrip
948 948 $ cd delayedstrip
949 949 $ hg debugdrawdag <<'EOS'
950 950 > D
951 951 > |
952 952 > C F H # Commit on top of "I",
953 953 > | |/| # Strip B+D+I+E+G+H+Z
954 954 > I B E G
955 955 > \|/
956 956 > A Z
957 957 > EOS
958 958 $ cp -R . ../scmutilcleanup
959 959
960 960 $ hg up -C I
961 961 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
962 962 $ echo 3 >> I
963 963 $ cat > $TESTTMP/delayedstrip.py <<EOF
964 964 > from mercurial import repair, commands
965 965 > def reposetup(ui, repo):
966 966 > def getnodes(expr):
967 967 > return [repo.changelog.node(r) for r in repo.revs(expr)]
968 968 > with repo.wlock():
969 969 > with repo.lock():
970 970 > with repo.transaction('delayedstrip'):
971 971 > repair.delayedstrip(ui, repo, getnodes('B+I+Z+D+E'), 'J')
972 972 > repair.delayedstrip(ui, repo, getnodes('G+H+Z'), 'I')
973 973 > commands.commit(ui, repo, message='J', date='0 0')
974 974 > EOF
975 975 $ hg log -r . -T '\n' --config extensions.t=$TESTTMP/delayedstrip.py
976 976 warning: orphaned descendants detected, not stripping 08ebfeb61bac, 112478962961, 7fb047a69f22
977 saved backup bundle to $TESTTMP/delayedstrip/.hg/strip-backup/f585351a92f8-81fa23b0-I.hg (glob)
977 saved backup bundle to $TESTTMP/delayedstrip/.hg/strip-backup/f585351a92f8-17475721-I.hg (glob)
978 978
979 979 $ hg log -G -T '{rev}:{node|short} {desc}' -r 'sort(all(), topo)'
980 980 @ 6:2f2d51af6205 J
981 981 |
982 982 o 3:08ebfeb61bac I
983 983 |
984 984 | o 5:64a8289d2492 F
985 985 | |
986 986 | o 2:7fb047a69f22 E
987 987 |/
988 988 | o 4:26805aba1e60 C
989 989 | |
990 990 | o 1:112478962961 B
991 991 |/
992 992 o 0:426bada5c675 A
993 993
994 994 Test high-level scmutil.cleanupnodes API
995 995
996 996 $ cd $TESTTMP/scmutilcleanup
997 997 $ hg debugdrawdag <<'EOS'
998 998 > D2 F2 G2 # D2, F2, G2 are replacements for D, F, G
999 999 > | | |
1000 1000 > C H G
1001 1001 > EOS
1002 1002 $ for i in B C D F G I Z; do
1003 1003 > hg bookmark -i -r $i b-$i
1004 1004 > done
1005 1005 $ hg bookmark -i -r E 'b-F@divergent1'
1006 1006 $ hg bookmark -i -r H 'b-F@divergent2'
1007 1007 $ hg bookmark -i -r G 'b-F@divergent3'
1008 1008 $ cp -R . ../scmutilcleanup.obsstore
1009 1009
1010 1010 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
1011 1011 > from mercurial import scmutil
1012 1012 > def reposetup(ui, repo):
1013 1013 > def nodes(expr):
1014 1014 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1015 1015 > def node(expr):
1016 1016 > return nodes(expr)[0]
1017 1017 > with repo.wlock():
1018 1018 > with repo.lock():
1019 1019 > with repo.transaction('delayedstrip'):
1020 1020 > mapping = {node('F'): [node('F2')],
1021 1021 > node('D'): [node('D2')],
1022 1022 > node('G'): [node('G2')]}
1023 1023 > scmutil.cleanupnodes(repo, mapping, 'replace')
1024 1024 > scmutil.cleanupnodes(repo, nodes('((B::)+I+Z)-D2'), 'replace')
1025 1025 > EOF
1026 1026 $ hg log -r . -T '\n' --config extensions.t=$TESTTMP/scmutilcleanup.py
1027 1027 warning: orphaned descendants detected, not stripping 112478962961, 1fc8102cda62, 26805aba1e60
1028 1028 saved backup bundle to $TESTTMP/scmutilcleanup/.hg/strip-backup/f585351a92f8-73fb7c03-replace.hg (glob)
1029 1029
1030 1030 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1031 1031 o 8:1473d4b996d1 G2 b-F@divergent3 b-G
1032 1032 |
1033 | o 7:d94e89b773b6 F2 b-F
1033 | o 7:d11b3456a873 F2 b-F
1034 1034 | |
1035 | o 5:7fe5bac4c918 H
1035 | o 5:5cb05ba470a7 H
1036 1036 |/|
1037 1037 | o 3:7fb047a69f22 E b-F@divergent1
1038 1038 | |
1039 1039 | | o 6:7c78f703e465 D2 b-D
1040 1040 | | |
1041 1041 | | o 4:26805aba1e60 C
1042 1042 | | |
1043 1043 | | o 2:112478962961 B
1044 1044 | |/
1045 1045 o | 1:1fc8102cda62 G
1046 1046 /
1047 1047 o 0:426bada5c675 A b-B b-C b-I
1048 1048
1049 1049 $ hg bookmark
1050 1050 b-B 0:426bada5c675
1051 1051 b-C 0:426bada5c675
1052 1052 b-D 6:7c78f703e465
1053 b-F 7:d94e89b773b6
1053 b-F 7:d11b3456a873
1054 1054 b-F@divergent1 3:7fb047a69f22
1055 1055 b-F@divergent3 8:1473d4b996d1
1056 1056 b-G 8:1473d4b996d1
1057 1057 b-I 0:426bada5c675
1058 1058 b-Z -1:000000000000
1059 1059
1060 1060 Test the above using obsstore "by the way". Not directly related to strip, but
1061 1061 we have reusable code here
1062 1062
1063 1063 $ cd $TESTTMP/scmutilcleanup.obsstore
1064 1064 $ cat >> .hg/hgrc <<EOF
1065 1065 > [experimental]
1066 1066 > evolution=all
1067 1067 > evolution.track-operation=1
1068 1068 > EOF
1069 1069
1070 1070 $ hg log -r . -T '\n' --config extensions.t=$TESTTMP/scmutilcleanup.py
1071 1071
1072 1072 $ rm .hg/localtags
1073 1073 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1074 1074 o 12:1473d4b996d1 G2 b-F@divergent3 b-G
1075 1075 |
1076 | o 11:d94e89b773b6 F2 b-F
1076 | o 11:d11b3456a873 F2 b-F
1077 1077 | |
1078 | o 8:7fe5bac4c918 H
1078 | o 8:5cb05ba470a7 H
1079 1079 |/|
1080 1080 | o 4:7fb047a69f22 E b-F@divergent1
1081 1081 | |
1082 1082 | | o 10:7c78f703e465 D2 b-D
1083 1083 | | |
1084 1084 | | x 6:26805aba1e60 C
1085 1085 | | |
1086 1086 | | x 3:112478962961 B
1087 1087 | |/
1088 1088 x | 1:1fc8102cda62 G
1089 1089 /
1090 1090 o 0:426bada5c675 A b-B b-C b-I
1091 1091
1092 1092 $ hg debugobsolete
1093 1093 1fc8102cda6204549f031015641606ccf5513ec3 1473d4b996d1d1b121de6b39fab6a04fbf9d873e 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1094 64a8289d249234b9886244d379f15e6b650b28e3 d94e89b773b67e72642a931159ada8d1a9246998 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1094 64a8289d249234b9886244d379f15e6b650b28e3 d11b3456a873daec7c7bc53e5622e8df6d741bd2 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1095 1095 f585351a92f85104bff7c284233c338b10eb1df7 7c78f703e465d73102cc8780667ce269c5208a40 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1096 1096 48b9aae0607f43ff110d84e6883c151942add5ab 0 {0000000000000000000000000000000000000000} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1097 1097 112478962961147124edd43549aedd1a335e44bf 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1098 1098 08ebfeb61bac6e3f12079de774d285a0d6689eba 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1099 1099 26805aba1e600a82e93661149f2313866a221a7b 0 {112478962961147124edd43549aedd1a335e44bf} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
General Comments 0
You need to be logged in to leave comments. Login now