Browse Source

submodule: fall back to remote's HEAD for missing remote.<name>.branch

When `remote.<name>.branch` is not configured, `git submodule update`
currently falls back to using the branch name `master`. A much better
idea, however, is to use the remote `HEAD`: on all Git servers running
reasonably recent Git versions, the symref `HEAD` points to the main
branch.

Note: t7419 demonstrates that there _might_ be use cases out there that
_expect_ `git submodule update --remote` to update submodules to the
remote `master` branch even if the remote `HEAD` points to another
branch. Arguably, this patch makes the behavior more intuitive, but
there is a slight possibility that this might cause regressions in
obscure setups.

Even so, it should be okay to fix this behavior without anything like a
longer transition period:

- The `git submodule update --remote` command is not really common.

- Current Git's behavior when running this command is outright
  confusing, unless the remote repository's current branch _is_ `master`
  (in which case the proposed behavior matches the old behavior).

- If a user encounters a regression due to the changed behavior, the fix
  is actually trivial: setting `submodule.<name>.branch` to `master`
  will reinstate the old behavior.

Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Johannes Schindelin 5 years ago committed by Junio C Hamano
parent
commit
f0a96e8d4c
  1. 12
      Documentation/git-submodule.txt
  2. 6
      Documentation/gitmodules.txt
  3. 2
      builtin/submodule--helper.c
  4. 16
      t/t7406-submodule-update.sh
  5. 7
      t/t7419-submodule-set-branch.sh

12
Documentation/git-submodule.txt

@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>::
Sets the default remote tracking branch for the submodule. The Sets the default remote tracking branch for the submodule. The
`--branch` option allows the remote branch to be specified. The `--branch` option allows the remote branch to be specified. The
`--default` option removes the submodule.<name>.branch configuration `--default` option removes the submodule.<name>.branch configuration
key, which causes the tracking branch to default to 'master'. key, which causes the tracking branch to default to the remote 'HEAD'.


set-url [--] <path> <newurl>:: set-url [--] <path> <newurl>::
Sets the URL of the specified submodule to <newurl>. Then, it will Sets the URL of the specified submodule to <newurl>. Then, it will
@ -284,7 +284,7 @@ OPTIONS
`.gitmodules` for `update --remote`. A special value of `.` is used to `.gitmodules` for `update --remote`. A special value of `.` is used to
indicate that the name of the branch in the submodule should be the indicate that the name of the branch in the submodule should be the
same name as the current branch in the current repository. If the same name as the current branch in the current repository. If the
option is not specified, it defaults to 'master'. option is not specified, it defaults to the remote 'HEAD'.


-f:: -f::
--force:: --force::
@ -322,10 +322,10 @@ OPTIONS
the superproject's recorded SHA-1 to update the submodule, use the the superproject's recorded SHA-1 to update the submodule, use the
status of the submodule's remote-tracking branch. The remote used status of the submodule's remote-tracking branch. The remote used
is branch's remote (`branch.<name>.remote`), defaulting to `origin`. is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
The remote branch used defaults to `master`, but the branch name may The remote branch used defaults to the remote `HEAD`, but the branch
be overridden by setting the `submodule.<name>.branch` option in name may be overridden by setting the `submodule.<name>.branch`
either `.gitmodules` or `.git/config` (with `.git/config` taking option in either `.gitmodules` or `.git/config` (with `.git/config`
precedence). taking precedence).
+ +
This works for any of the supported update procedures (`--checkout`, This works for any of the supported update procedures (`--checkout`,
`--rebase`, etc.). The only change is the source of the target SHA-1. `--rebase`, etc.). The only change is the source of the target SHA-1.

6
Documentation/gitmodules.txt

@ -49,9 +49,9 @@ submodule.<name>.update::


submodule.<name>.branch:: submodule.<name>.branch::
A remote branch name for tracking updates in the upstream submodule. A remote branch name for tracking updates in the upstream submodule.
If the option is not specified, it defaults to 'master'. A special If the option is not specified, it defaults to the remote 'HEAD'.
value of `.` is used to indicate that the name of the branch in the A special value of `.` is used to indicate that the name of the branch
submodule should be the same name as the current branch in the in the submodule should be the same name as the current branch in the
current repository. See the `--remote` documentation in current repository. See the `--remote` documentation in
linkgit:git-submodule[1] for details. linkgit:git-submodule[1] for details.



2
builtin/submodule--helper.c

@ -1981,7 +1981,7 @@ static const char *remote_submodule_branch(const char *path)
free(key); free(key);


if (!branch) if (!branch)
return "master"; return "HEAD";


if (!strcmp(branch, ".")) { if (!strcmp(branch, ".")) {
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL); const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);

16
t/t7406-submodule-update.sh

@ -70,6 +70,22 @@ test_expect_success 'setup a submodule tree' '
) )
' '


test_expect_success 'update --remote falls back to using HEAD' '
test_create_repo main-branch-submodule &&
test_commit -C main-branch-submodule initial &&

test_create_repo main-branch &&
git -C main-branch submodule add ../main-branch-submodule &&
git -C main-branch commit -m add-submodule &&

git -C main-branch-submodule switch -c hello &&
test_commit -C main-branch-submodule world &&

git clone --recursive main-branch main-branch-clone &&
git -C main-branch-clone submodule update --remote main-branch-submodule &&
test_path_exists main-branch-clone/main-branch-submodule/world.t
'

test_expect_success 'submodule update detaching the HEAD ' ' test_expect_success 'submodule update detaching the HEAD ' '
(cd super/submodule && (cd super/submodule &&
git reset --hard HEAD~1 git reset --hard HEAD~1

7
t/t7419-submodule-set-branch.sh

@ -52,12 +52,13 @@ test_expect_success 'test submodule set-branch --branch' '
' '


test_expect_success 'test submodule set-branch --default' ' test_expect_success 'test submodule set-branch --default' '
test_commit -C submodule c &&
(cd super && (cd super &&
git submodule set-branch --default submodule && git submodule set-branch --default submodule &&
! grep branch .gitmodules && ! grep branch .gitmodules &&
git submodule update --remote && git submodule update --remote &&
cat <<-\EOF >expect && cat <<-\EOF >expect &&
a c
EOF EOF
git -C submodule show -s --pretty=%s >actual && git -C submodule show -s --pretty=%s >actual &&
test_cmp expect actual test_cmp expect actual
@ -65,6 +66,7 @@ test_expect_success 'test submodule set-branch --default' '
' '


test_expect_success 'test submodule set-branch -b' ' test_expect_success 'test submodule set-branch -b' '
test_commit -C submodule b &&
(cd super && (cd super &&
git submodule set-branch -b topic submodule && git submodule set-branch -b topic submodule &&
grep "branch = topic" .gitmodules && grep "branch = topic" .gitmodules &&
@ -78,12 +80,13 @@ test_expect_success 'test submodule set-branch -b' '
' '


test_expect_success 'test submodule set-branch -d' ' test_expect_success 'test submodule set-branch -d' '
test_commit -C submodule d &&
(cd super && (cd super &&
git submodule set-branch -d submodule && git submodule set-branch -d submodule &&
! grep branch .gitmodules && ! grep branch .gitmodules &&
git submodule update --remote && git submodule update --remote &&
cat <<-\EOF >expect && cat <<-\EOF >expect &&
a d
EOF EOF
git -C submodule show -s --pretty=%s >actual && git -C submodule show -s --pretty=%s >actual &&
test_cmp expect actual test_cmp expect actual

Loading…
Cancel
Save