
The git-clone(1) command has the option `--branch` that allows the user to select the branch they want HEAD to point to. In a non-bare repository this also checks out that branch. Option `--branch` also accepts a tag. When a tag name is provided, the commit this tag points to is checked out and HEAD is detached. Thus `--branch` can be used to clone a repository and check out a ref kept under `refs/heads` or `refs/tags`. But some other refs might be in use as well. For example Git forges might use refs like `refs/pull/<id>` and `refs/merge-requests/<id>` to track pull/merge requests. These refs cannot be selected upon git-clone(1). Add option `--revision` to git-clone(1). This option accepts a fully qualified reference, or a hexadecimal commit ID. This enables the user to clone and check out any revision they want. `--revision` can be used in conjunction with `--depth` to do a minimal clone that only contains the blob and tree for a single revision. This can be useful for automated tests running in CI systems. Using option `--branch` and `--single-branch` together is a similar scenario, but serves a different purpose. Using these two options, a singlet remote tracking branch is created and the fetch refspec is set up so git-fetch(1) will receive updates on that branch from the remote. This allows the user work on that single branch. Option `--revision` on contrary detaches HEAD, creates no tracking branches, and writes no fetch refspec. Signed-off-by: Toon Claes <toon@iotcl.com> Acked-by: Patrick Steinhardt <ps@pks.im> [jc: removed unnecessary TEST_PASSES_SANITIZE_LEAK from the test] Signed-off-by: Junio C Hamano <gitster@pobox.com>
123 lines
4.2 KiB
Bash
Executable File
123 lines
4.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='tests for git clone --revision'
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'setup' '
|
|
test_commit --no-tag "initial commit" README "Hello" &&
|
|
test_commit --annotate "second commit" README "Hello world" v1.0 &&
|
|
test_commit --no-tag "third commit" README "Hello world!" &&
|
|
git switch -c feature v1.0 &&
|
|
test_commit --no-tag "feature commit" README "Hello world!" &&
|
|
git switch main
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being a branch' '
|
|
test_when_finished "rm -rf dst" &&
|
|
git clone --revision=refs/heads/feature . dst &&
|
|
git rev-parse refs/heads/feature >expect &&
|
|
git -C dst rev-parse HEAD >actual &&
|
|
test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch
|
|
'
|
|
|
|
test_expect_success 'clone with --depth and --revision being a branch' '
|
|
test_when_finished "rm -rf dst" &&
|
|
git clone --no-local --depth=1 --revision=refs/heads/feature . dst &&
|
|
git rev-parse refs/heads/feature >expect &&
|
|
git -C dst rev-parse HEAD >actual &&
|
|
test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch &&
|
|
git -C dst rev-list HEAD >actual &&
|
|
test_line_count = 1 actual
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being a tag' '
|
|
test_when_finished "rm -rf dst" &&
|
|
git clone --revision=refs/tags/v1.0 . dst &&
|
|
git rev-parse refs/tags/v1.0^{} >expect &&
|
|
git -C dst rev-parse HEAD >actual &&
|
|
test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being HEAD' '
|
|
test_when_finished "rm -rf dst" &&
|
|
git clone --revision=HEAD . dst &&
|
|
git rev-parse HEAD >expect &&
|
|
git -C dst rev-parse HEAD >actual &&
|
|
test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being a raw commit hash' '
|
|
test_when_finished "rm -rf dst" &&
|
|
oid=$(git rev-parse refs/heads/feature) &&
|
|
git clone --revision=$oid . dst &&
|
|
echo $oid >expect &&
|
|
git -C dst rev-parse HEAD >actual &&
|
|
test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch
|
|
'
|
|
|
|
test_expect_success 'clone with --revision and --bare' '
|
|
test_when_finished "rm -rf dst" &&
|
|
git clone --revision=refs/heads/main --bare . dst &&
|
|
oid=$(git rev-parse refs/heads/main) &&
|
|
git -C dst cat-file -t $oid >actual &&
|
|
echo "commit" >expect &&
|
|
test_cmp expect actual &&
|
|
git -C dst for-each-ref refs >expect &&
|
|
test_must_be_empty expect &&
|
|
test_must_fail git -C dst config remote.origin.fetch
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being a short raw commit hash' '
|
|
test_when_finished "rm -rf dst" &&
|
|
oid=$(git rev-parse --short refs/heads/feature) &&
|
|
test_must_fail git clone --revision=$oid . dst 2>err &&
|
|
test_grep "fatal: Remote revision $oid not found in upstream origin" err
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being a tree hash' '
|
|
test_when_finished "rm -rf dst" &&
|
|
oid=$(git rev-parse refs/heads/feature^{tree}) &&
|
|
test_must_fail git clone --revision=$oid . dst 2>err &&
|
|
test_grep "error: object $oid is a tree, not a commit" err
|
|
'
|
|
|
|
test_expect_success 'clone with --revision being the parent of a ref fails' '
|
|
test_when_finished "rm -rf dst" &&
|
|
test_must_fail git clone --revision=refs/heads/main^ . dst
|
|
'
|
|
|
|
test_expect_success 'clone with --revision and --branch fails' '
|
|
test_when_finished "rm -rf dst" &&
|
|
test_must_fail git clone --revision=refs/heads/main --branch=main . dst
|
|
'
|
|
|
|
test_expect_success 'clone with --revision and --mirror fails' '
|
|
test_when_finished "rm -rf dst" &&
|
|
test_must_fail git clone --revision=refs/heads/main --mirror . dst
|
|
'
|
|
|
|
test_done
|