Subject: bug#21120: [Bug-vc-dwim] bug#21120: vc-chlog fails if git submodules are dirty

From: Assaf Gordon <[email-masked]>
Date: Wed, 29 Jul 2015 23:44:02 +0000

Hello,

On Mon, Jul 27, 2015 at 10:22:08PM -0700, Jim Meyering wrote:
>On Wed, Jul 22, 2015 at 4:54 PM, Assaf Gordon <[email-masked]> wrote:
>> it seems that if a project using git has a submodule that is dirty, vc-chlog
>> will fail to print the information about all the files.
<...>

>> Another possible thing is to make 'vc-dwim' abort if there are dirty
>> submodules, on the assumption that 'vc-dwim' is meant to prevent problematic
>> commits, and a dirty submodule is a hint of a potential problem.

>Issuing a warning does have a little more appeal to me, but I would be happy
>with a complete patch implementing either behavior (i.e., updating NEWS
>and adding a test).

For starters, attached is the simpler approach of silently ignoring 
dirty git submodules with `vc-dwim --diff`.

Comments welcomed,
  -assaf
>From a4e3c56b2a8e546e8d5d7243b83a5718cac3ad24 Mon Sep 17 00:00:00 2001
From: Assaf Gordon <[email-masked]>
Date: Wed, 29 Jul 2015 19:31:52 -0400
Subject: [PATCH] vc-dwim: silently ignore dirty git submodules

* NEWS: mention it.
* VC.pm: ignore git submodules.
* tests/ignore-dirty-submodules: new file.
* tests/Makefile.am (TESTS): add it.
Discussed in http://bugs.gnu.org/21120
---
 NEWS                          |  2 ++
 VC.pm                         |  5 ++--
 tests/Makefile.am             |  3 ++-
 tests/ignore-dirty-submodules | 55 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 62 insertions(+), 3 deletions(-)
 create mode 100755 tests/ignore-dirty-submodules

diff --git a/NEWS b/NEWS
index 5129e3e..e7cb290 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ vc-dwim NEWS                                          -*- outline -*-
 
   vc-dwim now supports darcs.
 
+  vc-dwim now silently ignores dirty git submodules
+
 
 * Noteworthy changes in release 1.7 (2013-03-15) [stable]
 
diff --git a/VC.pm b/VC.pm
index 81a2390..039f312 100644
--- a/VC.pm
+++ b/VC.pm
@@ -57,8 +57,9 @@ my $vc_cmd =
    GIT() =>
    {
     AUTHOR_FMT => '--author=%s',
-    DIFF_COMMAND => [qw(git diff -B -C HEAD --)],
-    DIFF_PRISTINE => [qw(git diff --no-ext-diff -B -C HEAD --)],
+    DIFF_COMMAND => [qw(git diff --ignore-submodules=all -B -C HEAD --)],
+    DIFF_PRISTINE => [qw(git diff --ignore-submodules=all --no-ext-diff
+                         -B -C HEAD --)],
     VALID_DIFF_EXIT_STATUS => {0 => 1},
     COMMIT_COMMAND => [qw(git commit -q -F)],
     # is-version-controlled-file: true, if "git cat-file -t HEAD:$file"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 52671b5..2ff6375 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,6 +28,7 @@ TESTS = \
   subdir-cvs \
   t-vc-chlog \
   multiple-chlogs \
-  dirty-workdir
+  dirty-workdir \
+  ignore-dirty-submodules
 
 include $(srcdir)/check.mk
diff --git a/tests/ignore-dirty-submodules b/tests/ignore-dirty-submodules
new file mode 100755
index 0000000..c2bc52d
--- /dev/null
+++ b/tests/ignore-dirty-submodules
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# Ensure dirty git submodules are ignored by 'vc-dwim --diff'
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+print_ver_ vc-dwim
+
+require_git_
+
+fail=0
+
+##
+## Create two git repositories (a,b),
+## add 'a' as submodule of 'b',
+## then modify 'a'.
+##
+mkdir a b || framework_failure_
+(cd a \
+    && git init \
+    && echo a > a \
+    && git add a \
+    && git commit -m a ) >/dev/null || framework_failure_
+(cd b \
+    && git init \
+    && echo b > b \
+    && git add b \
+    && git commit -m b ) >/dev/null || framework_failure_
+(cd b \
+    && git submodule add ../a \
+    && git commit -m "submodule added") >/dev/null || framework_failure_
+
+## Sanity check: ensure no diffs, either with git or with vc-dwim
+cd b
+A=$(git diff) || framework_failure_
+test -z "$A" || framework_failure_
+B=$(vc-dwim --diff) || framework_failure_
+test -z "$B" || framework_failure_
+
+## Modify the submodule
+echo >> a/a || framework_failure_
+
+## git diff should report a dirty submodule
+git diff | grep -q '^\+Subproject commit [0-9a-f]*-dirty$' \
+    || framework_failure_
+
+## git diff with ignore flag should not report anything
+## (if this doesn't work as expected, vc-dwim will fail too)
+C=$(git diff --ignore-submodules=all) || framework_failure_
+test -z "$C" || framework_failure_
+
+## Now test vc-dwim
+D=$(vc-dwim --diff) || framework_failure_
+test -z "$D" || fail=1
+
+Exit $fail
-- 
1.9.1