From a87bcd6d47d545402ab80ae71a39531997eb6f6f Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 25 May 2016 15:00:04 -0700 Subject: submodule update: make use of the existing fetch_in_submodule function Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 5a4dec050b..7698102b9c 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -640,7 +640,7 @@ cmd_update() if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 - (sanitize_submodule_env; cd "$sm_path" && git-fetch) || + fetch_in_submodule "$sm_path" || die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" fi remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote) -- cgit v1.3 From abed000acafd8aa86e02bcbb65fc1a8e4f06b8a0 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 26 May 2016 14:59:43 -0700 Subject: submodule update: learn `--[no-]recommend-shallow` option Sometimes the history of a submodule is not considered important by the projects upstream. To make it easier for downstream users, allow a boolean field 'submodule..shallow' in .gitmodules, which can be used to recommend whether upstream considers the history important. This field is honored in the initial clone by default, it can be ignored by giving the `--no-recommend-shallow` option. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 11 +++++++-- builtin/submodule--helper.c | 7 +++++- git-submodule.sh | 9 ++++++- t/t5614-clone-submodules.sh | 52 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) (limited to 'git-submodule.sh') diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 9226c4380c..bf3bb372ee 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -15,8 +15,9 @@ SYNOPSIS 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] ...) 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] - [-f|--force] [--rebase|--merge] [--reference ] - [--depth ] [--recursive] [--jobs ] [--] [...] + [--[no-]recommend-shallow] [-f|--force] [--rebase|--merge] + [--reference ] [--depth ] [--recursive] + [--jobs ] [--] [...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) ] [commit] [--] [...] 'git submodule' [--quiet] foreach [--recursive] @@ -384,6 +385,12 @@ for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully. clone with a history truncated to the specified number of revisions. See linkgit:git-clone[1] +--[no-]recommend-shallow:: + This option is only valid for the update command. + The initial clone of a submodule will use the recommended + `submodule..shallow` as provided by the .gitmodules file + by default. To ignore the suggestions use `--no-recommend-shallow`. + -j :: --jobs :: This option is only valid for the update command. diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 8da263f0b0..ca33408f55 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -581,6 +581,7 @@ struct submodule_update_clone { /* configuration parameters which are passed on to the children */ int quiet; + int recommend_shallow; const char *reference; const char *depth; const char *recursive_prefix; @@ -593,7 +594,7 @@ struct submodule_update_clone { unsigned quickstop : 1; }; #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \ - SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \ + SUBMODULE_UPDATE_STRATEGY_INIT, 0, -1, NULL, NULL, NULL, NULL, \ STRING_LIST_INIT_DUP, 0} @@ -698,6 +699,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, argv_array_push(&child->args, "--quiet"); if (suc->prefix) argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL); + if (suc->recommend_shallow && sub->recommend_shallow == 1) + argv_array_push(&child->args, "--depth=1"); argv_array_pushl(&child->args, "--path", sub->path, NULL); argv_array_pushl(&child->args, "--name", sub->name, NULL); argv_array_pushl(&child->args, "--url", url, NULL); @@ -780,6 +783,8 @@ static int update_clone(int argc, const char **argv, const char *prefix) "specified number of revisions")), OPT_INTEGER('j', "jobs", &max_jobs, N_("parallel jobs")), + OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, + N_("whether the initial clone should follow the shallow recommendation")), OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), OPT_END() }; diff --git a/git-submodule.sh b/git-submodule.sh index 5a4dec050b..42e0e9f63d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b ] [-f|--force] [--name ] [--reference ...] or: $dashless [--quiet] init [--] [...] or: $dashless [--quiet] deinit [-f|--force] (--all| [--] ...) - or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference ] [--recursive] [--] [...] + or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference ] [--recursive] [--] [...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] or: $dashless [--quiet] foreach [--recursive] or: $dashless [--quiet] sync [--recursive] [--] [...]" @@ -559,6 +559,12 @@ cmd_update() --checkout) update="checkout" ;; + --recommend-shallow) + recommend_shallow="--recommend-shallow" + ;; + --no-recommend-shallow) + recommend_shallow="--no-recommend-shallow" + ;; --depth) case "$2" in '') usage ;; esac depth="--depth=$2" @@ -601,6 +607,7 @@ cmd_update() ${update:+--update "$update"} \ ${reference:+--reference "$reference"} \ ${depth:+--depth "$depth"} \ + ${recommend_shallow:+"$recommend_shallow"} \ ${jobs:+$jobs} \ "$@" || echo "#unmatched" } | { diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh index 62044c5a02..32d83e2694 100755 --- a/t/t5614-clone-submodules.sh +++ b/t/t5614-clone-submodules.sh @@ -82,4 +82,56 @@ test_expect_success 'non shallow clone with shallow submodule' ' ) ' +test_expect_success 'clone follows shallow recommendation' ' + test_when_finished "rm -rf super_clone" && + git config -f .gitmodules submodule.sub.shallow true && + git add .gitmodules && + git commit -m "recommed shallow for sub" && + git clone --recurse-submodules --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 4 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 1 lines + ) +' + +test_expect_success 'get unshallow recommended shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git submodule update --init --no-recommend-shallow && + git log --oneline >lines && + test_line_count = 4 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + +test_expect_success 'clone follows non shallow recommendation' ' + test_when_finished "rm -rf super_clone" && + git config -f .gitmodules submodule.sub.shallow false && + git add .gitmodules && + git commit -m "recommed non shallow for sub" && + git clone --recurse-submodules --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 5 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + test_done -- cgit v1.3 From bb9d91b4ed54df7bd970c82971ba2851e6735d72 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 9 Jun 2016 12:06:37 -0700 Subject: submodule update: continue when a clone fails In 15ffb7cde48 (2011-06-13, submodule update: continue when a checkout fails), we reasoned it is ok to continue, when there is not much of a mental burden by the failure. If a recursive submodule fails to clone because a .gitmodules file is broken (e.g. : fatal: No url found for submodule path 'foo/bar' in .gitmodules Failed to recurse into submodule path 'foo', signaled by exit code 128), this is one of the cases where the user is not expected to have much of a burden afterwards, so we can also continue in that case. This means we only want to stop for updating submodules in case of rebase, merge or custom update command failures, which are all signaled with exit code 2. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 42e0e9f63d..f1919ca16f 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -734,7 +734,7 @@ cmd_update() if test $res -gt 0 then die_msg="$(eval_gettext "Failed to recurse into submodule path '\$displaypath'")" - if test $res -eq 1 + if test $res -ne 2 then err="${err};$die_msg" continue -- cgit v1.3 From d323c6b6410dee0a8a2471b4dbf6d631cd3c3d4d Mon Sep 17 00:00:00 2001 From: Vasco Almeida Date: Fri, 17 Jun 2016 20:21:02 +0000 Subject: i18n: git-sh-setup.sh: mark strings for translation Positional arguments, such as $0, $1, etc, need to be stored on shell variables for use in translatable strings, according to gettext manual [1]. Add git-sh-setup.sh to LOCALIZED_SH variable in Makefile to enable extraction of string marked for translation by xgettext. Source git-sh-i18n in git-sh-setup.sh for gettext support. git-sh-setup.sh is a shell library to be sourced by other shell scripts. In order to avoid other scripts from sourcing git-sh-i18n twice, remove line that sources it from them. Not sourcing git-sh-i18n in any script that uses gettext would lead to failure due to, for instance, gettextln not being found. [1] http://www.gnu.org/software/gettext/manual/html_node/Preparing-Shell-Scripts.html Signed-off-by: Vasco Almeida Signed-off-by: Junio C Hamano --- Makefile | 4 +++- git-bisect.sh | 1 - git-merge-octopus.sh | 1 - git-rebase.sh | 1 - git-sh-setup.sh | 63 +++++++++++++++++++++++++++++++++++++++------------- git-stash.sh | 1 - git-submodule.sh | 1 - 7 files changed, 50 insertions(+), 22 deletions(-) (limited to 'git-submodule.sh') diff --git a/Makefile b/Makefile index 0d59718bf7..4e0c4ebf5e 100644 --- a/Makefile +++ b/Makefile @@ -2062,7 +2062,9 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh +LOCALIZED_SH = $(SCRIPT_SH) +LOCALIZED_SH += git-parse-remote.sh +LOCALIZED_SH += git-sh-setup.sh LOCALIZED_PERL = $(SCRIPT_PERL) ifdef XGETTEXT_INCLUDE_TESTS diff --git a/git-bisect.sh b/git-bisect.sh index 737bf05127..30d01bb2dc 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -33,7 +33,6 @@ Please use "git help bisect" to get the full man page.' OPTIONS_SPEC= . git-sh-setup -. git-sh-i18n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index d79fc84029..308eafd1d3 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -6,7 +6,6 @@ # . git-sh-setup -. git-sh-i18n LF=' ' diff --git a/git-rebase.sh b/git-rebase.sh index 9ba21ab6a1..04f6e44bc8 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -45,7 +45,6 @@ skip! skip current patch and continue edit-todo! edit the todo list during an interactive rebase " . git-sh-setup -. git-sh-i18n set_reflog_action rebase require_work_tree_exists cd_to_toplevel diff --git a/git-sh-setup.sh b/git-sh-setup.sh index c48139a494..2eda134800 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -2,6 +2,9 @@ # to set up some variables pointing at the normal git directories and # a few helper shell functions. +# Source git-sh-i18n for gettext support. +. git-sh-i18n + # Having this variable in your environment would break scripts because # you would cause "cd" to be taken to unexpected places. If you # like CDPATH, define it for your interactive shell sessions without @@ -83,16 +86,16 @@ if test -n "$OPTIONS_SPEC"; then else dashless=$(basename -- "$0" | sed -e 's/-/ /') usage() { - die "usage: $dashless $USAGE" + die "$(eval_gettext "usage: \$dashless \$USAGE")" } if [ -z "$LONG_USAGE" ] then - LONG_USAGE="usage: $dashless $USAGE" + LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE")" else - LONG_USAGE="usage: $dashless $USAGE + LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE -$LONG_USAGE" +$LONG_USAGE")" fi case "$1" in @@ -182,7 +185,7 @@ is_bare_repository () { cd_to_toplevel () { cdup=$(git rev-parse --show-toplevel) && cd "$cdup" || { - echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" + gettextln "Cannot chdir to \$cdup, the toplevel of the working tree" >&2 exit 1 } } @@ -190,13 +193,16 @@ cd_to_toplevel () { require_work_tree_exists () { if test "z$(git rev-parse --is-bare-repository)" != zfalse then - die "fatal: $0 cannot be used without a working tree." + program_name=$0 + die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" fi } require_work_tree () { - test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || - die "fatal: $0 cannot be used without a working tree." + test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || { + program_name=$0 + die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" + } } require_clean_work_tree () { @@ -206,24 +212,49 @@ require_clean_work_tree () { if ! git diff-files --quiet --ignore-submodules then - echo >&2 "Cannot $1: You have unstaged changes." + action=$1 + case "$action" in + rebase) + gettextln "Cannot rebase: You have unstaged changes." >&2 + ;; + "rewrite branches") + gettextln "Cannot rewrite branches: You have unstaged changes." >&2 + ;; + "pull with rebase") + gettextln "Cannot pull with rebase: You have unstaged changes." >&2 + ;; + *) + eval_gettextln "Cannot \$action: You have unstaged changes." >&2 + ;; + esac err=1 fi if ! git diff-index --cached --quiet --ignore-submodules HEAD -- then - if [ $err = 0 ] + if test $err = 0 then - echo >&2 "Cannot $1: Your index contains uncommitted changes." + action=$1 + case "$action" in + rebase) + gettextln "Cannot rebase: Your index contains uncommitted changes." >&2 + ;; + "pull with rebase") + gettextln "Cannot pull with rebase: Your index contains uncommitted changes." >&2 + ;; + *) + eval_gettextln "Cannot \$action: Your index contains uncommitted changes." >&2 + ;; + esac else - echo >&2 "Additionally, your index contains uncommitted changes." + gettextln "Additionally, your index contains uncommitted changes." >&2 fi err=1 fi - if [ $err = 1 ] + if test $err = 1 then - test -n "$2" && echo >&2 "$2" + test -n "$2" && echo "$2" >&2 exit 1 fi } @@ -336,12 +367,12 @@ git_dir_init () { then test -z "$(git rev-parse --show-cdup)" || { exit=$? - echo >&2 "You need to run this command from the toplevel of the working tree." + gettextln "You need to run this command from the toplevel of the working tree." >&2 exit $exit } fi test -n "$GIT_DIR" && GIT_DIR=$(cd "$GIT_DIR" && pwd) || { - echo >&2 "Unable to determine absolute path of git directory" + gettextln "Unable to determine absolute path of git directory" >&2 exit 1 } : ${GIT_OBJECT_DIRECTORY="$(git rev-parse --git-path objects)"} diff --git a/git-stash.sh b/git-stash.sh index c7509e8da4..22fb8bcba6 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -15,7 +15,6 @@ SUBDIRECTORY_OK=Yes OPTIONS_SPEC= START_DIR=$(pwd) . git-sh-setup -. git-sh-i18n require_work_tree cd_to_toplevel diff --git a/git-submodule.sh b/git-submodule.sh index 5a4dec050b..de7ddb67e4 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -16,7 +16,6 @@ USAGE="[--quiet] add [-b ] [-f|--force] [--name ] [--reference Date: Fri, 17 Jun 2016 21:54:12 +0000 Subject: i18n: submodule: join strings marked for translation Join strings marked for translation since that would facilitate and improve translations result. Signed-off-by: Vasco Almeida Signed-off-by: Junio C Hamano --- git-submodule.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index de7ddb67e4..5c7d251977 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -274,14 +274,15 @@ Use -f if you really want to add it." >&2 then if test -z "$force" then - echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")" + eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):" GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^," ", -e s,' (fetch)',, >&2 - echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")" - echo >&2 " $realrepo" - echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")" - die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")" + die "$(eval_gettextln "\ +If you want to reuse this local git directory instead of cloning again from + \$realrepo +use the '--force' option. If the local git directory is not the correct repo +or you are unsure what this means choose another name with the '--name' option.")" else - echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" + eval_gettextln "Reactivating local git directory for submodule '\$sm_name'." fi fi git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${depth:+"$depth"} || exit @@ -466,8 +467,9 @@ cmd_deinit() # Protect submodules containing a .git directory if test -d "$sm_path/.git" then - echo >&2 "$(eval_gettext "Submodule work tree '\$displaypath' contains a .git directory")" - die "$(eval_gettext "(use 'rm -rf' if you really want to remove it including all of its history)")" + die "$(eval_gettext "\ +Submodule work tree '\$displaypath' contains a .git directory +(use 'rm -rf' if you really want to remove it including all of its history)")" fi if test -z "$force" -- cgit v1.3 From c87302bfe4ca0a861004eaa5e67f011446afea74 Mon Sep 17 00:00:00 2001 From: Vasco Almeida Date: Fri, 17 Jun 2016 21:54:13 +0000 Subject: i18n: submodule: escape shell variables inside eval_gettext According to the gettext manual [1], references to shell variables inside eval_gettext call must be escaped so that eval_gettext receives the translatable string before the variable values are substituted into it. [1] http://www.gnu.org/software/gettext/manual/html_node/Preparing-Shell-Scripts.html Signed-off-by: Vasco Almeida Signed-off-by: Junio C Hamano --- git-submodule.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 5c7d251977..37c61f1652 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -647,7 +647,7 @@ cmd_update() remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote) sha1=$(sanitize_submodule_env; cd "$sm_path" && git rev-parse --verify "${remote_name}/${branch}") || - die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")" + die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" fi if test "$subsha1" != "$sha1" || test -n "$force" @@ -671,7 +671,7 @@ cmd_update() # not be reachable from any of the refs is_tip_reachable "$sm_path" "$sha1" || fetch_in_submodule "$sm_path" "$sha1" || - die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain $sha1. Direct fetching of that commit failed.")" + die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")" fi must_die_on_failure= -- cgit v1.3 From c4c02bf16c47f8751958458e540269ec13f4bd98 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 22 Jul 2016 21:14:38 +0200 Subject: git-submodule: forward exit code of git-submodule--helper more faithfully git-submodule--helper is invoked as the upstream of a pipe in several places. Usually, the failure of a program in this position is not detected by the shell. For this reason, the code inserts a token in the output stream when git-submodule--helper fails that is detected downstream, where the shell script is quit with exit code 1. There happens to be a bug in git-submodule--helper that leads to a segmentation fault. The test suite triggers the crash in several places, all of which are protected by 'test_must_fail'. But due to the inspecific exit code 1, the crash remains undiagnosed. Extend the failure protocol such that git-submodule--helper's exit code is passed downstream (only in the case of failure). This enables the downstream to use it as its own exit code, and 'test_must_fail' to identify the segmentation fault as an unexpected failure. The bug itself is fixed in the next commit. Signed-off-by: Johannes Sixt Acked-by: Stefan Beller Signed-off-by: Junio C Hamano --- git-submodule.sh | 22 +++++++++++----------- t/t5815-submodule-protos.sh | 4 ++-- t/t7400-submodule-basic.sh | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 7c62b53cc0..d8765361c5 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -50,7 +50,7 @@ die_if_unmatched () { if test "$1" = "#unmatched" then - exit 1 + exit ${2:-1} fi } @@ -312,11 +312,11 @@ cmd_foreach() { git submodule--helper list --prefix "$wt_prefix" || - echo "#unmatched" + echo "#unmatched" $? } | while read mode sha1 stage sm_path do - die_if_unmatched "$mode" + die_if_unmatched "$mode" "$sha1" if test -e "$sm_path"/.git then displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") @@ -423,11 +423,11 @@ cmd_deinit() { git submodule--helper list --prefix "$wt_prefix" "$@" || - echo "#unmatched" + echo "#unmatched" $? } | while read mode sha1 stage sm_path do - die_if_unmatched "$mode" + die_if_unmatched "$mode" "$sha1" name=$(git submodule--helper name "$sm_path") || exit displaypath=$(git submodule--helper relative-path "$sm_path" "$wt_prefix") @@ -580,12 +580,12 @@ cmd_update() ${depth:+--depth "$depth"} \ ${recommend_shallow:+"$recommend_shallow"} \ ${jobs:+$jobs} \ - "$@" || echo "#unmatched" + "$@" || echo "#unmatched" $? } | { err= while read mode sha1 stage just_cloned sm_path do - die_if_unmatched "$mode" + die_if_unmatched "$mode" "$sha1" name=$(git submodule--helper name "$sm_path") || exit url=$(git config submodule."$name".url) @@ -993,11 +993,11 @@ cmd_status() { git submodule--helper list --prefix "$wt_prefix" "$@" || - echo "#unmatched" + echo "#unmatched" $? } | while read mode sha1 stage sm_path do - die_if_unmatched "$mode" + die_if_unmatched "$mode" "$sha1" name=$(git submodule--helper name "$sm_path") || exit url=$(git config submodule."$name".url) displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix") @@ -1074,11 +1074,11 @@ cmd_sync() cd_to_toplevel { git submodule--helper list --prefix "$wt_prefix" "$@" || - echo "#unmatched" + echo "#unmatched" $? } | while read mode sha1 stage sm_path do - die_if_unmatched "$mode" + die_if_unmatched "$mode" "$sha1" name=$(git submodule--helper name "$sm_path") url=$(git config -f .gitmodules --get submodule."$name".url) diff --git a/t/t5815-submodule-protos.sh b/t/t5815-submodule-protos.sh index 06f55a1b8a..112cf40233 100755 --- a/t/t5815-submodule-protos.sh +++ b/t/t5815-submodule-protos.sh @@ -18,7 +18,7 @@ test_expect_success 'setup repository with submodules' ' git commit -m "add submodules" ' -test_expect_success 'clone with recurse-submodules fails' ' +test_expect_failure 'clone with recurse-submodules fails' ' test_must_fail git clone --recurse-submodules . dst ' @@ -32,7 +32,7 @@ test_expect_success 'update of ssh allowed' ' git -C dst submodule update ssh-module ' -test_expect_success 'update of ext not allowed' ' +test_expect_failure 'update of ext not allowed' ' test_must_fail git -C dst submodule update ext-module ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 3570f7bb8c..fba2659a22 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -352,7 +352,7 @@ test_expect_success 'sync should fail with unknown submodule' ' test_failure_with_unknown_submodule sync ' -test_expect_success 'update should fail when path is used by a file' ' +test_expect_failure 'update should fail when path is used by a file' ' echo hello >expect && echo "hello" >init && @@ -361,7 +361,7 @@ test_expect_success 'update should fail when path is used by a file' ' test_cmp expect init ' -test_expect_success 'update should fail when path is used by a nonempty directory' ' +test_expect_failure 'update should fail when path is used by a nonempty directory' ' echo hello >expect && rm -fr init && -- cgit v1.3 From 6cbf454a2eaa016efff04bd696dc1ec24b515c11 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 28 Jul 2016 17:44:04 -0700 Subject: submodule update: respect depth in subsequent fetches When depth is given the user may have a reasonable expectation that any remote operation is using the given depth. Add a test to demonstrate we still get the desired sha1 even if the depth is too short to include the actual commit. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- git-submodule.sh | 9 +++++---- t/t7406-submodule-update.sh | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 2b23ce6e25..40639ee231 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -479,7 +479,8 @@ fetch_in_submodule () ( '') git fetch ;; *) - git fetch $(get_default_remote) "$2" ;; + shift + git fetch $(get_default_remote) "$@" ;; esac ) @@ -617,7 +618,7 @@ cmd_update() if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 - fetch_in_submodule "$sm_path" || + fetch_in_submodule "$sm_path" $depth || die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" fi remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote) @@ -640,13 +641,13 @@ cmd_update() # Run fetch only if $sha1 isn't present or it # is not reachable from a ref. is_tip_reachable "$sm_path" "$sha1" || - fetch_in_submodule "$sm_path" || + fetch_in_submodule "$sm_path" $depth || die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")" # Now we tried the usual fetch, but $sha1 may # not be reachable from any of the refs is_tip_reachable "$sm_path" "$sha1" || - fetch_in_submodule "$sm_path" "$sha1" || + fetch_in_submodule "$sm_path" $depth "$sha1" || die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")" fi diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 8fc3a25c46..1bb1f43824 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -856,6 +856,22 @@ test_expect_success 'submodule update clone shallow submodule' ' ) ' +test_expect_success 'submodule update clone shallow submodule outside of depth' ' + test_when_finished "rm -rf super3" && + git clone cloned super3 && + pwd=$(pwd) && + ( + cd super3 && + sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp && + mv -f .gitmodules.tmp .gitmodules && + test_must_fail git submodule update --init --depth=1 2>actual && + test_i18ngrep "Direct fetching of that commit failed." actual && + git -C ../submodule config uploadpack.allowReachableSHA1InWant true && + git submodule update --init --depth=1 >actual && + test 1 = $(git -C submodule log --oneline | wc -l) + ) +' + test_expect_success 'submodule update --recursive drops module name before recursing' ' (cd super2 && (cd deeper/submodule/subsubmodule && -- cgit v1.3 From 341238ebc4c95a351db2e047a0ca2340766b48e8 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Thu, 28 Jul 2016 17:44:05 -0700 Subject: submodule update: narrow scope of local variable Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- git-submodule.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-submodule.sh') diff --git a/git-submodule.sh b/git-submodule.sh index 40639ee231..41aff65fac 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -589,7 +589,6 @@ cmd_update() name=$(git submodule--helper name "$sm_path") || exit url=$(git config submodule."$name".url) - branch=$(get_submodule_config "$name" branch master) if ! test -z "$update" then update_module=$update @@ -615,6 +614,7 @@ cmd_update() if test -n "$remote" then + branch=$(get_submodule_config "$name" branch master) if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 -- cgit v1.3 From 92bbe7ccf1fedac825f2c6ab4c8de91dc5370fd2 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 3 Aug 2016 13:44:03 -0700 Subject: submodule--helper: add remote-branch helper In a later patch we want to enhance the logic for the branch selection. Rewrite the current logic to be in C, so we can directly use C when we enhance the logic. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- builtin/submodule--helper.c | 36 +++++++++++++++++++++++++++++++++++- git-submodule.sh | 2 +- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'git-submodule.sh') diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index fb90c64832..9be2c75e0e 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -899,6 +899,39 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix return 0; } +static const char *remote_submodule_branch(const char *path) +{ + const struct submodule *sub; + gitmodules_config(); + git_config(submodule_config, NULL); + + sub = submodule_from_path(null_sha1, path); + if (!sub) + return NULL; + + if (!sub->branch) + return "master"; + + return sub->branch; +} + +static int resolve_remote_submodule_branch(int argc, const char **argv, + const char *prefix) +{ + const char *ret; + struct strbuf sb = STRBUF_INIT; + if (argc != 2) + die("submodule--helper remote-branch takes exactly one arguments, got %d", argc); + + ret = remote_submodule_branch(argv[1]); + if (!ret) + die("submodule %s doesn't exist", argv[1]); + + printf("%s", ret); + strbuf_release(&sb); + return 0; +} + struct cmd_struct { const char *cmd; int (*fn)(int, const char **, const char *); @@ -912,7 +945,8 @@ static struct cmd_struct commands[] = { {"relative-path", resolve_relative_path}, {"resolve-relative-url", resolve_relative_url}, {"resolve-relative-url-test", resolve_relative_url_test}, - {"init", module_init} + {"init", module_init}, + {"remote-branch", resolve_remote_submodule_branch} }; int cmd_submodule__helper(int argc, const char **argv, const char *prefix) diff --git a/git-submodule.sh b/git-submodule.sh index 41aff65fac..8c5e8982ab 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -614,7 +614,7 @@ cmd_update() if test -n "$remote" then - branch=$(get_submodule_config "$name" branch master) + branch=$(git submodule--helper remote-branch "$sm_path") if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 -- cgit v1.3