From 25804914fa3661549cb4017fd0d127b9b626fc69 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Tue, 14 Mar 2017 14:46:42 -0700 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- Documentation/git-read-tree.txt | 6 ++++++ builtin/read-tree.c | 29 +++++++++++++++++++++++++++++ t/lib-submodule-update.sh | 7 ++++++- t/t1013-read-tree-submodule.sh | 8 ++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index fa1d557e5..ed9d63ef4 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -115,6 +115,12 @@ OPTIONS directories the index file and index output file are located in. +--[no-]recurse-submodules:: + Using --recurse-submodules will update the content of all initialized + submodules according to the commit recorded in the superproject by + calling read-tree recursively, also setting the submodules HEAD to be + detached at that commit. + --no-sparse-checkout:: Disable sparse checkout support even if `core.sparseCheckout` is true. diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 8ba64bc78..23e212ee8 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -15,10 +15,13 @@ #include "builtin.h" #include "parse-options.h" #include "resolve-undo.h" +#include "submodule.h" +#include "submodule-config.h" static int nr_trees; static int read_empty; static struct tree *trees[MAX_UNPACK_TREES]; +static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int list_tree(unsigned char *sha1) { @@ -96,6 +99,23 @@ static int debug_merge(const struct cache_entry * const *stages, return 0; } +static int option_parse_recurse_submodules(const struct option *opt, + const char *arg, int unset) +{ + if (unset) { + recurse_submodules = RECURSE_SUBMODULES_OFF; + return 0; + } + if (arg) + recurse_submodules = + parse_update_recurse_submodules_arg(opt->long_name, + arg); + else + recurse_submodules = RECURSE_SUBMODULES_ON; + + return 0; +} + static struct lock_file lock_file; 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) N_("skip applying sparse checkout filter")), OPT_BOOL(0, "debug-unpack", &opts.debug_unpack, N_("debug unpack-trees")), + { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, + "checkout", "control recursive updating of submodules", + PARSE_OPT_OPTARG, option_parse_recurse_submodules }, OPT_END() }; @@ -152,6 +175,12 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); + if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT) { + gitmodules_config(); + git_config(submodule_config, NULL); + set_config_update_recurse_submodules(RECURSE_SUBMODULES_ON); + } + prefix_set = opts.prefix ? 1 : 0; if (1 < opts.merge + opts.reset + prefix_set) die("Which one? -m, --reset, or --prefix?"); diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh index 4e775a38b..fb4f7b014 100755 --- a/t/lib-submodule-update.sh +++ b/t/lib-submodule-update.sh @@ -792,6 +792,11 @@ test_submodule_switch_recursing () { then RESULTR=failure fi + RESULTOI=success + if test "$KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED" = 1 + then + RESULTOI=failure + fi ######################### Appearing submodule ######################### # Switching to a commit letting a submodule appear checks it out ... test_expect_success "$command: added submodule is checked out" ' @@ -832,7 +837,7 @@ test_submodule_switch_recursing () { ) ' # ... but an ignored file is fine. - test_expect_success "$command: added submodule removes an untracked ignored file" ' + test_expect_$RESULTOI "$command: added submodule removes an untracked ignored file" ' test_when_finished "rm submodule_update/.git/info/exclude" && prolog && reset_work_tree_to_interested no_submodule && diff --git a/t/t1013-read-tree-submodule.sh b/t/t1013-read-tree-submodule.sh index 20526aed3..de1ba02dc 100755 --- a/t/t1013-read-tree-submodule.sh +++ b/t/t1013-read-tree-submodule.sh @@ -5,6 +5,14 @@ test_description='read-tree can handle submodules' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh +KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED=1 +KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1 +KNOWN_FAILURE_SUBMODULE_OVERWRITE_IGNORED_UNTRACKED=1 + +test_submodule_switch_recursing "git read-tree --recurse-submodules -u -m" + +test_submodule_forced_switch_recursing "git read-tree --recurse-submodules -u --reset" + test_submodule_switch "git read-tree -u -m" test_submodule_forced_switch "git read-tree -u --reset" -- 2.11.0