Merge branch 'bf/fetch-set-head-config'

"git fetch" honors "remote.<remote>.followRemoteHEAD" settings to
tweak the remote-tracking HEAD in "refs/remotes/<remote>/HEAD".

* bf/fetch-set-head-config:
  remote set-head: set followRemoteHEAD to "warn" if "always"
  fetch set_head: add warn-if-not-$branch option
  fetch set_head: move warn advice into advise_if_enabled
  fetch: add configuration for set_head behaviour
This commit is contained in:
Junio C Hamano
2024-12-19 10:58:29 -08:00
9 changed files with 258 additions and 7 deletions

View File

@ -98,6 +98,144 @@ test_expect_success "fetch test remote HEAD change" '
branch=$(git rev-parse refs/remotes/origin/other) &&
test "z$head" = "z$branch"'
test_expect_success "fetch test followRemoteHEAD never" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git update-ref --no-deref -d refs/remotes/origin/HEAD &&
git config set remote.origin.followRemoteHEAD "never" &&
git fetch &&
test_must_fail git rev-parse --verify refs/remotes/origin/HEAD
)
'
test_expect_success "fetch test followRemoteHEAD warn no change" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git rev-parse --verify refs/remotes/origin/other &&
git remote set-head origin other &&
git rev-parse --verify refs/remotes/origin/HEAD &&
git rev-parse --verify refs/remotes/origin/main &&
git config set remote.origin.followRemoteHEAD "warn" &&
git fetch >output &&
echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \
"but we have ${SQ}other${SQ} locally." >expect &&
test_cmp expect output &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/other) &&
test "z$head" = "z$branch"
)
'
test_expect_success "fetch test followRemoteHEAD warn create" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git update-ref --no-deref -d refs/remotes/origin/HEAD &&
git config set remote.origin.followRemoteHEAD "warn" &&
git rev-parse --verify refs/remotes/origin/main &&
output=$(git fetch) &&
test "z" = "z$output" &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/main) &&
test "z$head" = "z$branch"
)
'
test_expect_success "fetch test followRemoteHEAD warn detached" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git update-ref --no-deref -d refs/remotes/origin/HEAD &&
git update-ref refs/remotes/origin/HEAD HEAD &&
HEAD=$(git log --pretty="%H") &&
git config set remote.origin.followRemoteHEAD "warn" &&
git fetch >output &&
echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \
"but we have a detached HEAD pointing to" \
"${SQ}${HEAD}${SQ} locally." >expect &&
test_cmp expect output
)
'
test_expect_success "fetch test followRemoteHEAD warn quiet" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git rev-parse --verify refs/remotes/origin/other &&
git remote set-head origin other &&
git rev-parse --verify refs/remotes/origin/HEAD &&
git rev-parse --verify refs/remotes/origin/main &&
git config set remote.origin.followRemoteHEAD "warn" &&
output=$(git fetch --quiet) &&
test "z" = "z$output" &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/other) &&
test "z$head" = "z$branch"
)
'
test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is same" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git rev-parse --verify refs/remotes/origin/other &&
git remote set-head origin other &&
git rev-parse --verify refs/remotes/origin/HEAD &&
git rev-parse --verify refs/remotes/origin/main &&
git config set remote.origin.followRemoteHEAD "warn-if-not-main" &&
actual=$(git fetch) &&
test "z" = "z$actual" &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/other) &&
test "z$head" = "z$branch"
)
'
test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is different" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git rev-parse --verify refs/remotes/origin/other &&
git remote set-head origin other &&
git rev-parse --verify refs/remotes/origin/HEAD &&
git rev-parse --verify refs/remotes/origin/main &&
git config set remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" &&
git fetch >actual &&
echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \
"but we have ${SQ}other${SQ} locally." >expect &&
test_cmp expect actual &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/other) &&
test "z$head" = "z$branch"
)
'
test_expect_success "fetch test followRemoteHEAD always" '
test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
(
cd "$D" &&
cd two &&
git rev-parse --verify refs/remotes/origin/other &&
git remote set-head origin other &&
git rev-parse --verify refs/remotes/origin/HEAD &&
git rev-parse --verify refs/remotes/origin/main &&
git config set remote.origin.followRemoteHEAD "always" &&
git fetch &&
head=$(git rev-parse refs/remotes/origin/HEAD) &&
branch=$(git rev-parse refs/remotes/origin/main) &&
test "z$head" = "z$branch"
)
'
test_expect_success 'fetch --prune on its own works as expected' '
cd "$D" &&
git clone . prune &&