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
This commit is contained in:
Junio C Hamano 2008-05-25 13:37:08 -07:00
commit 7e83003029
11 changed files with 132 additions and 12 deletions

View File

@ -228,6 +228,9 @@ endif::git-format-patch[]
--no-ext-diff:: --no-ext-diff::
Disallow external diff drivers. Disallow external diff drivers.
--ignore-submodules::
Ignore changes to submodules in the diff generation.
--src-prefix=<prefix>:: --src-prefix=<prefix>::
Show the given source prefix instead of "a/". Show the given source prefix instead of "a/".

View File

@ -15,6 +15,7 @@ SYNOPSIS
[--cacheinfo <mode> <object> <file>]\* [--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x] [--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged] [--assume-unchanged | --no-assume-unchanged]
[--ignore-submodules]
[--really-refresh] [--unresolve] [--again | -g] [--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info] [--info-only] [--index-info]
[-z] [--stdin] [-z] [--stdin]
@ -54,6 +55,10 @@ OPTIONS
default behavior is to error out. This option makes default behavior is to error out. This option makes
git-update-index continue anyway. git-update-index continue anyway.
--ignore-submodules:
Do not try to update submodules. This option is only respected
when passed before --refresh.
--unmerged:: --unmerged::
If --refresh finds unmerged changes in the index, the default If --refresh finds unmerged changes in the index, the default
behavior is to error out. This option makes git-update-index behavior is to error out. This option makes git-update-index

View File

@ -593,6 +593,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
refresh_flags |= REFRESH_QUIET; refresh_flags |= REFRESH_QUIET;
continue; continue;
} }
if (!strcmp(path, "--ignore-submodules")) {
refresh_flags |= REFRESH_IGNORE_SUBMODULES;
continue;
}
if (!strcmp(path, "--add")) { if (!strcmp(path, "--add")) {
allow_add = 1; allow_add = 1;
continue; continue;

View File

@ -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_UNMERGED 0x0002 /* allow unmerged */
#define REFRESH_QUIET 0x0004 /* be quiet about it */ #define REFRESH_QUIET 0x0004 /* be quiet about it */
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ #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); extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
struct lock_file { struct lock_file {

9
diff.c
View File

@ -2496,6 +2496,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_SET(options, ALLOW_EXTERNAL); DIFF_OPT_SET(options, ALLOW_EXTERNAL);
else if (!strcmp(arg, "--no-ext-diff")) else if (!strcmp(arg, "--no-ext-diff"))
DIFF_OPT_CLR(options, ALLOW_EXTERNAL); DIFF_OPT_CLR(options, ALLOW_EXTERNAL);
else if (!strcmp(arg, "--ignore-submodules"))
DIFF_OPT_SET(options, IGNORE_SUBMODULES);
/* misc options */ /* misc options */
else if (!strcmp(arg, "-z")) else if (!strcmp(arg, "-z"))
@ -3355,6 +3357,9 @@ void diff_addremove(struct diff_options *options,
char concatpath[PATH_MAX]; char concatpath[PATH_MAX];
struct diff_filespec *one, *two; 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 /* This may look odd, but it is a preparation for
* feeding "there are unchanged files which should * feeding "there are unchanged files which should
* not produce diffs, but when you are doing copy * not produce diffs, but when you are doing copy
@ -3399,6 +3404,10 @@ void diff_change(struct diff_options *options,
char concatpath[PATH_MAX]; char concatpath[PATH_MAX];
struct diff_filespec *one, *two; 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)) { if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
unsigned tmp; unsigned tmp;
const unsigned char *tmp_c; const unsigned char *tmp_c;

1
diff.h
View File

@ -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_REVERSE_DIFF (1 << 15)
#define DIFF_OPT_CHECK_FAILED (1 << 16) #define DIFF_OPT_CHECK_FAILED (1 << 16)
#define DIFF_OPT_RELATIVE_NAME (1 << 17) #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_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(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) #define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)

View File

@ -56,9 +56,9 @@ output () {
require_clean_work_tree () { require_clean_work_tree () {
# test if working tree is dirty # test if working tree is dirty
git rev-parse --verify HEAD > /dev/null && git rev-parse --verify HEAD > /dev/null &&
git update-index --refresh && git update-index --ignore-submodules --refresh &&
git diff-files --quiet && git diff-files --quiet --ignore-submodules &&
git diff-index --cached --quiet HEAD -- || git diff-index --cached --quiet HEAD --ignore-submodules -- ||
die "Working tree is dirty" die "Working tree is dirty"
} }
@ -377,11 +377,12 @@ do
# Sanity check # Sanity check
git rev-parse --verify HEAD >/dev/null || git rev-parse --verify HEAD >/dev/null ||
die "Cannot read HEAD" 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" die "Working tree is dirty"
# do we have anything to commit? # do we have anything to commit?
if git diff-index --cached --quiet HEAD -- if git diff-index --cached --quiet --ignore-submodules HEAD --
then then
: Nothing to commit -- skip this : Nothing to commit -- skip this
else else

View File

@ -60,7 +60,7 @@ continue_merge () {
fi fi
cmt=`cat "$dotest/current"` cmt=`cat "$dotest/current"`
if ! git diff-index --quiet HEAD -- if ! git diff-index --quiet --ignore-submodules HEAD --
then then
if ! git commit --no-verify -C "$cmt" if ! git commit --no-verify -C "$cmt"
then then
@ -150,7 +150,7 @@ while test $# != 0
do do
case "$1" in case "$1" in
--continue) --continue)
git diff-files --quiet || { git diff-files --quiet --ignore-submodules || {
echo "You must edit all merge conflicts and then" echo "You must edit all merge conflicts and then"
echo "mark them as resolved using git add" echo "mark them as resolved using git add"
exit 1 exit 1
@ -282,8 +282,8 @@ else
fi fi
# The tree must be really really clean. # The tree must be really really clean.
git update-index --refresh || exit git update-index --ignore-submodules --refresh || exit
diff=$(git diff-index --cached --name-status -r HEAD --) diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
case "$diff" in case "$diff" in
?*) echo "cannot rebase: your index is not up-to-date" ?*) echo "cannot rebase: your index is not up-to-date"
echo "$diff" echo "$diff"

View File

@ -15,8 +15,8 @@ trap 'rm -f "$TMP-*"' 0
ref_stash=refs/stash ref_stash=refs/stash
no_changes () { no_changes () {
git diff-index --quiet --cached HEAD -- && git diff-index --quiet --cached HEAD --ignore-submodules -- &&
git diff-files --quiet git diff-files --quiet --ignore-submodules
} }
clear_stash () { clear_stash () {
@ -130,7 +130,7 @@ show_stash () {
} }
apply_stash () { apply_stash () {
git diff-files --quiet || git diff-files --quiet --ignore-submodules ||
die 'Cannot restore on top of a dirty state' die 'Cannot restore on top of a dirty state'
unstash_index= unstash_index=

View 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 allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
int quiet = (flags & REFRESH_QUIET) != 0; int quiet = (flags & REFRESH_QUIET) != 0;
int not_new = (flags & REFRESH_IGNORE_MISSING) != 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; unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
for (i = 0; i < istate->cache_nr; i++) { 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; int cache_errno = 0;
ce = istate->cache[i]; ce = istate->cache[i];
if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
continue;
if (ce_stage(ce)) { if (ce_stage(ce)) {
while ((i < istate->cache_nr) && while ((i < istate->cache_nr) &&
! strcmp(istate->cache[i]->name, ce->name)) ! strcmp(istate->cache[i]->name, ce->name))

92
t/t7402-submodule-rebase.sh Executable file
View File

@ -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