[PATCH] Enable commit to disallow recursive submodule commits

Michael Ekstrand michael at elehack.net
Fri Apr 23 08:38:44 CDT 2010


# HG changeset patch
# User Michael Ekstrand <michael at elehack.net>
# Date 1272029833 18000
Enable commit to disallow recursive submodule commits

This patch adds support to commit for a 'commit.recursive' option, defaulting
to true, which controls whether or not commit recursively commits submodules.
If false and a submodule has uncommitted changes, commit fails unless the
'--force' option is passed.  If --force is passed, then .hgsubstate is updated
with the submodule's checked-out revision, if necessary, but not committed.

* Adds methods to subrepos to query working copy dirty state and current
  revision.
* Adds support to localrepo.commit for honoring the commit.recursive option.
* Adds tests to test-subrepo for the new changes.

diff -r db4d7077f48d -r 7418d84a9926 mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -861,9 +861,19 @@
             if subs or removedsubs:
                 state = wctx.substate.copy()
                 for s in subs:
-                    self.ui.status(_('committing subrepository %s\n') % s)
-                    sr = wctx.sub(s).commit(cctx._text, user, date)
-                    state[s] = (state[s][0], sr)
+                    srepo = wctx.sub(s)
+                    if self.ui.configbool('commit', 'recursive', default=True):
+                        self.ui.status(_('committing subrepository %s\n') % s)
+                        sr = srepo.commit(cctx._text, user, date)
+                        state[s] = (state[s][0], sr)
+                    else:
+                        if srepo.wcdirty() and not force:
+                            fail(s, _('subrepository working copy dirty'
+                                      ' (--force to commit anyway)'))
+                        else:
+                            self.ui.status(_('recording changes to'
+                                             ' subrepository %s\n') % s)
+                            state[s] = (state[s][0], srepo.curstate())
                 subrepo.writestate(self, state)
 
             # Save commit message in case this transaction gets rolled back
diff -r db4d7077f48d -r 7418d84a9926 mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -209,6 +209,14 @@
             return True
         return w.dirty() # working directory changed
 
+    def wcdirty(self):
+        'Query whether the working copy is dirty'
+        w = self._repo[None]
+        return w.dirty()
+
+    def curstate(self):
+        return self._repo['.'].hex()
+
     def commit(self, text, user, date):
         self._repo.ui.debug("committing subrepo %s\n" % self._path)
         n = self._repo.commit(text, user, date)
@@ -327,6 +335,12 @@
             return False
         return True
 
+    def wcdirty(self):
+        return self._wcchanged()[0]
+
+    def curstate(self):
+        return self._wcrev()
+
     def commit(self, text, user, date):
         # user and date are out of our hands since svn is centralized
         changed, extchanged = self._wcchanged()
diff -r db4d7077f48d -r 7418d84a9926 tests/test-subrepo
--- a/tests/test-subrepo
+++ b/tests/test-subrepo
@@ -36,6 +36,12 @@
 hg ci -m4
 hg tip -R s
 
+echo % leave sub dirty w/o recursive commits
+echo c2 > s/a
+hg --config commit.recursive=no ci -m4b
+hg tip -R s
+echo c > s/a
+
 echo % check caching
 hg co 0
 hg debugsub
@@ -106,6 +112,14 @@
 hg up | sed 's|from .*/sub|from .../sub|g'
 cat t/t
 
+echo % change submodule w/ non-recursive commit
+echo q >s/q
+hg -R s ci -Amsub1
+hg -R s tip
+hg --config commit.recursive=no ci -Amsub1
+hg tip
+hg debugsub
+
 echo % bogus subrepo path aborts
 echo 'bogus=[boguspath' >> .hgsub
 hg ci -m 'bogus subrepo path'
diff -r db4d7077f48d -r 7418d84a9926 tests/test-subrepo.out
--- a/tests/test-subrepo.out
+++ b/tests/test-subrepo.out
@@ -16,6 +16,14 @@
 date:        Thu Jan 01 00:00:00 1970 +0000
 summary:     4
 
+% leave sub dirty w/o recursive commits
+abort: s: subrepository working copy dirty (--force to commit anyway)
+changeset:   3:1c833a7a9e3a
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     4
+
 % check caching
 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
 % restore
@@ -205,6 +213,27 @@
 added 1 changesets with 1 changes to 1 files
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 blah
+% change submodule w/ non-recursive commit
+adding q
+changeset:   5:0885d7bce307
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     sub1
+
+recording changes to subrepository s
+changeset:   14:ea4e01af3701
+tag:         tip
+user:        test
+date:        Thu Jan 01 00:00:00 1970 +0000
+summary:     sub1
+
+path s
+ source   s
+ revision 0885d7bce307ca6d0358640b478eea284e90b772
+path t
+ source   t
+ revision 52c0adc0515a4d11c7e15eac7708c7a58df4666e
 % bogus subrepo path aborts
 abort: missing ] in subrepo source
 % issue 1986


More information about the Mercurial-devel mailing list