summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2013-12-12 15:13:25 -0800
committerJunio C Hamano <gitster@pobox.com>2013-12-12 15:13:25 -0800
commit850eeaf3c05139b5ef42452919641959c7c04430 (patch)
treef124bf4f33e8af3a448d7c9092404ff108f5413f
parent7538be6d8dd802745b00040f8dae1d347707b35f (diff)
parent5f3eb7674082a52dea6c6252752509b05a3bfe0a (diff)
downloadgit-850eeaf3c05139b5ef42452919641959c7c04430.tar.gz
Merge branch 'hv/submodule-ignore-fix' into HEAD
* hv/submodule-ignore-fix: disable complete ignorance of submodules for index <-> HEAD diff always show committed submodules in summary after commit teach add -f option for ignored submodules fix 'git add' to skip submodules configured as ignored
-rw-r--r--builtin/add.c55
-rw-r--r--builtin/commit.c1
-rw-r--r--builtin/diff.c2
-rw-r--r--diff-lib.c3
-rw-r--r--diff.h2
-rw-r--r--submodule.c26
-rw-r--r--submodule.h2
-rwxr-xr-xt/t4027-diff-submodule.sh12
-rwxr-xr-xt/t7508-status.sh6
9 files changed, 90 insertions, 19 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 0df73ae735..130b0cee04 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -15,6 +15,8 @@
#include "diffcore.h"
#include "revision.h"
#include "bulk-checkin.h"
+#include "submodule.h"
+#include "string-list.h"
static const char * const builtin_add_usage[] = {
N_("git add [options] [--] <pathspec>..."),
@@ -36,6 +38,20 @@ struct update_callback_data {
static const char *option_with_implicit_dot;
static const char *short_option_with_implicit_dot;
+static struct lock_file lock_file;
+
+static const char ignore_error[] =
+N_("The following paths are ignored by one of your .gitignore files:\n");
+static const char submodule_ignore_error[] =
+N_("The following paths are ignored submodules:\n");
+
+static int verbose, show_only, ignored_too, refresh_only;
+static int ignore_add_errors, intent_to_add, ignore_missing;
+
+#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
+static int addremove = ADDREMOVE_DEFAULT;
+static int addremove_explicit = -1; /* unspecified */
+
static void warn_pathless_add(void)
{
static int shown;
@@ -139,6 +155,9 @@ static void update_callback(struct diff_queue_struct *q,
warn_pathless_add();
continue;
}
+ if (is_ignored_submodule(path) && !ignored_too)
+ continue;
+
switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
@@ -173,6 +192,7 @@ static void update_files_in_cache(const char *prefix,
struct rev_info rev;
init_revisions(&rev, prefix);
+ enforce_no_complete_ignore_submodule(&rev.diffopt);
setup_revisions(0, NULL, &rev, NULL);
if (pathspec)
copy_pathspec(&rev.prune_data, pathspec);
@@ -331,18 +351,6 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
return 0;
}
-static struct lock_file lock_file;
-
-static const char ignore_error[] =
-N_("The following paths are ignored by one of your .gitignore files:\n");
-
-static int verbose, show_only, ignored_too, refresh_only;
-static int ignore_add_errors, intent_to_add, ignore_missing;
-
-#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */
-static int addremove = ADDREMOVE_DEFAULT;
-static int addremove_explicit = -1; /* unspecified */
-
static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)
{
/* if we are told to ignore, we are not adding removals */
@@ -378,6 +386,10 @@ static int add_config(const char *var, const char *value, void *cb)
ignore_add_errors = git_config_bool(var, value);
return 0;
}
+
+ if (!prefixcmp(var, "submodule."))
+ return parse_submodule_config_option(var, value);
+
return git_default_config(var, value, cb);
}
@@ -402,6 +414,17 @@ static int add_files(struct dir_struct *dir, int flags)
return exit_status;
}
+static void die_ignored_submodules(struct string_list *ignored_submodules)
+{
+ struct string_list_item *path;
+
+ fprintf(stderr, _(submodule_ignore_error));
+ for_each_string_list_item(path, ignored_submodules)
+ fprintf(stderr, "%s\n", path->string);
+ fprintf(stderr, _("Use -f if you really want to add them.\n"));
+ die(_("no files added"));
+}
+
int cmd_add(int argc, const char **argv, const char *prefix)
{
int exit_status = 0;
@@ -414,7 +437,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
char *seen = NULL;
int implicit_dot = 0;
struct update_callback_data update_data;
+ struct string_list ignored_submodules = STRING_LIST_INIT_NODUP;
+ gitmodules_config();
git_config(add_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_add_options,
@@ -545,6 +570,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
for (i = 0; i < pathspec.nr; i++) {
const char *path = pathspec.items[i].match;
+ char path_copy[PATH_MAX];
if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
continue;
if (!seen[i] &&
@@ -559,6 +585,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
die(_("pathspec '%s' did not match any files"),
pathspec.items[i].original);
}
+ normalize_path_copy(path_copy, path);
+ if (is_ignored_submodule(path_copy))
+ string_list_insert(&ignored_submodules, path);
}
free(seen);
}
@@ -580,6 +609,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
update_files_in_cache(prefix, &pathspec, &update_data);
exit_status |= !!update_data.add_errors;
+ if (!ignored_too && ignored_submodules.nr)
+ die_ignored_submodules(&ignored_submodules);
if (add_new_files)
exit_status |= add_files(&dir, flags);
diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478c6d..fd8731869c 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1361,6 +1361,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
strbuf_release(&committer_ident);
init_revisions(&rev, prefix);
+ enforce_no_complete_ignore_submodule(&rev.diffopt);
setup_revisions(0, NULL, &rev, NULL);
rev.diff = 1;
diff --git a/builtin/diff.c b/builtin/diff.c
index fe0cc7f1b5..82d29f66a3 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -165,6 +165,8 @@ static int builtin_diff_tree(struct rev_info *revs,
if (argc > 1)
usage(builtin_diff_usage);
+ enforce_no_complete_ignore_submodule(&revs->diffopt);
+
/*
* We saw two trees, ent0 and ent1. If ent1 is uninteresting,
* swap them.
diff --git a/diff-lib.c b/diff-lib.c
index 346cac651d..c5219cb046 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -483,6 +483,9 @@ int run_diff_index(struct rev_info *revs, int cached)
{
struct object_array_entry *ent;
+ if (cached)
+ enforce_no_complete_ignore_submodule(&revs->diffopt);
+
ent = revs->pending.objects;
if (diff_cache(revs, ent->item->sha1, ent->name, cached))
exit(128);
diff --git a/diff.h b/diff.h
index 760388fa17..da13a99c3f 100644
--- a/diff.h
+++ b/diff.h
@@ -64,7 +64,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
#define DIFF_OPT_FIND_COPIES_HARDER (1 << 6)
#define DIFF_OPT_FOLLOW_RENAMES (1 << 7)
#define DIFF_OPT_RENAME_EMPTY (1 << 8)
-/* (1 << 9) unused */
+#define DIFF_OPT_NO_IGNORE_SUBMODULE (1 << 9)
#define DIFF_OPT_HAS_CHANGES (1 << 10)
#define DIFF_OPT_QUICK (1 << 11)
#define DIFF_OPT_NO_INDEX (1 << 12)
diff --git a/submodule.c b/submodule.c
index b80ecacf60..a142390414 100644
--- a/submodule.c
+++ b/submodule.c
@@ -176,6 +176,16 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
}
}
+int is_ignored_submodule(const char *path)
+{
+ struct diff_options diffopt;
+ memset(&diffopt, 0, sizeof(diffopt));
+ set_diffopt_flags_from_submodule_config(&diffopt, path);
+ if (DIFF_OPT_TST(&diffopt, IGNORE_SUBMODULES))
+ return 1;
+ return 0;
+}
+
int submodule_config(const char *var, const char *value, void *cb)
{
if (starts_with(var, "submodule."))
@@ -271,6 +281,16 @@ int parse_submodule_config_option(const char *var, const char *value)
return 0;
}
+void enforce_no_complete_ignore_submodule(struct diff_options *diffopt)
+{
+ DIFF_OPT_SET(diffopt, NO_IGNORE_SUBMODULE);
+ if (DIFF_OPT_TST(diffopt, OVERRIDE_SUBMODULE_CONFIG) &&
+ DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES)) {
+ DIFF_OPT_CLR(diffopt, IGNORE_SUBMODULES);
+ DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
+ }
+}
+
void handle_ignore_submodules_arg(struct diff_options *diffopt,
const char *arg)
{
@@ -278,9 +298,11 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt,
DIFF_OPT_CLR(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
DIFF_OPT_CLR(diffopt, IGNORE_DIRTY_SUBMODULES);
- if (!strcmp(arg, "all"))
+ if (!strcmp(arg, "all")) {
+ if (DIFF_OPT_TST(diffopt, NO_IGNORE_SUBMODULE))
+ return;
DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
- else if (!strcmp(arg, "untracked"))
+ } else if (!strcmp(arg, "untracked"))
DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
else if (!strcmp(arg, "dirty"))
DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
diff --git a/submodule.h b/submodule.h
index 7beec4822b..e067580b57 100644
--- a/submodule.h
+++ b/submodule.h
@@ -17,9 +17,11 @@ int remove_path_from_gitmodules(const char *path);
void stage_updated_gitmodules(void);
void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
const char *path);
+int is_ignored_submodule(const char *path);
int submodule_config(const char *var, const char *value, void *cb);
void gitmodules_config(void);
int parse_submodule_config_option(const char *var, const char *value);
+void enforce_no_complete_ignore_submodule(struct diff_options *diffopt);
void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
void show_submodule_summary(FILE *f, const char *path,
diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh
index 518bf9524e..bd84ea7c7f 100755
--- a/t/t4027-diff-submodule.sh
+++ b/t/t4027-diff-submodule.sh
@@ -258,7 +258,9 @@ test_expect_success 'git diff between submodule commits' '
expect_from_to >expect.body $subtip $subprev &&
test_cmp expect.body actual.body &&
git diff --ignore-submodules HEAD^..HEAD >actual &&
- ! test -s actual
+ sed -e "1,/^@@/d" actual >actual.body &&
+ expect_from_to >expect.body $subtip $subprev &&
+ test_cmp expect.body actual.body
'
test_expect_success 'git diff between submodule commits [.git/config]' '
@@ -274,7 +276,9 @@ test_expect_success 'git diff between submodule commits [.git/config]' '
test_cmp expect.body actual.body &&
git config submodule.subname.ignore all &&
git diff HEAD^..HEAD >actual &&
- ! test -s actual &&
+ sed -e "1,/^@@/d" actual >actual.body &&
+ expect_from_to >expect.body $subtip $subprev &&
+ test_cmp expect.body actual.body &&
git diff --ignore-submodules=dirty HEAD^..HEAD >actual &&
sed -e "1,/^@@/d" actual >actual.body &&
expect_from_to >expect.body $subtip $subprev &&
@@ -294,7 +298,9 @@ test_expect_success 'git diff between submodule commits [.gitmodules]' '
test_cmp expect.body actual.body &&
git config -f .gitmodules submodule.subname.ignore all &&
git diff HEAD^..HEAD >actual &&
- ! test -s actual &&
+ sed -e "1,/^@@/d" actual >actual.body &&
+ expect_from_to >expect.body $subtip $subprev &&
+ test_cmp expect.body actual.body &&
git config submodule.subname.ignore dirty &&
git config submodule.subname.path sub &&
git diff HEAD^..HEAD >actual &&
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index c987b5ed65..977295f786 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -1357,6 +1357,11 @@ test_expect_success "status (core.commentchar with two chars with submodule summ
test_expect_success "--ignore-submodules=all suppresses submodule summary" '
cat > expect << EOF &&
On branch master
+Changes to be committed:
+ (use "git reset HEAD <file>..." to unstage)
+
+ modified: sm
+
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
@@ -1374,7 +1379,6 @@ Untracked files:
output
untracked
-no changes added to commit (use "git add" and/or "git commit -a")
EOF
git status --ignore-submodules=all > output &&
test_i18ncmp expect output