##// END OF EJS Templates
stack: return a sorted smartrev by default...
Boris Feld -
r37022:68fcc550 default
parent child Browse files
Show More
@@ -1,415 +1,415
1 1 # destutil.py - Mercurial utility function for command destination
2 2 #
3 3 # Copyright Matt Mackall <mpm@selenic.com> and other
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 from __future__ import absolute_import
9 9
10 10 from .i18n import _
11 11 from . import (
12 12 bookmarks,
13 13 error,
14 14 obsutil,
15 15 scmutil,
16 16 stack
17 17 )
18 18
19 19 def _destupdateobs(repo, clean):
20 20 """decide of an update destination from obsolescence markers"""
21 21 node = None
22 22 wc = repo[None]
23 23 p1 = wc.p1()
24 24 movemark = None
25 25
26 26 if p1.obsolete() and not p1.children():
27 27 # allow updating to successors
28 28 successors = obsutil.successorssets(repo, p1.node())
29 29
30 30 # behavior of certain cases is as follows,
31 31 #
32 32 # divergent changesets: update to highest rev, similar to what
33 33 # is currently done when there are more than one head
34 34 # (i.e. 'tip')
35 35 #
36 36 # replaced changesets: same as divergent except we know there
37 37 # is no conflict
38 38 #
39 39 # pruned changeset: no update is done; though, we could
40 40 # consider updating to the first non-obsolete parent,
41 41 # similar to what is current done for 'hg prune'
42 42
43 43 if successors:
44 44 # flatten the list here handles both divergent (len > 1)
45 45 # and the usual case (len = 1)
46 46 successors = [n for sub in successors for n in sub]
47 47
48 48 # get the max revision for the given successors set,
49 49 # i.e. the 'tip' of a set
50 50 node = repo.revs('max(%ln)', successors).first()
51 51 if bookmarks.isactivewdirparent(repo):
52 52 movemark = repo['.'].node()
53 53 return node, movemark, None
54 54
55 55 def _destupdatebook(repo, clean):
56 56 """decide on an update destination from active bookmark"""
57 57 # we also move the active bookmark, if any
58 58 activemark = None
59 59 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
60 60 if node is not None:
61 61 activemark = node
62 62 return node, movemark, activemark
63 63
64 64 def _destupdatebranch(repo, clean):
65 65 """decide on an update destination from current branch
66 66
67 67 This ignores closed branch heads.
68 68 """
69 69 wc = repo[None]
70 70 movemark = node = None
71 71 currentbranch = wc.branch()
72 72
73 73 if clean:
74 74 currentbranch = repo['.'].branch()
75 75
76 76 if currentbranch in repo.branchmap():
77 77 heads = repo.branchheads(currentbranch)
78 78 if heads:
79 79 node = repo.revs('max(.::(%ln))', heads).first()
80 80 if bookmarks.isactivewdirparent(repo):
81 81 movemark = repo['.'].node()
82 82 elif currentbranch == 'default' and not wc.p1():
83 83 # "null" parent belongs to "default" branch, but it doesn't exist, so
84 84 # update to the tipmost non-closed branch head
85 85 node = repo.revs('max(head() and not closed())').first()
86 86 else:
87 87 node = repo['.'].node()
88 88 return node, movemark, None
89 89
90 90 def _destupdatebranchfallback(repo, clean):
91 91 """decide on an update destination from closed heads in current branch"""
92 92 wc = repo[None]
93 93 currentbranch = wc.branch()
94 94 movemark = None
95 95 if currentbranch in repo.branchmap():
96 96 # here, all descendant branch heads are closed
97 97 heads = repo.branchheads(currentbranch, closed=True)
98 98 assert heads, "any branch has at least one head"
99 99 node = repo.revs('max(.::(%ln))', heads).first()
100 100 assert node is not None, ("any revision has at least "
101 101 "one descendant branch head")
102 102 if bookmarks.isactivewdirparent(repo):
103 103 movemark = repo['.'].node()
104 104 else:
105 105 # here, no "default" branch, and all branches are closed
106 106 node = repo.lookup('tip')
107 107 assert node is not None, "'tip' exists even in empty repository"
108 108 return node, movemark, None
109 109
110 110 # order in which each step should be evaluated
111 111 # steps are run until one finds a destination
112 112 destupdatesteps = ['evolution', 'bookmark', 'branch', 'branchfallback']
113 113 # mapping to ease extension overriding steps.
114 114 destupdatestepmap = {'evolution': _destupdateobs,
115 115 'bookmark': _destupdatebook,
116 116 'branch': _destupdatebranch,
117 117 'branchfallback': _destupdatebranchfallback,
118 118 }
119 119
120 120 def destupdate(repo, clean=False):
121 121 """destination for bare update operation
122 122
123 123 return (rev, movemark, activemark)
124 124
125 125 - rev: the revision to update to,
126 126 - movemark: node to move the active bookmark from
127 127 (cf bookmark.calculate update),
128 128 - activemark: a bookmark to activate at the end of the update.
129 129 """
130 130 node = movemark = activemark = None
131 131
132 132 for step in destupdatesteps:
133 133 node, movemark, activemark = destupdatestepmap[step](repo, clean)
134 134 if node is not None:
135 135 break
136 136 rev = repo[node].rev()
137 137
138 138 return rev, movemark, activemark
139 139
140 140 msgdestmerge = {
141 141 # too many matching divergent bookmark
142 142 'toomanybookmarks':
143 143 {'merge':
144 144 (_("multiple matching bookmarks to merge -"
145 145 " please merge with an explicit rev or bookmark"),
146 146 _("run 'hg heads' to see all heads")),
147 147 'rebase':
148 148 (_("multiple matching bookmarks to rebase -"
149 149 " please rebase to an explicit rev or bookmark"),
150 150 _("run 'hg heads' to see all heads")),
151 151 },
152 152 # no other matching divergent bookmark
153 153 'nootherbookmarks':
154 154 {'merge':
155 155 (_("no matching bookmark to merge - "
156 156 "please merge with an explicit rev or bookmark"),
157 157 _("run 'hg heads' to see all heads")),
158 158 'rebase':
159 159 (_("no matching bookmark to rebase - "
160 160 "please rebase to an explicit rev or bookmark"),
161 161 _("run 'hg heads' to see all heads")),
162 162 },
163 163 # branch have too many unbookmarked heads, no obvious destination
164 164 'toomanyheads':
165 165 {'merge':
166 166 (_("branch '%s' has %d heads - please merge with an explicit rev"),
167 167 _("run 'hg heads .' to see heads")),
168 168 'rebase':
169 169 (_("branch '%s' has %d heads - please rebase to an explicit rev"),
170 170 _("run 'hg heads .' to see heads")),
171 171 },
172 172 # branch have no other unbookmarked heads
173 173 'bookmarkedheads':
174 174 {'merge':
175 175 (_("heads are bookmarked - please merge with an explicit rev"),
176 176 _("run 'hg heads' to see all heads")),
177 177 'rebase':
178 178 (_("heads are bookmarked - please rebase to an explicit rev"),
179 179 _("run 'hg heads' to see all heads")),
180 180 },
181 181 # branch have just a single heads, but there is other branches
182 182 'nootherbranchheads':
183 183 {'merge':
184 184 (_("branch '%s' has one head - please merge with an explicit rev"),
185 185 _("run 'hg heads' to see all heads")),
186 186 'rebase':
187 187 (_("branch '%s' has one head - please rebase to an explicit rev"),
188 188 _("run 'hg heads' to see all heads")),
189 189 },
190 190 # repository have a single head
191 191 'nootherheads':
192 192 {'merge':
193 193 (_('nothing to merge'),
194 194 None),
195 195 'rebase':
196 196 (_('nothing to rebase'),
197 197 None),
198 198 },
199 199 # repository have a single head and we are not on it
200 200 'nootherheadsbehind':
201 201 {'merge':
202 202 (_('nothing to merge'),
203 203 _("use 'hg update' instead")),
204 204 'rebase':
205 205 (_('nothing to rebase'),
206 206 _("use 'hg update' instead")),
207 207 },
208 208 # We are not on a head
209 209 'notatheads':
210 210 {'merge':
211 211 (_('working directory not at a head revision'),
212 212 _("use 'hg update' or merge with an explicit revision")),
213 213 'rebase':
214 214 (_('working directory not at a head revision'),
215 215 _("use 'hg update' or rebase to an explicit revision"))
216 216 },
217 217 'emptysourceset':
218 218 {'merge':
219 219 (_('source set is empty'),
220 220 None),
221 221 'rebase':
222 222 (_('source set is empty'),
223 223 None),
224 224 },
225 225 'multiplebranchessourceset':
226 226 {'merge':
227 227 (_('source set is rooted in multiple branches'),
228 228 None),
229 229 'rebase':
230 230 (_('rebaseset is rooted in multiple named branches'),
231 231 _('specify an explicit destination with --dest')),
232 232 },
233 233 }
234 234
235 235 def _destmergebook(repo, action='merge', sourceset=None, destspace=None):
236 236 """find merge destination in the active bookmark case"""
237 237 node = None
238 238 bmheads = bookmarks.headsforactive(repo)
239 239 curhead = repo[repo._activebookmark].node()
240 240 if len(bmheads) == 2:
241 241 if curhead == bmheads[0]:
242 242 node = bmheads[1]
243 243 else:
244 244 node = bmheads[0]
245 245 elif len(bmheads) > 2:
246 246 msg, hint = msgdestmerge['toomanybookmarks'][action]
247 247 raise error.ManyMergeDestAbort(msg, hint=hint)
248 248 elif len(bmheads) <= 1:
249 249 msg, hint = msgdestmerge['nootherbookmarks'][action]
250 250 raise error.NoMergeDestAbort(msg, hint=hint)
251 251 assert node is not None
252 252 return node
253 253
254 254 def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True,
255 255 destspace=None):
256 256 """find merge destination based on branch heads"""
257 257 node = None
258 258
259 259 if sourceset is None:
260 260 sourceset = [repo[repo.dirstate.p1()].rev()]
261 261 branch = repo.dirstate.branch()
262 262 elif not sourceset:
263 263 msg, hint = msgdestmerge['emptysourceset'][action]
264 264 raise error.NoMergeDestAbort(msg, hint=hint)
265 265 else:
266 266 branch = None
267 267 for ctx in repo.set('roots(%ld::%ld)', sourceset, sourceset):
268 268 if branch is not None and ctx.branch() != branch:
269 269 msg, hint = msgdestmerge['multiplebranchessourceset'][action]
270 270 raise error.ManyMergeDestAbort(msg, hint=hint)
271 271 branch = ctx.branch()
272 272
273 273 bheads = repo.branchheads(branch)
274 274 onhead = repo.revs('%ld and %ln', sourceset, bheads)
275 275 if onheadcheck and not onhead:
276 276 # Case A: working copy if not on a head. (merge only)
277 277 #
278 278 # This is probably a user mistake We bailout pointing at 'hg update'
279 279 if len(repo.heads()) <= 1:
280 280 msg, hint = msgdestmerge['nootherheadsbehind'][action]
281 281 else:
282 282 msg, hint = msgdestmerge['notatheads'][action]
283 283 raise error.Abort(msg, hint=hint)
284 284 # remove heads descendants of source from the set
285 285 bheads = list(repo.revs('%ln - (%ld::)', bheads, sourceset))
286 286 # filters out bookmarked heads
287 287 nbhs = list(repo.revs('%ld - bookmark()', bheads))
288 288
289 289 if destspace is not None:
290 290 # restrict search space
291 291 # used in the 'hg pull --rebase' case, see issue 5214.
292 292 nbhs = list(repo.revs('%ld and %ld', destspace, nbhs))
293 293
294 294 if len(nbhs) > 1:
295 295 # Case B: There is more than 1 other anonymous heads
296 296 #
297 297 # This means that there will be more than 1 candidate. This is
298 298 # ambiguous. We abort asking the user to pick as explicit destination
299 299 # instead.
300 300 msg, hint = msgdestmerge['toomanyheads'][action]
301 301 msg %= (branch, len(bheads) + 1)
302 302 raise error.ManyMergeDestAbort(msg, hint=hint)
303 303 elif not nbhs:
304 304 # Case B: There is no other anonymous heads
305 305 #
306 306 # This means that there is no natural candidate to merge with.
307 307 # We abort, with various messages for various cases.
308 308 if bheads:
309 309 msg, hint = msgdestmerge['bookmarkedheads'][action]
310 310 elif len(repo.heads()) > 1:
311 311 msg, hint = msgdestmerge['nootherbranchheads'][action]
312 312 msg %= branch
313 313 elif not onhead:
314 314 # if 'onheadcheck == False' (rebase case),
315 315 # this was not caught in Case A.
316 316 msg, hint = msgdestmerge['nootherheadsbehind'][action]
317 317 else:
318 318 msg, hint = msgdestmerge['nootherheads'][action]
319 319 raise error.NoMergeDestAbort(msg, hint=hint)
320 320 else:
321 321 node = nbhs[0]
322 322 assert node is not None
323 323 return node
324 324
325 325 def destmerge(repo, action='merge', sourceset=None, onheadcheck=True,
326 326 destspace=None):
327 327 """return the default destination for a merge
328 328
329 329 (or raise exception about why it can't pick one)
330 330
331 331 :action: the action being performed, controls emitted error message
332 332 """
333 333 # destspace is here to work around issues with `hg pull --rebase` see
334 334 # issue5214 for details
335 335 if repo._activebookmark:
336 336 node = _destmergebook(repo, action=action, sourceset=sourceset,
337 337 destspace=destspace)
338 338 else:
339 339 node = _destmergebranch(repo, action=action, sourceset=sourceset,
340 340 onheadcheck=onheadcheck, destspace=destspace)
341 341 return repo[node].rev()
342 342
343 343 def desthistedit(ui, repo):
344 344 """Default base revision to edit for `hg histedit`."""
345 345 default = ui.config('histedit', 'defaultrev')
346 346
347 347 if default is None:
348 348 revs = stack.getstack(repo)
349 349 elif default:
350 350 revs = scmutil.revrange(repo, [default])
351 351
352 352 if revs:
353 353 # The revset supplied by the user may not be in ascending order nor
354 354 # take the first revision. So do this manually.
355 355 revs.sort()
356 356 return revs.first()
357 357
358 358 return None
359 359
360 360 def stackbase(ui, repo):
361 361 revs = stack.getstack(repo)
362 return revs.last() if revs else None
362 return revs.first() if revs else None
363 363
364 364 def _statusotherbook(ui, repo):
365 365 bmheads = bookmarks.headsforactive(repo)
366 366 curhead = repo[repo._activebookmark].node()
367 367 if repo.revs('%n and parents()', curhead):
368 368 # we are on the active bookmark
369 369 bmheads = [b for b in bmheads if curhead != b]
370 370 if bmheads:
371 371 msg = _('%i other divergent bookmarks for "%s"\n')
372 372 ui.status(msg % (len(bmheads), repo._activebookmark))
373 373
374 374 def _statusotherbranchheads(ui, repo):
375 375 currentbranch = repo.dirstate.branch()
376 376 allheads = repo.branchheads(currentbranch, closed=True)
377 377 heads = repo.branchheads(currentbranch)
378 378 if repo.revs('%ln and parents()', allheads):
379 379 # we are on a head, even though it might be closed
380 380 #
381 381 # on closed otherheads
382 382 # ========= ==========
383 383 # o 0 all heads for current branch are closed
384 384 # N only descendant branch heads are closed
385 385 # x 0 there is only one non-closed branch head
386 386 # N there are some non-closed branch heads
387 387 # ========= ==========
388 388 otherheads = repo.revs('%ln - parents()', heads)
389 389 if repo['.'].closesbranch():
390 390 ui.warn(_('no open descendant heads on branch "%s", '
391 391 'updating to a closed head\n') %
392 392 (currentbranch))
393 393 if otherheads:
394 394 ui.warn(_("(committing will reopen the head, "
395 395 "use 'hg heads .' to see %i other heads)\n") %
396 396 (len(otherheads)))
397 397 else:
398 398 ui.warn(_('(committing will reopen branch "%s")\n') %
399 399 (currentbranch))
400 400 elif otherheads:
401 401 curhead = repo['.']
402 402 ui.status(_('updated to "%s: %s"\n') % (curhead,
403 403 curhead.description().split('\n')[0]))
404 404 ui.status(_('%i other heads for branch "%s"\n') %
405 405 (len(otherheads), currentbranch))
406 406
407 407 def statusotherdests(ui, repo):
408 408 """Print message about other head"""
409 409 # XXX we should probably include a hint:
410 410 # - about what to do
411 411 # - how to see such heads
412 412 if repo._activebookmark:
413 413 _statusotherbook(ui, repo)
414 414 else:
415 415 _statusotherbranchheads(ui, repo)
@@ -1,27 +1,29
1 1 # stack.py - Mercurial functions for stack definition
2 2 #
3 3 # Copyright Matt Mackall <mpm@selenic.com> and other
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 from __future__ import absolute_import
9 9
10 10 from . import (
11 11 revsetlang,
12 12 scmutil,
13 13 )
14 14
15 15 def getstack(repo, rev=None):
16 """return a smartrev of the stack containing either rev if it is not None
17 or the current working directory parent.
16 """return a sorted smartrev of the stack containing either rev if it is
17 not None or the current working directory parent.
18 18
19 19 The stack will always contain all drafts changesets which are ancestors to
20 20 the revision and are not merges.
21 21 """
22 22 if rev is None:
23 23 rev = '.'
24 24
25 25 revspec = 'reverse(only(%s) and not public() and not ::merge())'
26 26 revset = revsetlang.formatspec(revspec, rev)
27 return scmutil.revrange(repo, [revset])
27 revisions = scmutil.revrange(repo, [revset])
28 revisions.sort()
29 return revisions
@@ -1,253 +1,253
1 1
2 2 This test test the low-level definition of stack, agnostic from all formatting
3 3
4 4 Initial setup
5 5
6 6 $ cat << EOF >> $HGRCPATH
7 7 > [ui]
8 8 > logtemplate = {rev} {branch} {phase} {desc|firstline}\n
9 9 > [extensions]
10 10 > rebase=
11 11 > [experimental]
12 12 > evolution=createmarkers,exchange,allowunstable
13 13 > EOF
14 14
15 15 $ hg init main
16 16 $ cd main
17 17 $ hg branch other
18 18 marked working directory as branch other
19 19 (branches are permanent and global, did you want a bookmark?)
20 20 $ echo aaa > aaa
21 21 $ hg add aaa
22 22 $ hg commit -m c_a
23 23 $ echo aaa > bbb
24 24 $ hg add bbb
25 25 $ hg commit -m c_b
26 26 $ hg branch foo
27 27 marked working directory as branch foo
28 28 $ echo aaa > ccc
29 29 $ hg add ccc
30 30 $ hg commit -m c_c
31 31 $ echo aaa > ddd
32 32 $ hg add ddd
33 33 $ hg commit -m c_d
34 34 $ echo aaa > eee
35 35 $ hg add eee
36 36 $ hg commit -m c_e
37 37 $ echo aaa > fff
38 38 $ hg add fff
39 39 $ hg commit -m c_f
40 40 $ hg log -G
41 41 @ 5 foo draft c_f
42 42 |
43 43 o 4 foo draft c_e
44 44 |
45 45 o 3 foo draft c_d
46 46 |
47 47 o 2 foo draft c_c
48 48 |
49 49 o 1 other draft c_b
50 50 |
51 51 o 0 other draft c_a
52 52
53 53
54 54 Check that stack doesn't include public changesets
55 55 --------------------------------------------------
56 56
57 57 $ hg up other
58 58 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
59 59 $ hg log -G -r "stack()"
60 60 @ 1 other draft c_b
61 61 |
62 62 o 0 other draft c_a
63 63
64 64 $ hg phase --public 'branch("other")'
65 65 $ hg log -G -r "stack()"
66 66 $ hg up foo
67 67 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 68
69 69 Simple test
70 70 -----------
71 71
72 72 'stack()' list all changeset in the branch
73 73
74 74 $ hg branch
75 75 foo
76 76 $ hg log -G -r "stack()"
77 77 @ 5 foo draft c_f
78 78 |
79 79 o 4 foo draft c_e
80 80 |
81 81 o 3 foo draft c_d
82 82 |
83 83 o 2 foo draft c_c
84 84 |
85 85 ~
86 86
87 87 Case with some of the branch unstable
88 88 ------------------------------------
89 89
90 90 $ hg up 3
91 91 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
92 92 $ echo bbb > ddd
93 93 $ hg commit --amend
94 94 2 new orphan changesets
95 95 $ hg log -G
96 96 @ 6 foo draft c_d
97 97 |
98 98 | * 5 foo draft c_f
99 99 | |
100 100 | * 4 foo draft c_e
101 101 | |
102 102 | x 3 foo draft c_d
103 103 |/
104 104 o 2 foo draft c_c
105 105 |
106 106 o 1 other public c_b
107 107 |
108 108 o 0 other public c_a
109 109
110 110 $ hg log -G -r "stack()"
111 111 @ 6 foo draft c_d
112 112 |
113 113 ~
114 114 $ hg up -r "desc(c_e)"
115 115 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
116 116 $ hg log -G -r "stack()"
117 117 @ 4 foo draft c_e
118 118 |
119 119 x 3 foo draft c_d
120 120 |
121 121 ~
122 122 $ hg up -r "desc(c_d)"
123 123 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
124 124
125 125 $ hg log -G -r "stack()"
126 126 @ 6 foo draft c_d
127 127 |
128 128 ~
129 129
130 130 Case with multiple topological heads
131 131 ------------------------------------
132 132
133 133 Make things linear again
134 134
135 135 $ hg rebase -s 'desc(c_e)' -d 'desc(c_d) - obsolete()'
136 136 rebasing 4:4f2a69f6d380 "c_e"
137 137 rebasing 5:913c298d8b0a "c_f"
138 138 $ hg log -G
139 139 o 8 foo draft c_f
140 140 |
141 141 o 7 foo draft c_e
142 142 |
143 143 @ 6 foo draft c_d
144 144 |
145 145 o 2 foo draft c_c
146 146 |
147 147 o 1 other public c_b
148 148 |
149 149 o 0 other public c_a
150 150
151 151
152 152 Create the second branch
153 153
154 154 $ hg up 'desc(c_d)'
155 155 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 156 $ echo aaa > ggg
157 157 $ hg add ggg
158 158 $ hg commit -m c_g
159 159 created new head
160 160 $ echo aaa > hhh
161 161 $ hg add hhh
162 162 $ hg commit -m c_h
163 163 $ hg log -G
164 164 @ 10 foo draft c_h
165 165 |
166 166 o 9 foo draft c_g
167 167 |
168 168 | o 8 foo draft c_f
169 169 | |
170 170 | o 7 foo draft c_e
171 171 |/
172 172 o 6 foo draft c_d
173 173 |
174 174 o 2 foo draft c_c
175 175 |
176 176 o 1 other public c_b
177 177 |
178 178 o 0 other public c_a
179 179
180 180
181 181 Test output
182 182
183 183 $ hg log -G -r "stack(10)"
184 184 @ 10 foo draft c_h
185 185 |
186 186 o 9 foo draft c_g
187 187 |
188 188 ~
189 189 $ hg log -G -r "stack(8)"
190 190 o 8 foo draft c_f
191 191 |
192 192 o 7 foo draft c_e
193 193 |
194 194 ~
195 195 $ hg log -G -r "stack(head())"
196 196 @ 10 foo draft c_h
197 197 |
198 198 o 9 foo draft c_g
199 199 |
200 200 ~
201 201 o 8 foo draft c_f
202 202 |
203 203 o 7 foo draft c_e
204 204 |
205 205 ~
206 206 Check the stack order
207 207 $ hg log -r "first(stack())"
208 10 foo draft c_h
208 9 foo draft c_g
209 209 $ hg log -r "first(stack(10))"
210 10 foo draft c_h
210 9 foo draft c_g
211 211 $ hg log -r "first(stack(8))"
212 8 foo draft c_f
212 7 foo draft c_e
213 213 $ hg log -r "first(stack(head()))"
214 8 foo draft c_f
214 7 foo draft c_e
215 215
216 216 Case with multiple heads with unstability involved
217 217 --------------------------------------------------
218 218
219 219 We amend the message to make sure the display base pick the right changeset
220 220
221 221 $ hg up 'desc(c_d)'
222 222 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
223 223 $ echo ccc > ddd
224 224 $ hg commit --amend -m 'c_D'
225 225 4 new orphan changesets
226 226 $ hg rebase -d . -s 'desc(c_g)'
227 227 rebasing 9:2ebb6e48ab8a "c_g"
228 228 rebasing 10:634f38e27a1d "c_h"
229 229 $ hg log -G
230 230 o 13 foo draft c_h
231 231 |
232 232 o 12 foo draft c_g
233 233 |
234 234 @ 11 foo draft c_D
235 235 |
236 236 | * 8 foo draft c_f
237 237 | |
238 238 | * 7 foo draft c_e
239 239 | |
240 240 | x 6 foo draft c_d
241 241 |/
242 242 o 2 foo draft c_c
243 243 |
244 244 o 1 other public c_b
245 245 |
246 246 o 0 other public c_a
247 247
248 248
249 249 We should improve stack definition to also show 12 and 13 here
250 250 $ hg log -G -r "stack()"
251 251 @ 11 foo draft c_D
252 252 |
253 253 ~
General Comments 0
You need to be logged in to leave comments. Login now