subrepo: make update -C clean the working directory for git subrepos
authorErik Zielke <ez@aragost.com>
Mon, 31 Jan 2011 13:40:05 +0100
changeset 13324 e5617047c926
parent 13323 d8d478f9ee0f
child 13325 7ebdfa37842e
subrepo: make update -C clean the working directory for git subrepos This makes 'hg update --clean' behave the same way for all three kinds of subrepositories [hg, svn, git]. Before git subrepos did not take the clean parameter into account, but just updated to the given revision and merged uncommitted changes into that.
mercurial/subrepo.py
tests/test-subrepo-git.t
--- a/mercurial/subrepo.py	Mon Jan 31 13:38:00 2011 +0100
+++ b/mercurial/subrepo.py	Mon Jan 31 13:40:05 2011 +0100
@@ -761,16 +761,32 @@
                 self._gitcommand(['reset', '--hard', 'HEAD'])
                 return
         elif self._gitstate() == revision:
+            if overwrite:
+                # first reset the index to unmark new files for commit, because 
+                # reset --hard will otherwise throw away files added for commit,
+                # not just unmark them.
+                self._gitcommand(['reset', 'HEAD'])
+                self._gitcommand(['reset', '--hard', 'HEAD'])
             return
         branch2rev, rev2branch = self._gitbranchmap()
 
+        def checkout(args):
+            cmd = ['checkout']
+            if overwrite:
+                # first reset the index to unmark new files for commit, because
+                # the -f option will otherwise throw away files added for
+                # commit, not just unmark them.
+                self._gitcommand(['reset', 'HEAD'])
+                cmd.append('-f')
+            self._gitcommand(cmd + args)
+
         def rawcheckout():
             # no branch to checkout, check it out with no branch
             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
                           self._relpath)
             self._ui.warn(_('check out a git branch if you intend '
                             'to make changes\n'))
-            self._gitcommand(['checkout', '-q', revision])
+            checkout(['-q', revision])
 
         if revision not in rev2branch:
             rawcheckout()
@@ -780,12 +796,12 @@
         for b in branches:
             if b == 'refs/heads/master':
                 # master trumps all other branches
-                self._gitcommand(['checkout', 'refs/heads/master'])
+                checkout(['refs/heads/master'])
                 return
             if not firstlocalbranch and not b.startswith('refs/remotes/'):
                 firstlocalbranch = b
         if firstlocalbranch:
-            self._gitcommand(['checkout', firstlocalbranch])
+            checkout([firstlocalbranch])
             return
 
         tracking = self._gittracking(branch2rev.keys())
@@ -800,7 +816,7 @@
         if remote not in tracking:
             # create a new local tracking branch
             local = remote.split('/', 2)[2]
-            self._gitcommand(['checkout', '-b', local, remote])
+            checkout(['-b', local, remote])
         elif self._gitisancestor(branch2rev[tracking[remote]], remote):
             # When updating to a tracked remote branch,
             # if the local tracking branch is downstream of it,
@@ -809,7 +825,7 @@
             # Since we are only looking at branching at update, we need to
             # detect this situation and perform this action lazily.
             if tracking[remote] != self._gitcurrentbranch():
-                self._gitcommand(['checkout', tracking[remote]])
+                checkout([tracking[remote]])
             self._gitcommand(['merge', '--ff', remote])
         else:
             # a real merge would be required, just checkout the revision
--- a/tests/test-subrepo-git.t	Mon Jan 31 13:38:00 2011 +0100
+++ b/tests/test-subrepo-git.t	Mon Jan 31 13:40:05 2011 +0100
@@ -304,3 +304,21 @@
   $ ls ../narchive/inner/s | grep -v pax_global_header
   f
   g
+
+Check hg update --clean
+  $ cd $TESTTMP/t
+  $ echo  > s/g
+  $ cd s
+  $ echo c1 > f1
+  $ echo c1 > f2
+  $ git add f1
+  $ git status --short
+  A  f1
+   M g
+  ?? f2
+  $ cd ..
+  $ hg update -C > /dev/null 2>/dev/null
+  $ cd s
+  $ git status --short
+  ?? f1
+  ?? f2