@matheusbsbs / matheus-bagliano / commits / 302ad7a993
Fork 0

Submodules: Use "ignore" settings from .gitmodules too for diff and status

The .gitmodules file is parsed for "submodule.<name>.ignore" entries before looking for them in .git/config. Thus settings found in .git/config will override those from .gitmodules, thereby allowing the local developer to ignore settings given by the remote side while also letting upstream set defaults for those users who don't have special needs. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jens Lehmann committed Aug 6, 2010 at 00:40 UTC 302ad7a9930a34413418b6436f96826070367647
13 files changed +209 -10
Documentation/config.txt
+3
@@ -1752,6 +1752,9 @@ submodule.<name>.ignore::
1752 let submodules with modified tracked files in their work tree show up.
1753 Using "none" (the default when this option is not set) also shows
1754 submodules that have untracked files in their work tree as changed.
1755 + This setting overrides any setting made in .gitmodules for this submodule,
1756 + both settings can be overriden on the command line by using the
1757 + "--ignore-submodule" option.
1758
1759 tar.umask::
1760 This variable can be used to restrict the permission bits of
Documentation/diff-options.txt
+1 -1
@@ -334,7 +334,7 @@ endif::git-format-patch[]
334 Using "none" will consider the submodule modified when it either contains
335 untracked or modified files or its HEAD differs from the commit recorded
336 in the superproject and can be used to override any settings of the
337 - 'ignore' option in linkgit:git-config[1]. When
337 + 'ignore' option in linkgit:git-config[1] or linkgit:gitmodules[5]. When
338 "untracked" is used submodules are not considered dirty when they only
339 contain untracked content (but they are still scanned for modified
340 content). Using "dirty" ignores all changes to the work tree of submodules,
Documentation/git-status.txt
+1 -1
@@ -59,7 +59,7 @@ specified.
59 Using "none" will consider the submodule modified when it either contains
60 untracked or modified files or its HEAD differs from the commit recorded
61 in the superproject and can be used to override any settings of the
62 - 'ignore' option in linkgit:git-config[1]. When
62 + 'ignore' option in linkgit:git-config[1] or linkgit:gitmodules[5]. When
63 "untracked" is used submodules are not considered dirty when they only
64 contain untracked content (but they are still scanned for modified
65 content). Using "dirty" ignores all changes to the work tree of submodules,
Documentation/gitmodules.txt
+15
@@ -44,6 +44,21 @@ submodule.<name>.update::
44 This config option is overridden if 'git submodule update' is given
45 the '--merge' or '--rebase' options.
46
47 +submodule.<name>.ignore::
48 + Defines under what circumstances "git status" and the diff family show
49 + a submodule as modified. When set to "all", it will never be considered
50 + modified, "dirty" will ignore all changes to the submodules work tree and
51 + takes only differences between the HEAD of the submodule and the commit
52 + recorded in the superproject into account. "untracked" will additionally
53 + let submodules with modified tracked files in their work tree show up.
54 + Using "none" (the default when this option is not set) also shows
55 + submodules that have untracked files in their work tree as changed.
56 + If this option is also present in the submodules entry in .git/config of
57 + the superproject, the setting there will override the one found in
58 + .gitmodules.
59 + Both settings can be overriden on the command line by using the
60 + "--ignore-submodule" option.
61 +
62
63 EXAMPLES
64 --------
builtin/commit.c
+2
@@ -25,6 +25,7 @@
25 #include "rerere.h"
26 #include "unpack-trees.h"
27 #include "quote.h"
28 +#include "submodule.h"
29
30 static const char * const builtin_commit_usage[] = {
31 "git commit [options] [--] <filepattern>...",
@@ -1073,6 +1074,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1074 status_format = STATUS_FORMAT_PORCELAIN;
1075
1076 wt_status_prepare(&s);
1077 + gitmodules_config();
1078 git_config(git_status_config, &s);
1079 in_merge = file_exists(git_path("MERGE_HEAD"));
1080 argc = parse_options(argc, argv, prefix,
builtin/diff-files.c
+2
@@ -8,6 +8,7 @@
8 #include "commit.h"
9 #include "revision.h"
10 #include "builtin.h"
11 +#include "submodule.h"
12
13 static const char diff_files_usage[] =
14 "git diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
@@ -20,6 +21,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
21 unsigned options = 0;
22
23 init_revisions(&rev, prefix);
24 + gitmodules_config();
25 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
26 rev.abbrev = 0;
27
builtin/diff-index.c
+2
@@ -3,6 +3,7 @@
3 #include "commit.h"
4 #include "revision.h"
5 #include "builtin.h"
6 +#include "submodule.h"
7
8 static const char diff_cache_usage[] =
9 "git diff-index [-m] [--cached] "
@@ -17,6 +18,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
18 int result;
19
20 init_revisions(&rev, prefix);
21 + gitmodules_config();
22 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
23 rev.abbrev = 0;
24
builtin/diff-tree.c
+2
@@ -3,6 +3,7 @@
3 #include "commit.h"
4 #include "log-tree.h"
5 #include "builtin.h"
6 +#include "submodule.h"
7
8 static struct rev_info log_tree_opt;
9
@@ -112,6 +113,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
113 int read_stdin = 0;
114
115 init_revisions(opt, prefix);
116 + gitmodules_config();
117 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
118 opt->abbrev = 0;
119 opt->diff = 1;
builtin/diff.c
+2
@@ -13,6 +13,7 @@
13 #include "revision.h"
14 #include "log-tree.h"
15 #include "builtin.h"
16 +#include "submodule.h"
17
18 struct blobinfo {
19 unsigned char sha1[20];
@@ -279,6 +280,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
280 */
281
282 prefix = setup_git_directory_gently(&nongit);
283 + gitmodules_config();
284 git_config(git_diff_ui_config, NULL);
285
286 if (diff_use_color_default == -1)
submodule.c
+19
@@ -62,6 +62,25 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
62 }
63 }
64
65 +static int submodule_config(const char *var, const char *value, void *cb)
66 +{
67 + if (!prefixcmp(var, "submodule."))
68 + return parse_submodule_config_option(var, value);
69 + return 0;
70 +}
71 +
72 +void gitmodules_config(void)
73 +{
74 + const char *work_tree = get_git_work_tree();
75 + if (work_tree) {
76 + struct strbuf gitmodules_path = STRBUF_INIT;
77 + strbuf_addstr(&gitmodules_path, work_tree);
78 + strbuf_addstr(&gitmodules_path, "/.gitmodules");
79 + git_config_from_file(submodule_config, gitmodules_path.buf, NULL);
80 + strbuf_release(&gitmodules_path);
81 + }
82 +}
83 +
84 int parse_submodule_config_option(const char *var, const char *value)
85 {
86 int len;
submodule.h
+1
@@ -5,6 +5,7 @@ struct diff_options;
5
6 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
7 const char *path);
8 +void gitmodules_config();
9 int parse_submodule_config_option(const char *var, const char *value);
10 void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
11 void show_submodule_summary(FILE *f, const char *path,
t/t4027-diff-submodule.sh
+76
@@ -139,6 +139,36 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)
139 git config --remove-section submodule.subname
140 '
141
142 +test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match) [.gitmodules]' '
143 + git config --add -f .gitmodules submodule.subname.ignore none &&
144 + git config --add -f .gitmodules submodule.subname.path sub &&
145 + git diff HEAD >actual &&
146 + sed -e "1,/^@@/d" actual >actual.body &&
147 + expect_from_to >expect.body $subprev $subprev-dirty &&
148 + test_cmp expect.body actual.body &&
149 + git config -f .gitmodules submodule.subname.ignore all &&
150 + git config -f .gitmodules submodule.subname.path sub &&
151 + git diff HEAD >actual2 &&
152 + ! test -s actual2 &&
153 + git config -f .gitmodules submodule.subname.ignore untracked &&
154 + git diff HEAD >actual3 &&
155 + sed -e "1,/^@@/d" actual3 >actual3.body &&
156 + expect_from_to >expect.body $subprev $subprev-dirty &&
157 + test_cmp expect.body actual3.body &&
158 + git config -f .gitmodules submodule.subname.ignore dirty &&
159 + git diff HEAD >actual4 &&
160 + ! test -s actual4 &&
161 + git config submodule.subname.ignore none &&
162 + git config submodule.subname.path sub &&
163 + git diff HEAD >actual &&
164 + sed -e "1,/^@@/d" actual >actual.body &&
165 + expect_from_to >expect.body $subprev $subprev-dirty &&
166 + test_cmp expect.body actual.body &&
167 + git config --remove-section submodule.subname &&
168 + git config --remove-section -f .gitmodules submodule.subname &&
169 + rm .gitmodules
170 +'
171 +
172 test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '
173 (
174 cd sub &&
@@ -189,6 +219,28 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)
219 git config --remove-section submodule.subname
220 '
221
222 +test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match) [.gitmodules]' '
223 + git config --add -f .gitmodules submodule.subname.ignore all &&
224 + git config --add -f .gitmodules submodule.subname.path sub &&
225 + git diff HEAD >actual2 &&
226 + ! test -s actual2 &&
227 + git config -f .gitmodules submodule.subname.ignore untracked &&
228 + git diff HEAD >actual3 &&
229 + ! test -s actual3 &&
230 + git config -f .gitmodules submodule.subname.ignore dirty &&
231 + git diff HEAD >actual4 &&
232 + ! test -s actual4 &&
233 + git config submodule.subname.ignore none &&
234 + git config submodule.subname.path sub &&
235 + git diff HEAD >actual &&
236 + sed -e "1,/^@@/d" actual >actual.body &&
237 + expect_from_to >expect.body $subprev $subprev-dirty &&
238 + test_cmp expect.body actual.body &&
239 + git config --remove-section submodule.subname &&
240 + git config --remove-section -f .gitmodules submodule.subname &&
241 + rm .gitmodules
242 +'
243 +
244 test_expect_success 'git diff between submodule commits' '
245 git diff HEAD^..HEAD >actual &&
246 sed -e "1,/^@@/d" actual >actual.body &&
@@ -222,6 +274,30 @@ test_expect_success 'git diff between submodule commits [.git/config]' '
274 git config --remove-section submodule.subname
275 '
276
277 +test_expect_success 'git diff between submodule commits [.gitmodules]' '
278 + git diff HEAD^..HEAD >actual &&
279 + sed -e "1,/^@@/d" actual >actual.body &&
280 + expect_from_to >expect.body $subtip $subprev &&
281 + test_cmp expect.body actual.body &&
282 + git config --add -f .gitmodules submodule.subname.ignore dirty &&
283 + git config --add -f .gitmodules submodule.subname.path sub &&
284 + git diff HEAD^..HEAD >actual &&
285 + sed -e "1,/^@@/d" actual >actual.body &&
286 + expect_from_to >expect.body $subtip $subprev &&
287 + test_cmp expect.body actual.body &&
288 + git config -f .gitmodules submodule.subname.ignore all &&
289 + git diff HEAD^..HEAD >actual &&
290 + ! test -s actual &&
291 + git config submodule.subname.ignore dirty &&
292 + git config submodule.subname.path sub &&
293 + git diff HEAD^..HEAD >actual &&
294 + sed -e "1,/^@@/d" actual >actual.body &&
295 + expect_from_to >expect.body $subtip $subprev &&
296 + git config --remove-section submodule.subname &&
297 + git config --remove-section -f .gitmodules submodule.subname &&
298 + rm .gitmodules
299 +'
300 +
301 test_expect_success 'git diff (empty submodule dir)' '
302 : >empty &&
303 rm -rf sub/* sub/.git &&
t/t7508-status.sh
+83 -8
@@ -848,12 +848,23 @@ test_expect_success '--ignore-submodules=untracked suppresses submodules with un
848 test_cmp expect output
849 '
850
851 +test_expect_success '.gitmodules ignore=untracked suppresses submodules with untracked content' '
852 + git config --add -f .gitmodules submodule.subname.ignore untracked &&
853 + git config --add -f .gitmodules submodule.subname.path sm &&
854 + git status > output &&
855 + test_cmp expect output &&
856 + git config -f .gitmodules --remove-section submodule.subname
857 +'
858 +
859 test_expect_success '.git/config ignore=untracked suppresses submodules with untracked content' '
860 + git config --add -f .gitmodules submodule.subname.ignore none &&
861 + git config --add -f .gitmodules submodule.subname.path sm &&
862 git config --add submodule.subname.ignore untracked &&
863 git config --add submodule.subname.path sm &&
864 git status > output &&
865 test_cmp expect output &&
856 - git config --remove-section submodule.subname
866 + git config --remove-section submodule.subname &&
867 + git config --remove-section -f .gitmodules submodule.subname
868 '
869
870 test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
@@ -861,12 +872,23 @@ test_expect_success '--ignore-submodules=dirty suppresses submodules with untrac
872 test_cmp expect output
873 '
874
875 +test_expect_success '.gitmodules ignore=dirty suppresses submodules with untracked content' '
876 + git config --add -f .gitmodules submodule.subname.ignore dirty &&
877 + git config --add -f .gitmodules submodule.subname.path sm &&
878 + git status > output &&
879 + test_cmp expect output &&
880 + git config -f .gitmodules --remove-section submodule.subname
881 +'
882 +
883 test_expect_success '.git/config ignore=dirty suppresses submodules with untracked content' '
884 + git config --add -f .gitmodules submodule.subname.ignore none &&
885 + git config --add -f .gitmodules submodule.subname.path sm &&
886 git config --add submodule.subname.ignore dirty &&
887 git config --add submodule.subname.path sm &&
888 git status > output &&
889 test_cmp expect output &&
869 - git config --remove-section submodule.subname
890 + git config --remove-section submodule.subname &&
891 + git config -f .gitmodules --remove-section submodule.subname
892 '
893
894 test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
@@ -875,12 +897,23 @@ test_expect_success '--ignore-submodules=dirty suppresses submodules with modifi
897 test_cmp expect output
898 '
899
900 +test_expect_success '.gitmodules ignore=dirty suppresses submodules with modified content' '
901 + git config --add -f .gitmodules submodule.subname.ignore dirty &&
902 + git config --add -f .gitmodules submodule.subname.path sm &&
903 + git status > output &&
904 + test_cmp expect output &&
905 + git config -f .gitmodules --remove-section submodule.subname
906 +'
907 +
908 test_expect_success '.git/config ignore=dirty suppresses submodules with modified content' '
909 + git config --add -f .gitmodules submodule.subname.ignore none &&
910 + git config --add -f .gitmodules submodule.subname.path sm &&
911 git config --add submodule.subname.ignore dirty &&
912 git config --add submodule.subname.path sm &&
913 git status > output &&
914 test_cmp expect output &&
883 - git config --remove-section submodule.subname
915 + git config --remove-section submodule.subname &&
916 + git config -f .gitmodules --remove-section submodule.subname
917 '
918
919 cat > expect << EOF
@@ -920,12 +953,23 @@ test_expect_success "--ignore-submodules=untracked doesn't suppress submodules w
953 test_cmp expect output
954 '
955
956 +test_expect_success ".gitmodules ignore=untracked doesn't suppress submodules with modified content" '
957 + git config --add -f .gitmodules submodule.subname.ignore untracked &&
958 + git config --add -f .gitmodules submodule.subname.path sm &&
959 + git status > output &&
960 + test_cmp expect output &&
961 + git config -f .gitmodules --remove-section submodule.subname
962 +'
963 +
964 test_expect_success ".git/config ignore=untracked doesn't suppress submodules with modified content" '
965 + git config --add -f .gitmodules submodule.subname.ignore none &&
966 + git config --add -f .gitmodules submodule.subname.path sm &&
967 git config --add submodule.subname.ignore untracked &&
968 git config --add submodule.subname.path sm &&
969 git status > output &&
970 test_cmp expect output &&
928 - git config --remove-section submodule.subname
971 + git config --remove-section submodule.subname &&
972 + git config -f .gitmodules --remove-section submodule.subname
973 '
974
975 head2=$(cd sm && git commit -q -m "2nd commit" foo && git rev-parse --short=7 --verify HEAD)
@@ -971,28 +1015,48 @@ test_expect_success "--ignore-submodules=untracked doesn't suppress submodule su
1015 test_cmp expect output
1016 '
1017
1018 +test_expect_success ".gitmodules ignore=untracked doesn't suppress submodule summary" '
1019 + git config --add -f .gitmodules submodule.subname.ignore untracked &&
1020 + git config --add -f .gitmodules submodule.subname.path sm &&
1021 + git status > output &&
1022 + test_cmp expect output &&
1023 + git config -f .gitmodules --remove-section submodule.subname
1024 +'
1025 +
1026 test_expect_success ".git/config ignore=untracked doesn't suppress submodule summary" '
1027 + git config --add -f .gitmodules submodule.subname.ignore none &&
1028 + git config --add -f .gitmodules submodule.subname.path sm &&
1029 git config --add submodule.subname.ignore untracked &&
1030 git config --add submodule.subname.path sm &&
1031 git status > output &&
1032 test_cmp expect output &&
979 - git config --remove-section submodule.subname
1033 + git config --remove-section submodule.subname &&
1034 + git config -f .gitmodules --remove-section submodule.subname
1035 '
1036
1037 test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
1038 git status --ignore-submodules=dirty > output &&
1039 test_cmp expect output
1040 '
1041 +test_expect_success ".gitmodules ignore=dirty doesn't suppress submodule summary" '
1042 + git config --add -f .gitmodules submodule.subname.ignore dirty &&
1043 + git config --add -f .gitmodules submodule.subname.path sm &&
1044 + git status > output &&
1045 + test_cmp expect output &&
1046 + git config -f .gitmodules --remove-section submodule.subname
1047 +'
1048
1049 test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary" '
1050 + git config --add -f .gitmodules submodule.subname.ignore none &&
1051 + git config --add -f .gitmodules submodule.subname.path sm &&
1052 git config --add submodule.subname.ignore dirty &&
1053 git config --add submodule.subname.path sm &&
1054 git status > output &&
1055 test_cmp expect output &&
992 - git config --remove-section submodule.subname
1056 + git config --remove-section submodule.subname &&
1057 + git config -f .gitmodules --remove-section submodule.subname
1058 '
1059
995 -
1060 cat > expect << EOF
1061 # On branch master
1062 # Changed but not updated:
@@ -1019,12 +1083,23 @@ test_expect_success "--ignore-submodules=all suppresses submodule summary" '
1083 test_cmp expect output
1084 '
1085
1086 +test_expect_failure '.gitmodules ignore=all suppresses submodule summary' '
1087 + git config --add -f .gitmodules submodule.subname.ignore all &&
1088 + git config --add -f .gitmodules submodule.subname.path sm &&
1089 + git status > output &&
1090 + test_cmp expect output &&
1091 + git config -f .gitmodules --remove-section submodule.subname
1092 +'
1093 +
1094 test_expect_failure '.git/config ignore=all suppresses submodule summary' '
1095 + git config --add -f .gitmodules submodule.subname.ignore none &&
1096 + git config --add -f .gitmodules submodule.subname.path sm &&
1097 git config --add submodule.subname.ignore all &&
1098 git config --add submodule.subname.path sm &&
1099 git status > output &&
1100 test_cmp expect output &&
1027 - git config --remove-section submodule.subname
1101 + git config --remove-section submodule.subname &&
1102 + git config -f .gitmodules --remove-section submodule.subname
1103 '
1104
1105 test_done