##// END OF EJS Templates
update: fix bare --clean to work on new branch (issue5003) (BC)...
liscju -
r29284:1c716700 default
parent child Browse files
Show More
@@ -1,433 +1,437 b''
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 obsolete,
15 15 )
16 16
17 17 def _destupdatevalidate(repo, rev, clean, check):
18 18 """validate that the destination comply to various rules
19 19
20 20 This exists as its own function to help wrapping from extensions."""
21 21 wc = repo[None]
22 22 p1 = wc.p1()
23 23 if not clean:
24 24 # Check that the update is linear.
25 25 #
26 26 # Mercurial do not allow update-merge for non linear pattern
27 27 # (that would be technically possible but was considered too confusing
28 28 # for user a long time ago)
29 29 #
30 30 # See mercurial.merge.update for details
31 31 if p1.rev() not in repo.changelog.ancestors([rev], inclusive=True):
32 32 dirty = wc.dirty(missing=True)
33 33 foreground = obsolete.foreground(repo, [p1.node()])
34 34 if not repo[rev].node() in foreground:
35 35 if dirty:
36 36 msg = _("uncommitted changes")
37 37 hint = _("commit and merge, or update --clean to"
38 38 " discard changes")
39 39 raise error.UpdateAbort(msg, hint=hint)
40 40 elif not check: # destination is not a descendant.
41 41 msg = _("not a linear update")
42 42 hint = _("merge or update --check to force update")
43 43 raise error.UpdateAbort(msg, hint=hint)
44 44
45 45 def _destupdateobs(repo, clean, check):
46 46 """decide of an update destination from obsolescence markers"""
47 47 node = None
48 48 wc = repo[None]
49 49 p1 = wc.p1()
50 50 movemark = None
51 51
52 52 if p1.obsolete() and not p1.children():
53 53 # allow updating to successors
54 54 successors = obsolete.successorssets(repo, p1.node())
55 55
56 56 # behavior of certain cases is as follows,
57 57 #
58 58 # divergent changesets: update to highest rev, similar to what
59 59 # is currently done when there are more than one head
60 60 # (i.e. 'tip')
61 61 #
62 62 # replaced changesets: same as divergent except we know there
63 63 # is no conflict
64 64 #
65 65 # pruned changeset: no update is done; though, we could
66 66 # consider updating to the first non-obsolete parent,
67 67 # similar to what is current done for 'hg prune'
68 68
69 69 if successors:
70 70 # flatten the list here handles both divergent (len > 1)
71 71 # and the usual case (len = 1)
72 72 successors = [n for sub in successors for n in sub]
73 73
74 74 # get the max revision for the given successors set,
75 75 # i.e. the 'tip' of a set
76 76 node = repo.revs('max(%ln)', successors).first()
77 77 if bookmarks.isactivewdirparent(repo):
78 78 movemark = repo['.'].node()
79 79 return node, movemark, None
80 80
81 81 def _destupdatebook(repo, clean, check):
82 82 """decide on an update destination from active bookmark"""
83 83 # we also move the active bookmark, if any
84 84 activemark = None
85 85 node, movemark = bookmarks.calculateupdate(repo.ui, repo, None)
86 86 if node is not None:
87 87 activemark = node
88 88 return node, movemark, activemark
89 89
90 90 def _destupdatebranch(repo, clean, check):
91 91 """decide on an update destination from current branch
92 92
93 93 This ignores closed branch heads.
94 94 """
95 95 wc = repo[None]
96 96 movemark = node = None
97 97 currentbranch = wc.branch()
98
99 if clean:
100 currentbranch = repo['.'].branch()
101
98 102 if currentbranch in repo.branchmap():
99 103 heads = repo.branchheads(currentbranch)
100 104 if heads:
101 105 node = repo.revs('max(.::(%ln))', heads).first()
102 106 if bookmarks.isactivewdirparent(repo):
103 107 movemark = repo['.'].node()
104 108 elif currentbranch == 'default' and not wc.p1():
105 109 # "null" parent belongs to "default" branch, but it doesn't exist, so
106 110 # update to the tipmost non-closed branch head
107 111 node = repo.revs('max(head() and not closed())').first()
108 112 else:
109 113 node = repo['.'].node()
110 114 return node, movemark, None
111 115
112 116 def _destupdatebranchfallback(repo, clean, check):
113 117 """decide on an update destination from closed heads in current branch"""
114 118 wc = repo[None]
115 119 currentbranch = wc.branch()
116 120 movemark = None
117 121 if currentbranch in repo.branchmap():
118 122 # here, all descendant branch heads are closed
119 123 heads = repo.branchheads(currentbranch, closed=True)
120 124 assert heads, "any branch has at least one head"
121 125 node = repo.revs('max(.::(%ln))', heads).first()
122 126 assert node is not None, ("any revision has at least "
123 127 "one descendant branch head")
124 128 if bookmarks.isactivewdirparent(repo):
125 129 movemark = repo['.'].node()
126 130 else:
127 131 # here, no "default" branch, and all branches are closed
128 132 node = repo.lookup('tip')
129 133 assert node is not None, "'tip' exists even in empty repository"
130 134 return node, movemark, None
131 135
132 136 # order in which each step should be evalutated
133 137 # steps are run until one finds a destination
134 138 destupdatesteps = ['evolution', 'bookmark', 'branch', 'branchfallback']
135 139 # mapping to ease extension overriding steps.
136 140 destupdatestepmap = {'evolution': _destupdateobs,
137 141 'bookmark': _destupdatebook,
138 142 'branch': _destupdatebranch,
139 143 'branchfallback': _destupdatebranchfallback,
140 144 }
141 145
142 146 def destupdate(repo, clean=False, check=False):
143 147 """destination for bare update operation
144 148
145 149 return (rev, movemark, activemark)
146 150
147 151 - rev: the revision to update to,
148 152 - movemark: node to move the active bookmark from
149 153 (cf bookmark.calculate update),
150 154 - activemark: a bookmark to activate at the end of the update.
151 155 """
152 156 node = movemark = activemark = None
153 157
154 158 for step in destupdatesteps:
155 159 node, movemark, activemark = destupdatestepmap[step](repo, clean, check)
156 160 if node is not None:
157 161 break
158 162 rev = repo[node].rev()
159 163
160 164 _destupdatevalidate(repo, rev, clean, check)
161 165
162 166 return rev, movemark, activemark
163 167
164 168 msgdestmerge = {
165 169 # too many matching divergent bookmark
166 170 'toomanybookmarks':
167 171 {'merge':
168 172 (_("multiple matching bookmarks to merge -"
169 173 " please merge with an explicit rev or bookmark"),
170 174 _("run 'hg heads' to see all heads")),
171 175 'rebase':
172 176 (_("multiple matching bookmarks to rebase -"
173 177 " please rebase to an explicit rev or bookmark"),
174 178 _("run 'hg heads' to see all heads")),
175 179 },
176 180 # no other matching divergent bookmark
177 181 'nootherbookmarks':
178 182 {'merge':
179 183 (_("no matching bookmark to merge - "
180 184 "please merge with an explicit rev or bookmark"),
181 185 _("run 'hg heads' to see all heads")),
182 186 'rebase':
183 187 (_("no matching bookmark to rebase - "
184 188 "please rebase to an explicit rev or bookmark"),
185 189 _("run 'hg heads' to see all heads")),
186 190 },
187 191 # branch have too many unbookmarked heads, no obvious destination
188 192 'toomanyheads':
189 193 {'merge':
190 194 (_("branch '%s' has %d heads - please merge with an explicit rev"),
191 195 _("run 'hg heads .' to see heads")),
192 196 'rebase':
193 197 (_("branch '%s' has %d heads - please rebase to an explicit rev"),
194 198 _("run 'hg heads .' to see heads")),
195 199 },
196 200 # branch have no other unbookmarked heads
197 201 'bookmarkedheads':
198 202 {'merge':
199 203 (_("heads are bookmarked - please merge with an explicit rev"),
200 204 _("run 'hg heads' to see all heads")),
201 205 'rebase':
202 206 (_("heads are bookmarked - please rebase to an explicit rev"),
203 207 _("run 'hg heads' to see all heads")),
204 208 },
205 209 # branch have just a single heads, but there is other branches
206 210 'nootherbranchheads':
207 211 {'merge':
208 212 (_("branch '%s' has one head - please merge with an explicit rev"),
209 213 _("run 'hg heads' to see all heads")),
210 214 'rebase':
211 215 (_("branch '%s' has one head - please rebase to an explicit rev"),
212 216 _("run 'hg heads' to see all heads")),
213 217 },
214 218 # repository have a single head
215 219 'nootherheads':
216 220 {'merge':
217 221 (_('nothing to merge'),
218 222 None),
219 223 'rebase':
220 224 (_('nothing to rebase'),
221 225 None),
222 226 },
223 227 # repository have a single head and we are not on it
224 228 'nootherheadsbehind':
225 229 {'merge':
226 230 (_('nothing to merge'),
227 231 _("use 'hg update' instead")),
228 232 'rebase':
229 233 (_('nothing to rebase'),
230 234 _("use 'hg update' instead")),
231 235 },
232 236 # We are not on a head
233 237 'notatheads':
234 238 {'merge':
235 239 (_('working directory not at a head revision'),
236 240 _("use 'hg update' or merge with an explicit revision")),
237 241 'rebase':
238 242 (_('working directory not at a head revision'),
239 243 _("use 'hg update' or rebase to an explicit revision"))
240 244 },
241 245 'emptysourceset':
242 246 {'merge':
243 247 (_('source set is empty'),
244 248 None),
245 249 'rebase':
246 250 (_('source set is empty'),
247 251 None),
248 252 },
249 253 'multiplebranchessourceset':
250 254 {'merge':
251 255 (_('source set is rooted in multiple branches'),
252 256 None),
253 257 'rebase':
254 258 (_('rebaseset is rooted in multiple named branches'),
255 259 _('specify an explicit destination with --dest')),
256 260 },
257 261 }
258 262
259 263 def _destmergebook(repo, action='merge', sourceset=None, destspace=None):
260 264 """find merge destination in the active bookmark case"""
261 265 node = None
262 266 bmheads = repo.bookmarkheads(repo._activebookmark)
263 267 curhead = repo[repo._activebookmark].node()
264 268 if len(bmheads) == 2:
265 269 if curhead == bmheads[0]:
266 270 node = bmheads[1]
267 271 else:
268 272 node = bmheads[0]
269 273 elif len(bmheads) > 2:
270 274 msg, hint = msgdestmerge['toomanybookmarks'][action]
271 275 raise error.ManyMergeDestAbort(msg, hint=hint)
272 276 elif len(bmheads) <= 1:
273 277 msg, hint = msgdestmerge['nootherbookmarks'][action]
274 278 raise error.NoMergeDestAbort(msg, hint=hint)
275 279 assert node is not None
276 280 return node
277 281
278 282 def _destmergebranch(repo, action='merge', sourceset=None, onheadcheck=True,
279 283 destspace=None):
280 284 """find merge destination based on branch heads"""
281 285 node = None
282 286
283 287 if sourceset is None:
284 288 sourceset = [repo[repo.dirstate.p1()].rev()]
285 289 branch = repo.dirstate.branch()
286 290 elif not sourceset:
287 291 msg, hint = msgdestmerge['emptysourceset'][action]
288 292 raise error.NoMergeDestAbort(msg, hint=hint)
289 293 else:
290 294 branch = None
291 295 for ctx in repo.set('roots(%ld::%ld)', sourceset, sourceset):
292 296 if branch is not None and ctx.branch() != branch:
293 297 msg, hint = msgdestmerge['multiplebranchessourceset'][action]
294 298 raise error.ManyMergeDestAbort(msg, hint=hint)
295 299 branch = ctx.branch()
296 300
297 301 bheads = repo.branchheads(branch)
298 302 onhead = repo.revs('%ld and %ln', sourceset, bheads)
299 303 if onheadcheck and not onhead:
300 304 # Case A: working copy if not on a head. (merge only)
301 305 #
302 306 # This is probably a user mistake We bailout pointing at 'hg update'
303 307 if len(repo.heads()) <= 1:
304 308 msg, hint = msgdestmerge['nootherheadsbehind'][action]
305 309 else:
306 310 msg, hint = msgdestmerge['notatheads'][action]
307 311 raise error.Abort(msg, hint=hint)
308 312 # remove heads descendants of source from the set
309 313 bheads = list(repo.revs('%ln - (%ld::)', bheads, sourceset))
310 314 # filters out bookmarked heads
311 315 nbhs = list(repo.revs('%ld - bookmark()', bheads))
312 316
313 317 if destspace is not None:
314 318 # restrict search space
315 319 # used in the 'hg pull --rebase' case, see issue 5214.
316 320 nbhs = list(repo.revs('%ld and %ld', destspace, nbhs))
317 321
318 322 if len(nbhs) > 1:
319 323 # Case B: There is more than 1 other anonymous heads
320 324 #
321 325 # This means that there will be more than 1 candidate. This is
322 326 # ambiguous. We abort asking the user to pick as explicit destination
323 327 # instead.
324 328 msg, hint = msgdestmerge['toomanyheads'][action]
325 329 msg %= (branch, len(bheads) + 1)
326 330 raise error.ManyMergeDestAbort(msg, hint=hint)
327 331 elif not nbhs:
328 332 # Case B: There is no other anonymous heads
329 333 #
330 334 # This means that there is no natural candidate to merge with.
331 335 # We abort, with various messages for various cases.
332 336 if bheads:
333 337 msg, hint = msgdestmerge['bookmarkedheads'][action]
334 338 elif len(repo.heads()) > 1:
335 339 msg, hint = msgdestmerge['nootherbranchheads'][action]
336 340 msg %= branch
337 341 elif not onhead:
338 342 # if 'onheadcheck == False' (rebase case),
339 343 # this was not caught in Case A.
340 344 msg, hint = msgdestmerge['nootherheadsbehind'][action]
341 345 else:
342 346 msg, hint = msgdestmerge['nootherheads'][action]
343 347 raise error.NoMergeDestAbort(msg, hint=hint)
344 348 else:
345 349 node = nbhs[0]
346 350 assert node is not None
347 351 return node
348 352
349 353 def destmerge(repo, action='merge', sourceset=None, onheadcheck=True,
350 354 destspace=None):
351 355 """return the default destination for a merge
352 356
353 357 (or raise exception about why it can't pick one)
354 358
355 359 :action: the action being performed, controls emitted error message
356 360 """
357 361 # destspace is here to work around issues with `hg pull --rebase` see
358 362 # issue5214 for details
359 363 if repo._activebookmark:
360 364 node = _destmergebook(repo, action=action, sourceset=sourceset,
361 365 destspace=destspace)
362 366 else:
363 367 node = _destmergebranch(repo, action=action, sourceset=sourceset,
364 368 onheadcheck=onheadcheck, destspace=destspace)
365 369 return repo[node].rev()
366 370
367 371 histeditdefaultrevset = 'reverse(only(.) and not public() and not ::merge())'
368 372
369 373 def desthistedit(ui, repo):
370 374 """Default base revision to edit for `hg histedit`."""
371 375 # Avoid cycle: scmutil -> revset -> destutil
372 376 from . import scmutil
373 377
374 378 default = ui.config('histedit', 'defaultrev', histeditdefaultrevset)
375 379 if default:
376 380 revs = scmutil.revrange(repo, [default])
377 381 if revs:
378 382 # The revset supplied by the user may not be in ascending order nor
379 383 # take the first revision. So do this manually.
380 384 revs.sort()
381 385 return revs.first()
382 386
383 387 return None
384 388
385 389 def _statusotherbook(ui, repo):
386 390 bmheads = repo.bookmarkheads(repo._activebookmark)
387 391 curhead = repo[repo._activebookmark].node()
388 392 if repo.revs('%n and parents()', curhead):
389 393 # we are on the active bookmark
390 394 bmheads = [b for b in bmheads if curhead != b]
391 395 if bmheads:
392 396 msg = _('%i other divergent bookmarks for "%s"\n')
393 397 ui.status(msg % (len(bmheads), repo._activebookmark))
394 398
395 399 def _statusotherbranchheads(ui, repo):
396 400 currentbranch = repo.dirstate.branch()
397 401 allheads = repo.branchheads(currentbranch, closed=True)
398 402 heads = repo.branchheads(currentbranch)
399 403 if repo.revs('%ln and parents()', allheads):
400 404 # we are on a head, even though it might be closed
401 405 #
402 406 # on closed otherheads
403 407 # ========= ==========
404 408 # o 0 all heads for current branch are closed
405 409 # N only descendant branch heads are closed
406 410 # x 0 there is only one non-closed branch head
407 411 # N there are some non-closed branch heads
408 412 # ========= ==========
409 413 otherheads = repo.revs('%ln - parents()', heads)
410 414 if repo['.'].closesbranch():
411 415 ui.warn(_('no open descendant heads on branch "%s", '
412 416 'updating to a closed head\n') %
413 417 (currentbranch))
414 418 if otherheads:
415 419 ui.warn(_('(committing will reopen the head, '
416 420 'use `hg heads .` to see %i other heads)\n') %
417 421 (len(otherheads)))
418 422 else:
419 423 ui.warn(_('(committing will reopen branch "%s")\n') %
420 424 (currentbranch))
421 425 elif otherheads:
422 426 ui.status(_('%i other heads for branch "%s"\n') %
423 427 (len(otherheads), currentbranch))
424 428
425 429 def statusotherdests(ui, repo):
426 430 """Print message about other head"""
427 431 # XXX we should probably include a hint:
428 432 # - about what to do
429 433 # - how to see such heads
430 434 if repo._activebookmark:
431 435 _statusotherbook(ui, repo)
432 436 else:
433 437 _statusotherbranchheads(ui, repo)
@@ -1,465 +1,534 b''
1 1 $ branchcache=.hg/cache/branch2
2 2
3 3 $ listbranchcaches() {
4 4 > for f in .hg/cache/branch2*;
5 5 > do echo === $f ===;
6 6 > cat $f;
7 7 > done;
8 8 > }
9 9 $ purgebranchcaches() {
10 10 > rm .hg/cache/branch2*
11 11 > }
12 12
13 13 $ hg init t
14 14 $ cd t
15 15
16 16 $ hg branches
17 17 $ echo foo > a
18 18 $ hg add a
19 19 $ hg ci -m "initial"
20 20 $ hg branch foo
21 21 marked working directory as branch foo
22 22 (branches are permanent and global, did you want a bookmark?)
23 23 $ hg branch
24 24 foo
25 25 $ hg ci -m "add branch name"
26 26 $ hg branch bar
27 27 marked working directory as branch bar
28 28 $ hg ci -m "change branch name"
29 29
30 30 Branch shadowing:
31 31
32 32 $ hg branch default
33 33 abort: a branch of the same name already exists
34 34 (use 'hg update' to switch to it)
35 35 [255]
36 36
37 37 $ hg branch -f default
38 38 marked working directory as branch default
39 39
40 40 $ hg ci -m "clear branch name"
41 41 created new head
42 42
43 43 There should be only one default branch head
44 44
45 45 $ hg heads .
46 46 changeset: 3:1c28f494dae6
47 47 tag: tip
48 48 user: test
49 49 date: Thu Jan 01 00:00:00 1970 +0000
50 50 summary: clear branch name
51 51
52 52 Merging and branches
53 53
54 54 $ hg co foo
55 55 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 56 $ hg branch
57 57 foo
58 58
59 59 set existing branch name fails unless force - setting existing parent branch works without force:
60 60
61 61 $ hg branch bar
62 62 abort: a branch of the same name already exists
63 63 (use 'hg update' to switch to it)
64 64 [255]
65 65
66 66 $ hg branch -f bar
67 67 marked working directory as branch bar
68 68
69 69 $ hg branch foo
70 70 marked working directory as branch foo
71 71
72 72 $ echo bleah > a
73 73 $ hg ci -m "modify a branch"
74 74
75 75 $ hg merge default
76 76 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 77 (branch merge, don't forget to commit)
78 78
79 79 $ hg branch
80 80 foo
81 81
82 82 set existing branch name where branch head is ancestor:
83 83
84 84 $ hg branch bar
85 85 abort: a branch of the same name already exists
86 86 (use 'hg update' to switch to it)
87 87 [255]
88 88
89 89 set (other) parent branch as branch name
90 90
91 91 $ hg branch default
92 92 marked working directory as branch default
93 93
94 94 set (first) parent branch as branch name
95 95
96 96 $ hg branch foo
97 97 marked working directory as branch foo
98 98
99 99 $ hg ci -m "merge"
100 100
101 101 $ hg log -G -T '{rev}:{node|short} {branch} {desc}\n'
102 102 @ 5:530046499edf foo merge
103 103 |\
104 104 | o 4:adf1a74a7f7b foo modify a branch
105 105 | |
106 106 o | 3:1c28f494dae6 default clear branch name
107 107 | |
108 108 o | 2:c21617b13b22 bar change branch name
109 109 |/
110 110 o 1:6c0e42da283a foo add branch name
111 111 |
112 112 o 0:db01e8ea3388 default initial
113 113
114 114 $ hg branches
115 115 foo 5:530046499edf
116 116 default 3:1c28f494dae6 (inactive)
117 117 bar 2:c21617b13b22 (inactive)
118 118
119 119 $ hg branches -q
120 120 foo
121 121 default
122 122 bar
123 123
124 124 Test for invalid branch cache:
125 125
126 126 $ hg rollback
127 127 repository tip rolled back to revision 4 (undo commit)
128 128 working directory now based on revisions 4 and 3
129 129
130 130 $ cp ${branchcache}-served .hg/bc-invalid
131 131
132 132 $ hg log -r foo
133 133 changeset: 4:adf1a74a7f7b
134 134 branch: foo
135 135 tag: tip
136 136 parent: 1:6c0e42da283a
137 137 user: test
138 138 date: Thu Jan 01 00:00:00 1970 +0000
139 139 summary: modify a branch
140 140
141 141 $ cp .hg/bc-invalid $branchcache
142 142
143 143 $ hg --debug log -r foo
144 144 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
145 145 branch: foo
146 146 tag: tip
147 147 phase: draft
148 148 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
149 149 parent: -1:0000000000000000000000000000000000000000
150 150 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
151 151 user: test
152 152 date: Thu Jan 01 00:00:00 1970 +0000
153 153 files: a
154 154 extra: branch=foo
155 155 description:
156 156 modify a branch
157 157
158 158
159 159 $ purgebranchcaches
160 160 $ echo corrupted > $branchcache
161 161
162 162 $ hg log -qr foo
163 163 4:adf1a74a7f7b
164 164
165 165 $ listbranchcaches
166 166 === .hg/cache/branch2 ===
167 167 corrupted
168 168 === .hg/cache/branch2-served ===
169 169 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
170 170 c21617b13b220988e7a2e26290fbe4325ffa7139 o bar
171 171 1c28f494dae69a2f8fc815059d257eccf3fcfe75 o default
172 172 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 o foo
173 173
174 174 Push should update the branch cache:
175 175
176 176 $ hg init ../target
177 177
178 178 Pushing just rev 0:
179 179
180 180 $ hg push -qr 0 ../target
181 181
182 182 $ (cd ../target/; listbranchcaches)
183 183 === .hg/cache/branch2-base ===
184 184 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
185 185 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 o default
186 186
187 187 Pushing everything:
188 188
189 189 $ hg push -qf ../target
190 190
191 191 $ (cd ../target/; listbranchcaches)
192 192 === .hg/cache/branch2-base ===
193 193 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
194 194 c21617b13b220988e7a2e26290fbe4325ffa7139 o bar
195 195 1c28f494dae69a2f8fc815059d257eccf3fcfe75 o default
196 196 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 o foo
197 197
198 198 Update with no arguments: tipmost revision of the current branch:
199 199
200 200 $ hg up -q -C 0
201 201 $ hg up -q
202 202 $ hg id
203 203 1c28f494dae6
204 204
205 205 $ hg up -q 1
206 206 $ hg up -q
207 207 $ hg id
208 208 adf1a74a7f7b (foo) tip
209 209
210 210 $ hg branch foobar
211 211 marked working directory as branch foobar
212 212
213 213 $ hg up
214 214 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 215
216 216 Fast-forward merge:
217 217
218 218 $ hg branch ff
219 219 marked working directory as branch ff
220 220
221 221 $ echo ff > ff
222 222 $ hg ci -Am'fast forward'
223 223 adding ff
224 224
225 225 $ hg up foo
226 226 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
227 227
228 228 $ hg merge ff
229 229 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
230 230 (branch merge, don't forget to commit)
231 231
232 232 $ hg branch
233 233 foo
234 234 $ hg commit -m'Merge ff into foo'
235 235 $ hg parents
236 236 changeset: 6:185ffbfefa30
237 237 branch: foo
238 238 tag: tip
239 239 parent: 4:adf1a74a7f7b
240 240 parent: 5:1a3c27dc5e11
241 241 user: test
242 242 date: Thu Jan 01 00:00:00 1970 +0000
243 243 summary: Merge ff into foo
244 244
245 245 $ hg manifest
246 246 a
247 247 ff
248 248
249 249
250 250 Test merging, add 3 default heads and one test head:
251 251
252 252 $ cd ..
253 253 $ hg init merges
254 254 $ cd merges
255 255 $ echo a > a
256 256 $ hg ci -Ama
257 257 adding a
258 258
259 259 $ echo b > b
260 260 $ hg ci -Amb
261 261 adding b
262 262
263 263 $ hg up 0
264 264 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
265 265 $ echo c > c
266 266 $ hg ci -Amc
267 267 adding c
268 268 created new head
269 269
270 270 $ hg up 0
271 271 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
272 272 $ echo d > d
273 273 $ hg ci -Amd
274 274 adding d
275 275 created new head
276 276
277 277 $ hg up 0
278 278 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
279 279 $ hg branch test
280 280 marked working directory as branch test
281 281 (branches are permanent and global, did you want a bookmark?)
282 282 $ echo e >> e
283 283 $ hg ci -Ame
284 284 adding e
285 285
286 286 $ hg log
287 287 changeset: 4:3a1e01ed1df4
288 288 branch: test
289 289 tag: tip
290 290 parent: 0:cb9a9f314b8b
291 291 user: test
292 292 date: Thu Jan 01 00:00:00 1970 +0000
293 293 summary: e
294 294
295 295 changeset: 3:980f7dc84c29
296 296 parent: 0:cb9a9f314b8b
297 297 user: test
298 298 date: Thu Jan 01 00:00:00 1970 +0000
299 299 summary: d
300 300
301 301 changeset: 2:d36c0562f908
302 302 parent: 0:cb9a9f314b8b
303 303 user: test
304 304 date: Thu Jan 01 00:00:00 1970 +0000
305 305 summary: c
306 306
307 307 changeset: 1:d2ae7f538514
308 308 user: test
309 309 date: Thu Jan 01 00:00:00 1970 +0000
310 310 summary: b
311 311
312 312 changeset: 0:cb9a9f314b8b
313 313 user: test
314 314 date: Thu Jan 01 00:00:00 1970 +0000
315 315 summary: a
316 316
317 317 Implicit merge with test branch as parent:
318 318
319 319 $ hg merge
320 320 abort: branch 'test' has one head - please merge with an explicit rev
321 321 (run 'hg heads' to see all heads)
322 322 [255]
323 323 $ hg up -C default
324 324 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
325 325
326 326 Implicit merge with default branch as parent:
327 327
328 328 $ hg merge
329 329 abort: branch 'default' has 3 heads - please merge with an explicit rev
330 330 (run 'hg heads .' to see heads)
331 331 [255]
332 332
333 333 3 branch heads, explicit merge required:
334 334
335 335 $ hg merge 2
336 336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 337 (branch merge, don't forget to commit)
338 338 $ hg ci -m merge
339 339
340 340 2 branch heads, implicit merge works:
341 341
342 342 $ hg merge
343 343 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
344 344 (branch merge, don't forget to commit)
345 345
346 346 $ cd ..
347 347
348 348 We expect that bare update on new branch, updates to parent
349 349
350 350 $ hg init bareupdateonnewbranch
351 351 $ cd bareupdateonnewbranch
352 352 $ hg update
353 353 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
354 354 $ touch a
355 355 $ hg commit -A -m "a"
356 356 adding a
357 357 $ touch b
358 358 $ hg commit -A -m "b"
359 359 adding b
360 360 $ touch c
361 361 $ hg commit -A -m "c"
362 362 adding c
363 363 $ hg update -r 1
364 364 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
365 365 $ hg log -G
366 366 o changeset: 2:991a3460af53
367 367 | tag: tip
368 368 | user: test
369 369 | date: Thu Jan 01 00:00:00 1970 +0000
370 370 | summary: c
371 371 |
372 372 @ changeset: 1:0e067c57feba
373 373 | user: test
374 374 | date: Thu Jan 01 00:00:00 1970 +0000
375 375 | summary: b
376 376 |
377 377 o changeset: 0:3903775176ed
378 378 user: test
379 379 date: Thu Jan 01 00:00:00 1970 +0000
380 380 summary: a
381 381
382 382 $ hg branch dev
383 383 marked working directory as branch dev
384 384 (branches are permanent and global, did you want a bookmark?)
385 385 $ hg update
386 386 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 387 $ hg summary
388 388 parent: 1:0e067c57feba
389 389 b
390 390 branch: dev
391 391 commit: (new branch)
392 392 update: (current)
393 393 phases: 3 draft
394 394
395 395 $ cd ..
396 396
397 397 We need special handling for repositories with no "default" branch because
398 398 "null" revision belongs to non-existent "default" branch.
399 399
400 400 $ hg init nodefault
401 401 $ cd nodefault
402 402 $ hg branch -q foo
403 403 $ touch 0
404 404 $ hg ci -Aqm0
405 405 $ touch 1
406 406 $ hg ci -Aqm1
407 407 $ hg update -qr0
408 408 $ hg branch -q bar
409 409 $ touch 2
410 410 $ hg ci -Aqm2
411 411 $ hg update -qr0
412 412 $ hg branch -q baz
413 413 $ touch 3
414 414 $ hg ci -Aqm3
415 415 $ hg ci --close-branch -m 'close baz'
416 416 $ hg update -q null
417 417 $ hg log -GT'{rev} {branch}\n'
418 418 _ 4 baz
419 419 |
420 420 o 3 baz
421 421 |
422 422 | o 2 bar
423 423 |/
424 424 | o 1 foo
425 425 |/
426 426 o 0 foo
427 427
428 428
429 429 a) updating from "null" should bring us to the tip-most branch head as
430 430 there is no "default" branch:
431 431
432 432 $ hg update -q null
433 433 $ hg id -bn
434 434 -1 default
435 435 $ hg update
436 436 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
437 437 $ hg id -bn
438 438 2 bar
439 439
440 440 b) but if we are at uncommitted "default" branch, we should stick to the
441 441 current revision:
442 442
443 443 $ hg update -q 0
444 444 $ hg branch default
445 445 marked working directory as branch default
446 446 $ hg id -bn
447 447 0 default
448 448 $ hg update
449 449 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450 $ hg id -bn
451 451 0 default
452 452
453 453 c) also, if we have uncommitted branch at "null", we should stick to it:
454 454
455 455 $ hg update -q null
456 456 $ hg branch new
457 457 marked working directory as branch new
458 458 $ hg id -bn
459 459 -1 new
460 460 $ hg update
461 461 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
462 462 $ hg id -bn
463 463 -1 new
464 464
465 465 $ cd ..
466
467 We expect that update --clean discard changes in working directory,
468 and updates to the head of parent branch.
469
470 $ hg init updatebareclean
471 $ cd updatebareclean
472 $ hg update --clean
473 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
474 $ touch a
475 $ hg commit -A -m "a"
476 adding a
477 $ touch b
478 $ hg commit -A -m "b"
479 adding b
480 $ touch c
481 $ hg commit -A -m "c"
482 adding c
483 $ hg log
484 changeset: 2:991a3460af53
485 tag: tip
486 user: test
487 date: Thu Jan 01 00:00:00 1970 +0000
488 summary: c
489
490 changeset: 1:0e067c57feba
491 user: test
492 date: Thu Jan 01 00:00:00 1970 +0000
493 summary: b
494
495 changeset: 0:3903775176ed
496 user: test
497 date: Thu Jan 01 00:00:00 1970 +0000
498 summary: a
499
500 $ hg update -r 1
501 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
502 $ hg branch new-branch
503 marked working directory as branch new-branch
504 (branches are permanent and global, did you want a bookmark?)
505 $ echo "aa" >> a
506 $ hg update --clean
507 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
508 $ hg status
509 $ hg branch
510 default
511 $ hg parent
512 changeset: 2:991a3460af53
513 tag: tip
514 user: test
515 date: Thu Jan 01 00:00:00 1970 +0000
516 summary: c
517
518 We expect that update --clean on non existing parent discards a new branch
519 and updates to the tipmost non-closed branch head
520
521 $ hg update null
522 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
523 $ hg branch newbranch
524 marked working directory as branch newbranch
525 (branches are permanent and global, did you want a bookmark?)
526 $ hg update -C
527 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
528 $ hg summary
529 parent: 2:991a3460af53 tip
530 c
531 branch: default
532 commit: (clean)
533 update: (current)
534 phases: 3 draft
General Comments 0
You need to be logged in to leave comments. Login now