aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-05-25 13:37:08 -0700
committerJunio C Hamano <gitster@pobox.com>2008-05-25 13:37:08 -0700
commit7e83003029ed488253f6173b047a9c77933c8561 (patch)
tree191fd7e272b6adde953d76b974a3ed9de282b128
parent58dd4915ba1a933af0087e351743e31b2f9be878 (diff)
parent6848d58c60b7af365ce54cf3e3b274a2f9da2e7e (diff)
downloadgit-7e83003029ed488253f6173b047a9c77933c8561.tar.gz
git-7e83003029ed488253f6173b047a9c77933c8561.tar.xz
Merge branch 'js/ignore-submodule'
* js/ignore-submodule: Ignore dirty submodule states during rebase and stash Teach update-index about --ignore-submodules diff options: Introduce --ignore-submodules
-rw-r--r--Documentation/diff-options.txt3
-rw-r--r--Documentation/git-update-index.txt5
-rw-r--r--builtin-update-index.c4
-rw-r--r--cache.h1
-rw-r--r--diff.c9
-rw-r--r--diff.h1
-rwxr-xr-xgit-rebase--interactive.sh11
-rwxr-xr-xgit-rebase.sh8
-rwxr-xr-xgit-stash.sh6
-rw-r--r--read-cache.c4
-rwxr-xr-xt/t7402-submodule-rebase.sh92
11 files changed, 132 insertions, 12 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 13234fa28..859d67990 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -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/".
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 66be18ef3..06640603c 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -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
diff --git a/builtin-update-index.c b/builtin-update-index.c
index a8795d3d5..d4c85c0cb 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -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 8db19cc25..ef330b4c6 100644
--- 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 439d4746c..d57bc299e 100644
--- 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 3a02d38d1..1dfe1f98b 100644
--- 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)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 8aa73712c..8ee08ff2f 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -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
diff --git a/git-rebase.sh b/git-rebase.sh
index 68855c18a..dd7dfe123 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -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"
diff --git a/git-stash.sh b/git-stash.sh
index c2b68205a..4938ade58 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -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=
diff --git a/read-cache.c b/read-cache.c
index 8b467f8f4..bc039819e 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -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
index 000000000..5becb3ec5
--- /dev/null
+++ b/t/t7402-submodule-rebase.sh
@@ -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