changeset 32956:4f0a7f604449

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.
author Sean Farley <sean@farley.io>
date Sat, 10 Jun 2017 23:42:38 -0700
parents 70661eeb8ddb
children 067173e3c8a6
files mercurial/bookmarks.py mercurial/commands.py
diffstat 2 files changed, 58 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- 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)