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:
commit
7e83003029
@ -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/".
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
1
cache.h
1
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_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
9
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);
|
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
1
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_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)
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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=
|
||||||
|
@ -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
92
t/t7402-submodule-rebase.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user