commands: move checkconflict to bookmarks module
Again, commands.bookmark is getting too large. checkconflict already has
a lot of state and putting it in the bmstore makes more sense than
having it as a closure. This also allows extensions a place to override
this behavior.
While we're here, add a documentation string because, well, we should be
documenting more of our methods.
--- a/mercurial/bookmarks.py Sat Jun 10 23:32:58 2017 -0700
+++ b/mercurial/bookmarks.py Sat Jun 10 23:42:38 2017 -0700
@@ -13,6 +13,7 @@
from .node import (
bin,
hex,
+ short,
)
from . import (
encoding,
@@ -156,6 +157,61 @@
raise error.Abort(_("no active bookmark"))
return bname
+ def checkconflict(self, mark, force=False, target=None):
+ """check repo for a potential clash of mark with an existing bookmark,
+ branch, or hash
+
+ If target is supplied, then check that we are moving the bookmark
+ forward.
+
+ If force is supplied, then forcibly move the bookmark to a new commit
+ regardless if it is a move forward.
+ """
+ cur = self._repo.changectx('.').node()
+ if mark in self and not force:
+ if target:
+ if self[mark] == target and target == cur:
+ # re-activating a bookmark
+ return
+ rev = self._repo[target].rev()
+ anc = self._repo.changelog.ancestors([rev])
+ bmctx = self._repo[self[mark]]
+ divs = [self._repo[b].node() for b in self
+ if b.split('@', 1)[0] == mark.split('@', 1)[0]]
+
+ # allow resolving a single divergent bookmark even if moving
+ # the bookmark across branches when a revision is specified
+ # that contains a divergent bookmark
+ if bmctx.rev() not in anc and target in divs:
+ deletedivergent(self._repo, [target], mark)
+ return
+
+ deletefrom = [b for b in divs
+ if self._repo[b].rev() in anc or b == target]
+ deletedivergent(self._repo, deletefrom, mark)
+ if validdest(self._repo, bmctx, self._repo[target]):
+ self._repo.ui.status(
+ _("moving bookmark '%s' forward from %s\n") %
+ (mark, short(bmctx.node())))
+ return
+ raise error.Abort(_("bookmark '%s' already exists "
+ "(use -f to force)") % mark)
+ if ((mark in self._repo.branchmap() or
+ mark == self._repo.dirstate.branch()) and not force):
+ raise error.Abort(
+ _("a bookmark cannot have the name of an existing branch"))
+ if len(mark) > 3 and not force:
+ try:
+ shadowhash = (mark in self._repo)
+ except error.LookupError: # ambiguous identifier
+ shadowhash = False
+ if shadowhash:
+ self._repo.ui.warn(
+ _("bookmark %s matches a changeset hash\n"
+ "(did you leave a -r out of an 'hg bookmark' "
+ "command?)\n")
+ % mark)
+
def _readactive(repo, marks):
"""
Get the active bookmark. We can have an active bookmark that updates
--- a/mercurial/commands.py Sat Jun 10 23:32:58 2017 -0700
+++ b/mercurial/commands.py Sat Jun 10 23:42:38 2017 -0700
@@ -957,48 +957,6 @@
rename = opts.get('rename')
inactive = opts.get('inactive')
- def checkconflict(repo, mark, cur, force=False, target=None):
- if mark in marks and not force:
- if target:
- if marks[mark] == target and target == cur:
- # re-activating a bookmark
- return
- anc = repo.changelog.ancestors([repo[target].rev()])
- bmctx = repo[marks[mark]]
- divs = [repo[b].node() for b in marks
- if b.split('@', 1)[0] == mark.split('@', 1)[0]]
-
- # allow resolving a single divergent bookmark even if moving
- # the bookmark across branches when a revision is specified
- # that contains a divergent bookmark
- if bmctx.rev() not in anc and target in divs:
- bookmarks.deletedivergent(repo, [target], mark)
- return
-
- deletefrom = [b for b in divs
- if repo[b].rev() in anc or b == target]
- bookmarks.deletedivergent(repo, deletefrom, mark)
- if bookmarks.validdest(repo, bmctx, repo[target]):
- ui.status(_("moving bookmark '%s' forward from %s\n") %
- (mark, short(bmctx.node())))
- return
- raise error.Abort(_("bookmark '%s' already exists "
- "(use -f to force)") % mark)
- if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
- and not force):
- raise error.Abort(
- _("a bookmark cannot have the name of an existing branch"))
- if len(mark) > 3 and not force:
- try:
- shadowhash = (mark in repo)
- except error.LookupError: # ambiguous identifier
- shadowhash = False
- if shadowhash:
- repo.ui.warn(
- _("bookmark %s matches a changeset hash\n"
- "(did you leave a -r out of an 'hg bookmark' command?)\n")
- % mark)
-
if delete and rename:
raise error.Abort(_("--delete and --rename are incompatible"))
if delete and rev:
@@ -1035,7 +993,7 @@
if rename not in marks:
raise error.Abort(_("bookmark '%s' does not exist")
% rename)
- checkconflict(repo, mark, cur, force)
+ marks.checkconflict(mark, force)
marks[mark] = marks[rename]
if repo._activebookmark == rename and not inactive:
bookmarks.activate(repo, mark)
@@ -1053,7 +1011,7 @@
tgt = cur
if rev:
tgt = scmutil.revsingle(repo, rev).node()
- checkconflict(repo, mark, cur, force, tgt)
+ marks.checkconflict(mark, force, tgt)
marks[mark] = tgt
if not inactive and cur == marks[newact] and not rev:
bookmarks.activate(repo, newact)