mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
![Jeff King](/assets/img/avatar_default.png)
In most cases, fetching the remote HEAD explicitly is unnecessary. It's just a symref pointing to a branch which we are already fetching, so we will already ask for its sha1. However, if the remote has a detached HEAD, things are less certain. We do not ask for HEAD's sha1, but we do try to write it into a local detached HEAD. In most cases this is fine, as the remote HEAD is pointing to some part of the history graph that we will fetch via the refs. But if the remote HEAD points to an "orphan" commit (one which was is not an ancestor of any refs), then we will not have the object, and update_ref will complain when we try to write the detached HEAD, aborting the whole clone. This patch makes clone always explicitly ask the remote for the sha1 of its HEAD commit. In the non-detached case, this is a no-op, as we were going to ask for that sha1 anyway. In the regular detached case, this will add an extra "want" to the protocol negotiation, but will not change the history that gets sent. And in the detached orphan case, we will fetch the orphaned history so that we can write it into our local detached HEAD. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
77 lines
1.9 KiB
Bash
Executable file
77 lines
1.9 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='test cloning a repository with detached HEAD'
|
|
. ./test-lib.sh
|
|
|
|
head_is_detached() {
|
|
git --git-dir=$1/.git rev-parse --verify HEAD &&
|
|
test_must_fail git --git-dir=$1/.git symbolic-ref HEAD
|
|
}
|
|
|
|
test_expect_success 'setup' '
|
|
echo one >file &&
|
|
git add file &&
|
|
git commit -m one &&
|
|
echo two >file &&
|
|
git commit -a -m two &&
|
|
git tag two &&
|
|
echo three >file &&
|
|
git commit -a -m three
|
|
'
|
|
|
|
test_expect_success 'clone repo (detached HEAD points to branch)' '
|
|
git checkout master^0 &&
|
|
git clone "file://$PWD" detached-branch
|
|
'
|
|
test_expect_success 'cloned HEAD matches' '
|
|
echo three >expect &&
|
|
git --git-dir=detached-branch/.git log -1 --format=%s >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
test_expect_failure 'cloned HEAD is detached' '
|
|
head_is_detached detached-branch
|
|
'
|
|
|
|
test_expect_success 'clone repo (detached HEAD points to tag)' '
|
|
git checkout two^0 &&
|
|
git clone "file://$PWD" detached-tag
|
|
'
|
|
test_expect_success 'cloned HEAD matches' '
|
|
echo two >expect &&
|
|
git --git-dir=detached-tag/.git log -1 --format=%s >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
test_expect_success 'cloned HEAD is detached' '
|
|
head_is_detached detached-tag
|
|
'
|
|
|
|
test_expect_success 'clone repo (detached HEAD points to history)' '
|
|
git checkout two^ &&
|
|
git clone "file://$PWD" detached-history
|
|
'
|
|
test_expect_success 'cloned HEAD matches' '
|
|
echo one >expect &&
|
|
git --git-dir=detached-history/.git log -1 --format=%s >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
test_expect_success 'cloned HEAD is detached' '
|
|
head_is_detached detached-history
|
|
'
|
|
|
|
test_expect_success 'clone repo (orphan detached HEAD)' '
|
|
git checkout master^0 &&
|
|
echo four >file &&
|
|
git commit -a -m four &&
|
|
git clone "file://$PWD" detached-orphan
|
|
'
|
|
test_expect_success 'cloned HEAD matches' '
|
|
echo four >expect &&
|
|
git --git-dir=detached-orphan/.git log -1 --format=%s >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
test_expect_success 'cloned HEAD is detached' '
|
|
head_is_detached detached-orphan
|
|
'
|
|
|
|
test_done
|