diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -696,6 +696,34 @@ def update(repo, node, branchmerge, forc node = repo.lookup("tip") # update to tip else: raise util.Abort(_("branch %s not found") % wc.branch()) + + if p1.obsolete() and not p1.children(): + # allow updating to successors + successors = obsolete.successorssets(repo, p1.node()) + + # behavior of certain cases is as follows, + # + # divergent changesets: update to highest rev, similar to what + # is currently done when there are more than one head + # (i.e. 'tip') + # + # replaced changesets: same as divergent except we know there + # is no conflict + # + # pruned changeset: no update is done; though, we could + # consider updating to the first non-obsolete parent, + # similar to what is current done for 'hg prune' + + if successors: + # flatten the list here handles both divergent (len > 1) + # and the usual case (len = 1) + successors = [n for sub in successors for n in sub] + + # get the max revision for the given successors set, + # i.e. the 'tip' of a set + node = repo.revs("max(%ln)", successors)[0] + pa = p1 + overwrite = force and not branchmerge p2 = repo[node] diff --git a/tests/test-update-branches.t b/tests/test-update-branches.t --- a/tests/test-update-branches.t +++ b/tests/test-update-branches.t @@ -229,6 +229,14 @@ the bookmark (issue4015) $ hg bookmarks * bm 5:ff252e8273df +Test that 4 is detected as the no-argument destination from 3 + $ hg up --quiet 0 # we should be able to update to 3 directly + $ hg up --quiet --hidden 3 # but not implemented yet. + $ hg up + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg id + d047485b3896+ (b1) + Test that 5 is detected as a valid destination from 1 $ hg up --quiet 0 # we should be able to update to 3 directly $ hg up --quiet --hidden 3 # but not implemented yet. @@ -242,3 +250,14 @@ Test that 5 is not detected as a valid d abort: uncommitted changes (commit or update --clean to discard changes) [255] + +Test that we don't crash when updating from a pruned changeset (i.e. has no +successors). Behavior should probably be that we update to the first +non-obsolete parent but that will be decided later. + $ hg id --debug -r 2 + bd10386d478cd5a9faf2e604114c8e6da62d3889 + $ hg up --quiet 0 + $ hg up --quiet 2 + $ hg debugobsolete bd10386d478cd5a9faf2e604114c8e6da62d3889 + $ hg up + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved