Patchwork [17,of,19] commit: move commit subrepo preparation fully into workingctx

login
register
mail settings
Submitter David Schleimer
Date Feb. 10, 2013, 11:30 p.m.
Message ID <06702855099328ba716c.1360539007@dev010.prn1.facebook.com>
Download mbox | patch
Permalink /patch/957/
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 1360518119 28800
# Node ID 06702855099328ba716cd3096706357b379f6b50
# Parent  486ffe802a0386d1aafa666d67363e937756e1e7
commit: move commit subrepo preparation fully into workingctx

This moves the last of ht elogic for munging changes related to
subrepos during the commit process out of localrepo.commit and into
workingcontext.  This should hopefully make it easier for other code
to access.  In particular, it should make it possible for other code
to subclass workingcontext and perform commits using this logic.

the long-term plan is to have memctx soubclass workingctx to take
advantage of this.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -828,6 +828,8 @@ 
             self._ms = None
             self._unresolved = None
 
+        self._commitsubs = []
+
         self._extra = {}
         self.setextra(extra)
 
@@ -1170,6 +1172,47 @@ 
             finally:
                 wlock.release()
 
+    def preparesubstate(self, match, force):
+        """Prepare the substate in this workingcontext for commit.
+
+        Specifically, this builds the substate info needed to commit
+        subrepos, and makes sure that the match object matches the
+        subrepo state files if subrepos are in use.
+
+        It also attaches the information needed to later commit
+        subrepos via commitsubstate to this workingctx.
+
+        Returns a list of subrepos included in the commit
+        """
+        # check subrepos
+        # only manage subrepos and .hgsubstate if .hgsub is present
+        subs = []
+        if '.hgsub' in self:
+            # we'll decide whether to track this ourselves, thanks
+            if '.hgsubstate' in self.modified():
+                self.modified().remove('.hgsubstate')
+            if '.hgsubstate' in self.removed():
+                self.removed().remove('.hgsubstate')
+
+            commitable = self.commitablesubstate(match, force)
+            subs, self._commitsubs, self.substate = commitable
+            if subs:
+                rawchanges = self._rawstatus()
+                if (not match('.hgsub') and
+                    # 0 = modified, 1 = added
+                    '.hgsub' in (rawchanges[0] + rawchanges[1])):
+                    raise util.Abort(
+                        _("can't commit subrepos without .hgsub"))
+                self.modified().insert(0, '.hgsubstate')
+
+        elif '.hgsub' in self.removed():
+            # clean up .hgsubstate when .hgsub is removed
+            if ('.hgsubstate' in self and
+                '.hgsubstate' not in self.files()):
+                self.removed().insert(0, '.hgsubstate')
+
+        return subs
+
     def commitablesubstate(self, match, force):
         subs = []
         commitsubs = set()
@@ -1207,14 +1250,14 @@ 
 
         return subs, commitsubs, newstate
 
-    def commitsubstate(self, commitsubs, newstate):
-        for s in sorted(commitsubs):
+    def commitsubstate(self):
+        for s in sorted(self._commitsubs):
             sub = self.sub(s)
             self._repo.ui.status(_('committing subrepository %s\n') %
                                  subrepo.subrelpath(sub))
             sr = sub.commit(self.description(), self._user, self._date)
-            newstate[s] = (newstate[s][0], sr)
-        subrepo.writestate(self._repo, newstate)
+            self.substate[s] = (self.substate[s][0], sr)
+        subrepo.writestate(self._repo, self.substate)
 
 
     def markcommitted(self, node):
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1156,32 +1156,7 @@ 
                 # mq may commit unchanged files
                 wctx.modified().extend(wctx.clean())
 
-            subs = []
-            # check subrepos
-            # only manage subrepos and .hgsubstate if .hgsub is present
-            if '.hgsub' in wctx:
-                # we'll decide whether to track this ourselves, thanks
-                if '.hgsubstate' in wctx.modified():
-                    wctx.modified().remove('.hgsubstate')
-                if '.hgsubstate' in wctx.removed():
-                    wctx.removed().remove('.hgsubstate')
-
-                subs, commitsubs, newstate = wctx.commitablesubstate(match,
-                                                                     force)
-                if subs:
-                    rawchanges = wctx._rawstatus()
-                    if (not match('.hgsub') and
-                        # 0 = modified, 1 = added
-                        '.hgsub' in (rawchanges[0] + rawchanges[1])):
-                        raise util.Abort(
-                            _("can't commit subrepos without .hgsub"))
-                    wctx.modified().insert(0, '.hgsubstate')
-
-            elif '.hgsub' in wctx.removed():
-                # clean up .hgsubstate when .hgsub is removed
-                if ('.hgsubstate' in wctx and
-                    '.hgsubstate' not in wctx.files()):
-                    wctx.removed().insert(0, '.hgsubstate')
+            subs = wctx.preparesubstate(match, force)
 
             # make sure all explicit patterns are matched
             if not force and match.files():
@@ -1228,7 +1203,7 @@ 
 
             # commit subs and write new state
             if subs:
-                cctx.commitsubstate(commitsubs, newstate)
+                cctx.commitsubstate()
 
             # Save commit message in case this transaction gets rolled back
             # (e.g. by a pretxncommit hook).  Leave the content alone on