# HG changeset patch # User David Soria Parra # Date 2012-05-13 09:55:42 # Node ID 4a02cf4fbb2e33df136b69095758af0f4d05cddf # Parent f8dee1a8f844fa4979b6976f9ab4447cecbd753d merge: respect bookmarks during merge Bookmarks will behave more like named branches when merge tries to pick a revision to merge. Bookmarks now to respect the current bookmarks. Bookmarks will not accidentally merged with unnamed heads or other bookmarks. However merge can pick heads with diverging bookmarks and pick those automatically. We end up with two cases for picking a revision to merge: (1) In case of an current bookmark, merge can pick a branch head that has a diverged bookmark (2) In case of no current bookmark, merge can pick a branch head that does not have a bookmark. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4168,17 +4168,43 @@ def merge(ui, repo, node=None, **opts): if not node: node = opts.get('rev') - if not node: + if node: + node = scmutil.revsingle(repo, node).node() + + if not node and repo._bookmarkcurrent: + bmheads = repo.bookmarkheads(repo._bookmarkcurrent) + curhead = repo[repo._bookmarkcurrent] + if len(bmheads) == 2: + if curhead == bmheads[0]: + node = bmheads[1] + else: + node = bmheads[0] + elif len(bmheads) > 2: + raise util.Abort(_("multiple matching bookmarks to merge - " + "please merge with an explicit rev or bookmark"), + hint=_("run 'hg heads' to see all heads")) + elif len(bmheads) <= 1: + raise util.Abort(_("no matching bookmark to merge - " + "please merge with an explicit rev or bookmark"), + hint=_("run 'hg heads' to see all heads")) + + if not node and not repo._bookmarkcurrent: branch = repo[None].branch() bheads = repo.branchheads(branch) - if len(bheads) > 2: + nbhs = [bh for bh in bheads if not repo[bh].bookmarks()] + + if len(nbhs) > 2: raise util.Abort(_("branch '%s' has %d heads - " "please merge with an explicit rev") % (branch, len(bheads)), hint=_("run 'hg heads .' to see heads")) parent = repo.dirstate.p1() - if len(bheads) == 1: + if len(nbhs) == 1: + if len(bheads) > 1: + raise util.Abort(_("heads are bookmarked - " + "please merge with an explicit rev"), + hint=_("run 'hg heads' to see all heads")) if len(repo.heads()) > 1: raise util.Abort(_("branch '%s' has one head - " "please merge with an explicit rev") @@ -4193,9 +4219,10 @@ def merge(ui, repo, node=None, **opts): raise util.Abort(_('working directory not at a head revision'), hint=_("use 'hg update' or merge with an " "explicit revision")) - node = parent == bheads[0] and bheads[-1] or bheads[0] - else: - node = scmutil.revsingle(repo, node).node() + if parent == nbhs[0]: + node = nbhs[-1] + else: + node = nbhs[0] if opts.get('preview'): # find nodes that are ancestors of p2 but not of p1 diff --git a/tests/test-bookmarks-merge.t b/tests/test-bookmarks-merge.t --- a/tests/test-bookmarks-merge.t +++ b/tests/test-bookmarks-merge.t @@ -29,3 +29,65 @@ $ hg bookmarks b 1:d2ae7f538514 * c 3:b8f96cf4688b + + $ hg up -C 3 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo d > d + $ hg add d + $ hg commit -m'd' + + $ hg up -C 3 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo e > e + $ hg add e + $ hg commit -m'e' + created new head + $ hg up -C 5 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg bookmark e + $ hg bookmarks + b 1:d2ae7f538514 + c 3:b8f96cf4688b + * e 5:26bee9c5bcf3 + +# the picked side is bookmarked + + $ hg up -C 4 + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg merge + abort: heads are bookmarked - please merge with an explicit rev + (run 'hg heads' to see all heads) + [255] + +# our revision is bookmarked + + $ hg up -C e + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg merge + abort: no matching bookmark to merge - please merge with an explicit rev or bookmark + (run 'hg heads' to see all heads) + [255] + +# merge bookmark heads + + $ hg up -C 4 + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo f > f + $ hg commit -Am "f" + adding f + $ hg up -C e + 1 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ hg bookmarks -r 4 "e@diverged" + $ hg bookmarks + b 1:d2ae7f538514 + c 3:b8f96cf4688b + * e 5:26bee9c5bcf3 + e@diverged 4:a0546fcfe0fb + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg commit -m'merge' + $ hg bookmarks + b 1:d2ae7f538514 + c 3:b8f96cf4688b + * e 7:ca784329f0ba diff --git a/tests/test-convert-hg-source.t b/tests/test-convert-hg-source.t --- a/tests/test-convert-hg-source.t +++ b/tests/test-convert-hg-source.t @@ -19,7 +19,7 @@ $ hg ci -m 'make bar and baz copies of foo' -d '2 0' created new head $ hg bookmark premerge1 - $ hg merge + $ hg merge -r 1 merging baz and foo to baz 1 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)