diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-12-12 15:13:25 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-12-12 15:13:25 -0800 |
commit | 850eeaf3c05139b5ef42452919641959c7c04430 (patch) | |
tree | f124bf4f33e8af3a448d7c9092404ff108f5413f | |
parent | 7538be6d8dd802745b00040f8dae1d347707b35f (diff) | |
parent | 5f3eb7674082a52dea6c6252752509b05a3bfe0a (diff) | |
download | git-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.c | 55 | ||||
-rw-r--r-- | builtin/commit.c | 1 | ||||
-rw-r--r-- | builtin/diff.c | 2 | ||||
-rw-r--r-- | diff-lib.c | 3 | ||||
-rw-r--r-- | diff.h | 2 | ||||
-rw-r--r-- | submodule.c | 26 | ||||
-rw-r--r-- | submodule.h | 2 | ||||
-rwxr-xr-x | t/t4027-diff-submodule.sh | 12 | ||||
-rwxr-xr-x | t/t7508-status.sh | 6 |
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); @@ -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 |