builtin/read-tree: add --recurse-submodules switch

A new known failure mode is introduced[1], which is actually not a failure but a feature in read-tree. Unlike checkout for which the recursive submodule tests were originally written, read-tree does warn about ignored untracked files that would be overwritten. For the sake of keeping the test library for submodules generic, just mark the test as a failure. [1] KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Mar 14, 2017 at 14:46 UTC 25804914fa3661549cb4017fd0d127b9b626fc69
4 files changed +49 -1
Documentation/git-read-tree.txt
+6
@@ -115,6 +115,12 @@ OPTIONS
115 directories the index file and index output file are
116 located in.
117
118 +--[no-]recurse-submodules::
119 + Using --recurse-submodules will update the content of all initialized
120 + submodules according to the commit recorded in the superproject by
121 + calling read-tree recursively, also setting the submodules HEAD to be
122 + detached at that commit.
123 +
124 --no-sparse-checkout::
125 Disable sparse checkout support even if `core.sparseCheckout`
126 is true.
builtin/read-tree.c
+29
@@ -15,10 +15,13 @@
15 #include "builtin.h"
16 #include "parse-options.h"
17 #include "resolve-undo.h"
18 +#include "submodule.h"
19 +#include "submodule-config.h"
20
21 static int nr_trees;
22 static int read_empty;
23 static struct tree *trees[MAX_UNPACK_TREES];
24 +static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
25
26 static int list_tree(unsigned char *sha1)
27 {
@@ -96,6 +99,23 @@ static int debug_merge(const struct cache_entry * const *stages,
99 return 0;
100 }
101
102 +static int option_parse_recurse_submodules(const struct option *opt,
103 + const char *arg, int unset)
104 +{
105 + if (unset) {
106 + recurse_submodules = RECURSE_SUBMODULES_OFF;
107 + return 0;
108 + }
109 + if (arg)
110 + recurse_submodules =
111 + parse_update_recurse_submodules_arg(opt->long_name,
112 + arg);
113 + else
114 + recurse_submodules = RECURSE_SUBMODULES_ON;
115 +
116 + return 0;
117 +}
118 +
119 static struct lock_file lock_file;
120
121 int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
@@ -137,6 +157,9 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
157 N_("skip applying sparse checkout filter")),
158 OPT_BOOL(0, "debug-unpack", &opts.debug_unpack,
159 N_("debug unpack-trees")),
160 + { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
161 + "checkout", "control recursive updating of submodules",
162 + PARSE_OPT_OPTARG, option_parse_recurse_submodules },
163 OPT_END()
164 };
165
@@ -152,6 +175,12 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
175
176 hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
177
178 + if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) {
179 + gitmodules_config();
180 + git_config(submodule_config, NULL);
181 + set_config_update_recurse_submodules(RECURSE_SUBMODULES_ON);
182 + }
183 +
184 prefix_set = opts.prefix ? 1 : 0;
185 if (1 < opts.merge + opts.reset + prefix_set)
186 die("Which one? -m, --reset, or --prefix?");
t/lib-submodule-update.sh
+6 -1
@@ -792,6 +792,11 @@ test_submodule_switch_recursing () {
792 then
793 RESULTR=failure
794 fi
795 + RESULTOI=success
796 + if test "$KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED" = 1
797 + then
798 + RESULTOI=failure
799 + fi
800 ######################### Appearing submodule #########################
801 # Switching to a commit letting a submodule appear checks it out ...
802 test_expect_success "$command: added submodule is checked out" '
@@ -832,7 +837,7 @@ test_submodule_switch_recursing () {
837 )
838 '
839 # ... but an ignored file is fine.
835 - test_expect_success "$command: added submodule removes an untracked ignored file" '
840 + test_expect_$RESULTOI "$command: added submodule removes an untracked ignored file" '
841 test_when_finished "rm submodule_update/.git/info/exclude" &&
842 prolog &&
843 reset_work_tree_to_interested no_submodule &&
t/t1013-read-tree-submodule.sh
+8
@@ -5,6 +5,14 @@ test_description='read-tree can handle submodules'
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-submodule-update.sh
7
8 +KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED=1
9 +KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
10 +KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1
11 +
12 +test_submodule_switch_recursing "git read-tree --recurse-submodules -u -m"
13 +
14 +test_submodule_forced_switch_recursing "git read-tree --recurse-submodules -u --reset"
15 +
16 test_submodule_switch "git read-tree -u -m"
17
18 test_submodule_forced_switch "git read-tree -u --reset"