Skip to content
/ git Public
forked from git/git

Commit

Permalink
Merge branch 'sb/submodule-update-dot-branch'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Aug 10, 2016
2 parents 1a5f1a3 + 967d7f8 commit 11b5395
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 17 deletions.
56 changes: 54 additions & 2 deletions builtin/submodule--helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,13 +892,64 @@ static int resolve_relative_path(int argc, const char **argv, const char *prefix
{
struct strbuf sb = STRBUF_INIT;
if (argc != 3)
die("submodule--helper relative_path takes exactly 2 arguments, got %d", argc);
die("submodule--helper relative-path takes exactly 2 arguments, got %d", argc);

printf("%s", relative_path(argv[1], argv[2], &sb));
strbuf_release(&sb);
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";

if (!strcmp(sub->branch, ".")) {
unsigned char sha1[20];
const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL);

if (!refname)
die(_("No such ref: %s"), "HEAD");

/* detached HEAD */
if (!strcmp(refname, "HEAD"))
die(_("Submodule (%s) branch configured to inherit "
"branch from superproject, but the superproject "
"is not on any branch"), sub->name);

if (!skip_prefix(refname, "refs/heads/", &refname))
die(_("Expecting a full ref name, got %s"), refname);
return refname;
}

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 *);
Expand All @@ -912,7 +963,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)
Expand Down
11 changes: 6 additions & 5 deletions git-submodule.sh
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ fetch_in_submodule () (
'')
git fetch ;;
*)
git fetch $(get_default_remote) "$2" ;;
shift
git fetch $(get_default_remote) "$@" ;;
esac
)

Expand Down Expand Up @@ -588,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
Expand All @@ -614,10 +614,11 @@ cmd_update()

if test -n "$remote"
then
branch=$(git submodule--helper remote-branch "$sm_path")
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)
Expand All @@ -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

Expand Down
11 changes: 10 additions & 1 deletion submodule-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ static void free_one_config(struct submodule_entry *entry)
{
free((void *) entry->config->path);
free((void *) entry->config->name);
free((void *) entry->config->branch);
free((void *) entry->config->update_strategy.command);
free(entry->config);
}
Expand Down Expand Up @@ -199,6 +200,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
submodule->update_strategy.command = NULL;
submodule->fetch_recurse = RECURSE_SUBMODULES_NONE;
submodule->ignore = NULL;
submodule->branch = NULL;
submodule->recommend_shallow = -1;

hashcpy(submodule->gitmodules_sha1, gitmodules_sha1);
Expand Down Expand Up @@ -358,9 +360,16 @@ static int parse_config(const char *var, const char *value, void *data)
if (!me->overwrite && submodule->recommend_shallow != -1)
warn_multiple_config(me->commit_sha1, submodule->name,
"shallow");
else {
else
submodule->recommend_shallow =
git_config_bool(var, value);
} else if (!strcmp(item.buf, "branch")) {
if (!me->overwrite && submodule->branch)
warn_multiple_config(me->commit_sha1, submodule->name,
"branch");
else {
free((void *)submodule->branch);
submodule->branch = xstrdup(value);
}
}

Expand Down
1 change: 1 addition & 0 deletions submodule-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct submodule {
const char *url;
int fetch_recurse;
const char *ignore;
const char *branch;
struct submodule_update_strategy update_strategy;
/* the sha1 blob id of the responsible .gitmodules file */
unsigned char gitmodules_sha1[20];
Expand Down
70 changes: 61 additions & 9 deletions t/t7406-submodule-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,42 @@ test_expect_success 'submodule update --remote should fetch upstream changes' '
)
'

test_expect_success 'submodule update --remote should fetch upstream changes with .' '
(
cd super &&
git config -f .gitmodules submodule."submodule".branch "." &&
git add .gitmodules &&
git commit -m "submodules: update from the respective superproject branch"
) &&
(
cd submodule &&
echo line4a >> file &&
git add file &&
test_tick &&
git commit -m "upstream line4a" &&
git checkout -b test-branch &&
test_commit on-test-branch
) &&
(
cd super &&
git submodule update --remote --force submodule &&
git -C submodule log -1 --oneline >actual
git -C ../submodule log -1 --oneline master >expect
test_cmp expect actual &&
git checkout -b test-branch &&
git submodule update --remote --force submodule &&
git -C submodule log -1 --oneline >actual
git -C ../submodule log -1 --oneline test-branch >expect
test_cmp expect actual &&
git checkout master &&
git branch -d test-branch &&
git reset --hard HEAD^
)
'

test_expect_success 'local config should override .gitmodules branch' '
(cd submodule &&
git checkout -b test-branch &&
git checkout test-branch &&
echo line5 >> file &&
git add file &&
test_tick &&
Expand Down Expand Up @@ -841,16 +874,35 @@ test_expect_success SYMLINKS 'submodule update can handle symbolic links in pwd'
'

test_expect_success 'submodule update clone shallow submodule' '
test_when_finished "rm -rf super3" &&
first=$(git -C cloned submodule status submodule |cut -c2-41) &&
second=$(git -C submodule rev-parse HEAD) &&
commit_count=$(git -C submodule rev-list --count $first^..$second) &&
git clone cloned super3 &&
pwd=$(pwd) &&
(cd super3 &&
sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
mv -f .gitmodules.tmp .gitmodules &&
git submodule update --init --depth=3
(cd submodule &&
test 1 = $(git log --oneline | wc -l)
)
)
(
cd super3 &&
sed -e "s#url = ../#url = file://$pwd/#" <.gitmodules >.gitmodules.tmp &&
mv -f .gitmodules.tmp .gitmodules &&
git submodule update --init --depth=$commit_count &&
test 1 = $(git -C submodule log --oneline | wc -l)
)
'

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' '
Expand Down

0 comments on commit 11b5395

Please sign in to comment.