Skip to content

Commit 11b5395

Browse files
committed
Merge branch 'sb/submodule-update-dot-branch'
A few updates to "git submodule update". Use of "| wc -l" break with BSD variant of 'wc'. * sb/submodule-update-dot-branch: t7406: fix breakage on OSX submodule update: allow '.' for branch value submodule--helper: add remote-branch helper submodule-config: keep configured branch around submodule--helper: fix usage string for relative-path submodule update: narrow scope of local variable submodule update: respect depth in subsequent fetches t7406: future proof tests with hard coded depth
2 parents 1a5f1a3 + 967d7f8 commit 11b5395

File tree

5 files changed

+132
-17
lines changed

5 files changed

+132
-17
lines changed

builtin/submodule--helper.c

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,13 +892,64 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix
892892
{
893893
struct strbuf sb = STRBUF_INIT;
894894
if (argc != 3)
895-
die("submodule--helper relative_path takes exactly 2 arguments, got %d", argc);
895+
die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc);
896896

897897
printf("%s", relative_path(argv[1], argv[2], &sb));
898898
strbuf_release(&sb);
899899
return 0;
900900
}
901901

902+
static const char *remote_submodule_branch(const char *path)
903+
{
904+
const struct submodule *sub;
905+
gitmodules_config();
906+
git_config(submodule_config, NULL);
907+
908+
sub = submodule_from_path(null_sha1, path);
909+
if (!sub)
910+
return NULL;
911+
912+
if (!sub->branch)
913+
return "master";
914+
915+
if (!strcmp(sub->branch, ".")) {
916+
unsigned char sha1[20];
917+
const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
918+
919+
if (!refname)
920+
die(_("No such ref: %s"), "HEAD");
921+
922+
/* detached HEAD */
923+
if (!strcmp(refname, "HEAD"))
924+
die(_("Submodule (%s) branch configured to inherit "
925+
"branch from superproject, but the superproject "
926+
"is not on any branch"), sub->name);
927+
928+
if (!skip_prefix(refname, "refs/heads/", &refname))
929+
die(_("Expecting a full ref name, got %s"), refname);
930+
return refname;
931+
}
932+
933+
return sub->branch;
934+
}
935+
936+
static int resolve_remote_submodule_branch(int argc, const char **argv,
937+
const char *prefix)
938+
{
939+
const char *ret;
940+
struct strbuf sb = STRBUF_INIT;
941+
if (argc != 2)
942+
die("submodule--helper remote-branch takes exactly one arguments, got %d", argc);
943+
944+
ret = remote_submodule_branch(argv[1]);
945+
if (!ret)
946+
die("submodule %s doesn't exist", argv[1]);
947+
948+
printf("%s", ret);
949+
strbuf_release(&sb);
950+
return 0;
951+
}
952+
902953
struct cmd_struct {
903954
const char *cmd;
904955
int (*fn)(int, const char **, const char *);
@@ -912,7 +963,8 @@ static struct cmd_struct commands[] = {
912963
{"relative-path", resolve_relative_path},
913964
{"resolve-relative-url", resolve_relative_url},
914965
{"resolve-relative-url-test", resolve_relative_url_test},
915-
{"init", module_init}
966+
{"init", module_init},
967+
{"remote-branch", resolve_remote_submodule_branch}
916968
};
917969

918970
int cmd_submodule__helper(int argc, const char **argv, const char *prefix)

git-submodule.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ fetch_in_submodule () (
479479
'')
480480
git fetch ;;
481481
*)
482-
git fetch $(get_default_remote) "$2" ;;
482+
shift
483+
git fetch $(get_default_remote) "$@" ;;
483484
esac
484485
)
485486

@@ -588,7 +589,6 @@ cmd_update()
588589

589590
name=$(git submodule--helper name "$sm_path") || exit
590591
url=$(git config submodule."$name".url)
591-
branch=$(get_submodule_config "$name" branch master)
592592
if ! test -z "$update"
593593
then
594594
update_module=$update
@@ -614,10 +614,11 @@ cmd_update()
614614

615615
if test -n "$remote"
616616
then
617+
branch=$(git submodule--helper remote-branch "$sm_path")
617618
if test -z "$nofetch"
618619
then
619620
# Fetch remote before determining tracking $sha1
620-
fetch_in_submodule "$sm_path" ||
621+
fetch_in_submodule "$sm_path" $depth ||
621622
die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
622623
fi
623624
remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
@@ -640,13 +641,13 @@ cmd_update()
640641
# Run fetch only if $sha1 isn't present or it
641642
# is not reachable from a ref.
642643
is_tip_reachable "$sm_path" "$sha1" ||
643-
fetch_in_submodule "$sm_path" ||
644+
fetch_in_submodule "$sm_path" $depth ||
644645
die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
645646

646647
# Now we tried the usual fetch, but $sha1 may
647648
# not be reachable from any of the refs
648649
is_tip_reachable "$sm_path" "$sha1" ||
649-
fetch_in_submodule "$sm_path" "$sha1" ||
650+
fetch_in_submodule "$sm_path" $depth "$sha1" ||
650651
die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")"
651652
fi
652653

submodule-config.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static void free_one_config(struct submodule_entry *entry)
5959
{
6060
free((void *) entry->config->path);
6161
free((void *) entry->config->name);
62+
free((void *) entry->config->branch);
6263
free((void *) entry->config->update_strategy.command);
6364
free(entry->config);
6465
}
@@ -199,6 +200,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
199200
submodule->update_strategy.command = NULL;
200201
submodule->fetch_recurse = RECURSE_SUBMODULES_NONE;
201202
submodule->ignore = NULL;
203+
submodule->branch = NULL;
202204
submodule->recommend_shallow = -1;
203205

204206
hashcpy(submodule->gitmodules_sha1, gitmodules_sha1);
@@ -358,9 +360,16 @@ static int parse_config(const char *var, const char *value, void *data)
358360
if (!me->overwrite && submodule->recommend_shallow != -1)
359361
warn_multiple_config(me->commit_sha1, submodule->name,
360362
"shallow");
361-
else {
363+
else
362364
submodule->recommend_shallow =
363365
git_config_bool(var, value);
366+
} else if (!strcmp(item.buf, "branch")) {
367+
if (!me->overwrite && submodule->branch)
368+
warn_multiple_config(me->commit_sha1, submodule->name,
369+
"branch");
370+
else {
371+
free((void *)submodule->branch);
372+
submodule->branch = xstrdup(value);
364373
}
365374
}
366375

submodule-config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct submodule {
1515
const char *url;
1616
int fetch_recurse;
1717
const char *ignore;
18+
const char *branch;
1819
struct submodule_update_strategy update_strategy;
1920
/* the sha1 blob id of the responsible .gitmodules file */
2021
unsigned char gitmodules_sha1[20];

t/t7406-submodule-update.sh

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,42 @@ test_expect_success 'submodule update --remote should fetch upstream changes' '
209209
)
210210
'
211211

212+
test_expect_success 'submodule update --remote should fetch upstream changes with .' '
213+
(
214+
cd super &&
215+
git config -f .gitmodules submodule."submodule".branch "." &&
216+
git add .gitmodules &&
217+
git commit -m "submodules: update from the respective superproject branch"
218+
) &&
219+
(
220+
cd submodule &&
221+
echo line4a >> file &&
222+
git add file &&
223+
test_tick &&
224+
git commit -m "upstream line4a" &&
225+
git checkout -b test-branch &&
226+
test_commit on-test-branch
227+
) &&
228+
(
229+
cd super &&
230+
git submodule update --remote --force submodule &&
231+
git -C submodule log -1 --oneline >actual
232+
git -C ../submodule log -1 --oneline master >expect
233+
test_cmp expect actual &&
234+
git checkout -b test-branch &&
235+
git submodule update --remote --force submodule &&
236+
git -C submodule log -1 --oneline >actual
237+
git -C ../submodule log -1 --oneline test-branch >expect
238+
test_cmp expect actual &&
239+
git checkout master &&
240+
git branch -d test-branch &&
241+
git reset --hard HEAD^
242+
)
243+
'
244+
212245
test_expect_success 'local config should override .gitmodules branch' '
213246
(cd submodule &&
214-
git checkout -b test-branch &&
247+
git checkout test-branch &&
215248
echo line5 >> file &&
216249
git add file &&
217250
test_tick &&
@@ -841,16 +874,35 @@ test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd'
841874
'
842875

843876
test_expect_success 'submodule update clone shallow submodule' '
877+
test_when_finished "rm -rf super3" &&
878+
first=$(git -C cloned submodule status submodule |cut -c2-41) &&
879+
second=$(git -C submodule rev-parse HEAD) &&
880+
commit_count=$(git -C submodule rev-list --count $first^..$second) &&
844881
git clone cloned super3 &&
845882
pwd=$(pwd) &&
846-
(cd super3 &&
847-
sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
848-
mv -f .gitmodules.tmp .gitmodules &&
849-
git submodule update --init --depth=3
850-
(cd submodule &&
851-
test 1 = $(git log --oneline | wc -l)
852-
)
853-
)
883+
(
884+
cd super3 &&
885+
sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
886+
mv -f .gitmodules.tmp .gitmodules &&
887+
git submodule update --init --depth=$commit_count &&
888+
test 1 = $(git -C submodule log --oneline | wc -l)
889+
)
890+
'
891+
892+
test_expect_success 'submodule update clone shallow submodule outside of depth' '
893+
test_when_finished "rm -rf super3" &&
894+
git clone cloned super3 &&
895+
pwd=$(pwd) &&
896+
(
897+
cd super3 &&
898+
sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
899+
mv -f .gitmodules.tmp .gitmodules &&
900+
test_must_fail git submodule update --init --depth=1 2>actual &&
901+
test_i18ngrep "Direct fetching of that commit failed." actual &&
902+
git -C ../submodule config uploadpack.allowReachableSHA1InWant true &&
903+
git submodule update --init --depth=1 >actual &&
904+
test 1 = $(git -C submodule log --oneline | wc -l)
905+
)
854906
'
855907

856908
test_expect_success 'submodule update --recursive drops module name before recursing' '

0 commit comments

Comments
 (0)