]> Pileus Git - ~andy/git/commitdiff
Merge branch 'js/ignore-submodule'
authorJunio C Hamano <gitster@pobox.com>
Sun, 25 May 2008 20:37:08 +0000 (13:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 25 May 2008 20:37:08 +0000 (13:37 -0700)
* js/ignore-submodule:
  Ignore dirty submodule states during rebase and stash
  Teach update-index about --ignore-submodules
  diff options: Introduce --ignore-submodules

Documentation/diff-options.txt
Documentation/git-update-index.txt
builtin-update-index.c
cache.h
diff.c
diff.h
git-rebase--interactive.sh
git-rebase.sh
git-stash.sh
read-cache.c
t/t7402-submodule-rebase.sh [new file with mode: 0755]

index 13234fa280b279bfccad0a9aec6989727957567a..859d67990a62049c2f328dfd676cf21da8ff9a27 100644 (file)
@@ -228,6 +228,9 @@ endif::git-format-patch[]
 --no-ext-diff::
        Disallow external diff drivers.
 
+--ignore-submodules::
+       Ignore changes to submodules in the diff generation.
+
 --src-prefix=<prefix>::
        Show the given source prefix instead of "a/".
 
index 66be18ef36696c7422acd46510b16d756962fb8d..06640603c4b2cbd3f1825f33706544db8cbfe492 100644 (file)
@@ -15,6 +15,7 @@ SYNOPSIS
             [--cacheinfo <mode> <object> <file>]\*
             [--chmod=(+|-)x]
             [--assume-unchanged | --no-assume-unchanged]
+            [--ignore-submodules]
             [--really-refresh] [--unresolve] [--again | -g]
             [--info-only] [--index-info]
             [-z] [--stdin]
@@ -54,6 +55,10 @@ OPTIONS
         default behavior is to error out.  This option makes
         git-update-index continue anyway.
 
+--ignore-submodules:
+       Do not try to update submodules.  This option is only respected
+       when passed before --refresh.
+
 --unmerged::
         If --refresh finds unmerged changes in the index, the default
         behavior is to error out.  This option makes git-update-index
index a8795d3d5fea9f340dfe21a71190f120c63856cd..d4c85c0cbc6fec3d526cc57d8b748b1f1a82b9a1 100644 (file)
@@ -593,6 +593,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                                refresh_flags |= REFRESH_QUIET;
                                continue;
                        }
+                       if (!strcmp(path, "--ignore-submodules")) {
+                               refresh_flags |= REFRESH_IGNORE_SUBMODULES;
+                               continue;
+                       }
                        if (!strcmp(path, "--add")) {
                                allow_add = 1;
                                continue;
diff --git a/cache.h b/cache.h
index 8db19cc253dda9b63401f7b55ffbc0d333e216a8..ef330b4c6b71ebf5775b9fbb889ea635c7422c30 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -388,6 +388,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 #define REFRESH_UNMERGED       0x0002  /* allow unmerged */
 #define REFRESH_QUIET          0x0004  /* be quiet about it */
 #define REFRESH_IGNORE_MISSING 0x0008  /* ignore non-existent */
+#define REFRESH_IGNORE_SUBMODULES      0x0008  /* ignore submodules */
 extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
 
 struct lock_file {
diff --git a/diff.c b/diff.c
index 439d4746cae343f08b298473d35d9792048abfa0..d57bc299ee7499dc8f448220e894cc6e6a1d8aca 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2496,6 +2496,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                DIFF_OPT_SET(options, ALLOW_EXTERNAL);
        else if (!strcmp(arg, "--no-ext-diff"))
                DIFF_OPT_CLR(options, ALLOW_EXTERNAL);
+       else if (!strcmp(arg, "--ignore-submodules"))
+               DIFF_OPT_SET(options, IGNORE_SUBMODULES);
 
        /* misc options */
        else if (!strcmp(arg, "-z"))
@@ -3355,6 +3357,9 @@ void diff_addremove(struct diff_options *options,
        char concatpath[PATH_MAX];
        struct diff_filespec *one, *two;
 
+       if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
+               return;
+
        /* This may look odd, but it is a preparation for
         * feeding "there are unchanged files which should
         * not produce diffs, but when you are doing copy
@@ -3399,6 +3404,10 @@ void diff_change(struct diff_options *options,
        char concatpath[PATH_MAX];
        struct diff_filespec *one, *two;
 
+       if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
+                       && S_ISGITLINK(new_mode))
+               return;
+
        if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
                unsigned tmp;
                const unsigned char *tmp_c;
diff --git a/diff.h b/diff.h
index 3a02d38d12d94c39ff9ef3ab744ea7d157fb52b4..1dfe1f98b1dbe66fd3c7c5cd5a999c28172cd8cc 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -63,6 +63,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
 #define DIFF_OPT_REVERSE_DIFF        (1 << 15)
 #define DIFF_OPT_CHECK_FAILED        (1 << 16)
 #define DIFF_OPT_RELATIVE_NAME       (1 << 17)
+#define DIFF_OPT_IGNORE_SUBMODULES   (1 << 18)
 #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
 #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
 #define DIFF_OPT_CLR(opts, flag)    ((opts)->flags &= ~DIFF_OPT_##flag)
index 8aa73712ca11f4527f4b8d42bf3a14de2a16c39c..8ee08ff2fd4e414337f79a7e52d29ccda72377e6 100755 (executable)
@@ -56,9 +56,9 @@ output () {
 require_clean_work_tree () {
        # test if working tree is dirty
        git rev-parse --verify HEAD > /dev/null &&
-       git update-index --refresh &&
-       git diff-files --quiet &&
-       git diff-index --cached --quiet HEAD -- ||
+       git update-index --ignore-submodules --refresh &&
+       git diff-files --quiet --ignore-submodules &&
+       git diff-index --cached --quiet HEAD --ignore-submodules -- ||
        die "Working tree is dirty"
 }
 
@@ -377,11 +377,12 @@ do
                # Sanity check
                git rev-parse --verify HEAD >/dev/null ||
                        die "Cannot read HEAD"
-               git update-index --refresh && git diff-files --quiet ||
+               git update-index --ignore-submodules --refresh &&
+                       git diff-files --quiet --ignore-submodules ||
                        die "Working tree is dirty"
 
                # do we have anything to commit?
-               if git diff-index --cached --quiet HEAD --
+               if git diff-index --cached --quiet --ignore-submodules HEAD --
                then
                        : Nothing to commit -- skip this
                else
index 68855c18ae62ef6f4a3fdacb6f8de9c57511aa79..dd7dfe123c15a4b281c4a25a77887150b4a5dbb5 100755 (executable)
@@ -60,7 +60,7 @@ continue_merge () {
        fi
 
        cmt=`cat "$dotest/current"`
-       if ! git diff-index --quiet HEAD --
+       if ! git diff-index --quiet --ignore-submodules HEAD --
        then
                if ! git commit --no-verify -C "$cmt"
                then
@@ -150,7 +150,7 @@ while test $# != 0
 do
        case "$1" in
        --continue)
-               git diff-files --quiet || {
+               git diff-files --quiet --ignore-submodules || {
                        echo "You must edit all merge conflicts and then"
                        echo "mark them as resolved using git add"
                        exit 1
@@ -282,8 +282,8 @@ else
 fi
 
 # The tree must be really really clean.
-git update-index --refresh || exit
-diff=$(git diff-index --cached --name-status -r HEAD --)
+git update-index --ignore-submodules --refresh || exit
+diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
 case "$diff" in
 ?*)    echo "cannot rebase: your index is not up-to-date"
        echo "$diff"
index c2b68205a2b69eb91b2403e11238093fc65c04ef..4938ade589f2f7d1c69bd53f7bc7bc1bd33f488c 100755 (executable)
@@ -15,8 +15,8 @@ trap 'rm -f "$TMP-*"' 0
 ref_stash=refs/stash
 
 no_changes () {
-       git diff-index --quiet --cached HEAD -- &&
-       git diff-files --quiet
+       git diff-index --quiet --cached HEAD --ignore-submodules -- &&
+       git diff-files --quiet --ignore-submodules
 }
 
 clear_stash () {
@@ -130,7 +130,7 @@ show_stash () {
 }
 
 apply_stash () {
-       git diff-files --quiet ||
+       git diff-files --quiet --ignore-submodules ||
                die 'Cannot restore on top of a dirty state'
 
        unstash_index=
index 8b467f8f415b68db6e6ea83720ce6ae63dedb9e4..bc039819ee24083f13fee4558e51f16dee72a918 100644 (file)
@@ -942,6 +942,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
        int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
        int quiet = (flags & REFRESH_QUIET) != 0;
        int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+       int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
        unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
 
        for (i = 0; i < istate->cache_nr; i++) {
@@ -949,6 +950,9 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
                int cache_errno = 0;
 
                ce = istate->cache[i];
+               if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
+                       continue;
+
                if (ce_stage(ce)) {
                        while ((i < istate->cache_nr) &&
                               ! strcmp(istate->cache[i]->name, ce->name))
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
new file mode 100755 (executable)
index 0000000..5becb3e
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Johannes Schindelin
+#
+
+test_description='Test rebasing and stashing with dirty submodules'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       echo file > file &&
+       git add file &&
+       test_tick &&
+       git commit -m initial &&
+       git clone . submodule &&
+       git add submodule &&
+       test_tick &&
+       git commit -m submodule &&
+       echo second line >> file &&
+       (cd submodule && git pull) &&
+       test_tick &&
+       git commit -m file-and-submodule -a
+
+'
+
+test_expect_success 'rebase with a dirty submodule' '
+
+       (cd submodule &&
+        echo 3rd line >> file &&
+        test_tick &&
+        git commit -m fork -a) &&
+       echo unrelated >> file2 &&
+       git add file2 &&
+       test_tick &&
+       git commit -m unrelated file2 &&
+       echo other line >> file &&
+       test_tick &&
+       git commit -m update file &&
+       CURRENT=$(cd submodule && git rev-parse HEAD) &&
+       EXPECTED=$(git rev-parse HEAD~2:submodule) &&
+       GIT_TRACE=1 git rebase --onto HEAD~2 HEAD^ &&
+       STORED=$(git rev-parse HEAD:submodule) &&
+       test $EXPECTED = $STORED &&
+       test $CURRENT = $(cd submodule && git rev-parse HEAD)
+
+'
+
+cat > fake-editor.sh << \EOF
+#!/bin/sh
+echo $EDITOR_TEXT
+EOF
+chmod a+x fake-editor.sh
+
+test_expect_success 'interactive rebase with a dirty submodule' '
+
+       test submodule = $(git diff --name-only) &&
+       HEAD=$(git rev-parse HEAD) &&
+       GIT_EDITOR="\"$(pwd)/fake-editor.sh\"" EDITOR_TEXT="pick $HEAD" \
+               git rebase -i HEAD^ &&
+       test submodule = $(git diff --name-only)
+
+'
+
+test_expect_success 'rebase with dirty file and submodule fails' '
+
+       echo yet another line >> file &&
+       test_tick &&
+       git commit -m next file &&
+       echo rewrite > file &&
+       test_tick &&
+       git commit -m rewrite file &&
+       echo dirty > file &&
+       ! git rebase --onto HEAD~2 HEAD^
+
+'
+
+test_expect_success 'stash with a dirty submodule' '
+
+       echo new > file &&
+       CURRENT=$(cd submodule && git rev-parse HEAD) &&
+       git stash &&
+       test new != $(cat file) &&
+       test submodule = $(git diff --name-only) &&
+       test $CURRENT = $(cd submodule && git rev-parse HEAD) &&
+       git stash apply &&
+       test new = $(cat file) &&
+       test $CURRENT = $(cd submodule && git rev-parse HEAD)
+
+'
+
+test_done