Patchwork [18,of,19] commit: move commit preparation from localrepo.commit to workingctx

login
register
mail settings
Submitter David Schleimer
Date Feb. 10, 2013, 11:30 p.m.
Message ID <7a150f3cfd3ea54a11db.1360539008@dev010.prn1.facebook.com>
Download mbox | patch
Permalink /patch/958/
State Changes Requested
Headers show

Comments

David Schleimer - Feb. 10, 2013, 11:30 p.m.
# HG changeset patch
# User David Schleimer <dschleimer@fb.com>
# Date 1360534411 28800
# Node ID 7a150f3cfd3ea54a11dbe5754671d3e82420d40b
# Parent  06702855099328ba716cd3096706357b379f6b50
commit: move commit preparation from localrepo.commit to workingctx

This moves the logic for change filtering, subrepo munging, and
subrepo-related validation out of localrepo and into workingcontext.
The long-term goal is to make this logic more accessible to other
code.
Bryan O'Sullivan - Feb. 11, 2013, 9:04 p.m.
On Sun, Feb 10, 2013 at 3:30 PM, David Schleimer <dschleimer@fb.com> wrote:

> +        Includes validation, subrepo state munging, and change
> +        filtering.
>

"Includes" implies that the method does more than just these things, which
I don't think it does. Maybe use "Performs" instead?

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1213,6 +1213,60 @@ 
 
         return subs
 
+    def preparecommit(self, match, force):
+        """Prepare this workingcontext for commit.
+
+        Includes validation, subrepo state munging, and change
+        filtering.
+        """
+        merge = len(self.parents()) > 1
+
+        def fail(f, msg):
+            raise util.Abort('%s: %s' % (f, msg))
+
+        if not match:
+            match = matchmod.always(self._repo.root, '')
+
+        if not force:
+            vdirs = []
+            match.dir = vdirs.append
+            match.bad = fail
+
+        if (not force and merge and match and
+            (match.files() or match.anypats())):
+            raise util.Abort(_('cannot partially commit a merge '
+                               '(do not specify files or patterns)'))
+
+        self.status(match=match, clean=force)
+
+        if force:
+            # mq may commit unchanged files
+            self.modified().extend(self.clean())
+
+        subs = self.preparesubstate(match, force)
+
+        # make sure all explicit patterns are matched
+        if not force and match.files():
+            matched = set(self.files())
+
+            for f in match.files():
+                f = self._repo.dirstate.normalize(f)
+                if f == '.' or f in matched or f in self.substate:
+                    continue
+                if f in self.deleted(): # missing
+                    fail(f, _('file not found!'))
+                if f in vdirs: # visited directory
+                    d = f + '/'
+                    for mf in matched:
+                        if mf.startswith(d):
+                            break
+                    else:
+                        fail(f, _("no match under directory!"))
+                elif f not in self._repo.dirstate:
+                    fail(f, _("file not tracked!"))
+
+        return subs
+
     def commitablesubstate(self, match, force):
         subs = []
         commitsubs = set()
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1130,54 +1130,12 @@ 
         supplied, it is called to get a commit message.
         """
 
-        def fail(f, msg):
-            raise util.Abort('%s: %s' % (f, msg))
-
-        if not match:
-            match = matchmod.always(self.root, '')
-
-        if not force:
-            vdirs = []
-            match.dir = vdirs.append
-            match.bad = fail
-
         wlock = self.wlock()
         try:
             wctx = self[None]
             merge = len(wctx.parents()) > 1
 
-            if (not force and merge and match and
-                (match.files() or match.anypats())):
-                raise util.Abort(_('cannot partially commit a merge '
-                                   '(do not specify files or patterns)'))
-
-            wctx.status(match=match, clean=force)
-            if force:
-                # mq may commit unchanged files
-                wctx.modified().extend(wctx.clean())
-
-            subs = wctx.preparesubstate(match, force)
-
-            # make sure all explicit patterns are matched
-            if not force and match.files():
-                matched = set(wctx.files())
-
-                for f in match.files():
-                    f = self.dirstate.normalize(f)
-                    if f == '.' or f in matched or f in wctx.substate:
-                        continue
-                    if f in wctx.deleted(): # missing
-                        fail(f, _('file not found!'))
-                    if f in vdirs: # visited directory
-                        d = f + '/'
-                        for mf in matched:
-                            if mf.startswith(d):
-                                break
-                        else:
-                            fail(f, _("no match under directory!"))
-                    elif f not in self.dirstate:
-                        fail(f, _("file not tracked!"))
-
+            subs = wctx.preparecommit(match, force)
             cctx = wctx
 
             if (not force and not extra.get("close") and not merge