subrepo: add status support for ignored and clean files in git subrepos
authorMathias De Maré <mathias.demare@gmail.com>
Mon, 09 Mar 2015 22:14:09 +0100
changeset 24256 e964edc3274e
parent 24255 4bfe9f2d9761
child 24257 31e9f66863f3
subrepo: add status support for ignored and clean files in git subrepos
mercurial/subrepo.py
tests/test-subrepo-git.t
--- a/mercurial/subrepo.py	Wed Jan 14 15:16:08 2015 -0500
+++ b/mercurial/subrepo.py	Mon Mar 09 22:14:09 2015 +0100
@@ -1662,13 +1662,42 @@
 
         deleted, unknown, ignored, clean = [], [], [], []
 
+        command = ['status', '--porcelain', '-z']
         if opts.get('unknown'):
-            command = ['ls-files', '--others', '--exclude-standard']
-            out = self._gitcommand(command)
-            for line in out.split('\n'):
-                if len(line) == 0:
-                    continue
-                unknown.append(line)
+            command += ['--untracked-files=all']
+        if opts.get('ignored'):
+            command += ['--ignored']
+        out = self._gitcommand(command)
+
+        changedfiles = set()
+        changedfiles.update(modified)
+        changedfiles.update(added)
+        changedfiles.update(removed)
+        for line in out.split('\0'):
+            if not line:
+                continue
+            st = line[0:2]
+            #moves and copies show 2 files on one line
+            if line.find('\0') >= 0:
+                filename1, filename2 = line[3:].split('\0')
+            else:
+                filename1 = line[3:]
+                filename2 = None
+
+            changedfiles.add(filename1)
+            if filename2:
+                changedfiles.add(filename2)
+
+            if st == '??':
+                unknown.append(filename1)
+            elif st == '!!':
+                ignored.append(filename1)
+
+        if opts.get('clean'):
+            out = self._gitcommand(['ls-files'])
+            for f in out.split('\n'):
+                if not f in changedfiles:
+                    clean.append(f)
 
         return scmutil.status(modified, added, removed, deleted,
                               unknown, ignored, clean)
--- a/tests/test-subrepo-git.t	Wed Jan 14 15:16:08 2015 -0500
+++ b/tests/test-subrepo-git.t	Mon Mar 09 22:14:09 2015 +0100
@@ -175,6 +175,8 @@
   pulling subrepo s from $TESTTMP/gitroot
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
+  $ hg st --subrepos s
+  A s/f
   $ cat s/f
   f
   $ cat s/g
@@ -944,6 +946,16 @@
   ? s/c.c
   ? s/cpp.cpp
   ? s/foobar.orig
+  $ hg st --subrepos s --all
+  A s/.gitignore
+  ? s/barfoo
+  ? s/c.c
+  ? s/cpp.cpp
+  ? s/foobar.orig
+  I s/snake.python
+  C s/f
+  C s/foobar
+  C s/g
   $ hg add --subrepos "glob:**.python"
   $ hg st --subrepos s
   A s/.gitignore
@@ -978,13 +990,41 @@
   $ hg add s/.gitignore
   s/.gitignore already tracked!
   [1]
+  $ hg add s/g
+  s/g already tracked!
+  [1]
 
 removed files can be re-added
+removing files using 'rm' or 'git rm' has the same effect,
+since we ignore the staging area
   $ hg ci --subrepos -m 'snake'
   committing subrepository s
   $ cd s
+  $ rm snake.python
+(remove leftover .hg so Mercurial doesn't look for a root here)
+  $ rm -r .hg
+  $ hg status --subrepos --all .
+  R snake.python
+  ? barfoo
+  ? c.c
+  ? cpp.cpp
+  ? foobar.orig
+  C .gitignore
+  C f
+  C foobar
+  C g
   $ git rm snake.python
   rm 'snake.python'
+  $ hg status --subrepos --all .
+  R snake.python
+  ? barfoo
+  ? c.c
+  ? cpp.cpp
+  ? foobar.orig
+  C .gitignore
+  C f
+  C foobar
+  C g
   $ touch snake.python
   $ cd ..
   $ hg add s/snake.python