Download raw body.
fix cloning of repositories with dangling head reference
Make 'got clone -b' work for repositories which lack a HEAD reference
that points to an existing branch.
Regression test which reproduces the problem is included.
Patch fixes this error:
got-fetch-pack: could not find any branches to fetch
Also ensures that default config files get created in this case.
ok?
diff ca7cfae029f0cbca1f65f326025744f627b69d92 593af7bd3baeb8314b7ef9a11fe0559a6ba9557d
commit - ca7cfae029f0cbca1f65f326025744f627b69d92
commit + 593af7bd3baeb8314b7ef9a11fe0559a6ba9557d
blob - c0c38ea47dfbd657ee0c14d0e8829767ad691ae6
blob + 1e29e64a3d1e97b5787efdf1754a70fe1615d190
--- got/got.c
+++ got/got.c
@@ -1856,6 +1856,7 @@ cmd_clone(int argc, char *argv[])
goto done;
}
if (pe == NULL) {
+ struct got_reference *target_ref = NULL;
/*
* We failed to set the HEAD reference. If we asked for
* a set of wanted branches use the first of one of those
@@ -1863,12 +1864,12 @@ cmd_clone(int argc, char *argv[])
*/
TAILQ_FOREACH(pe, &wanted_branches, entry) {
const char *target = pe->path;
- struct got_reference *target_ref;
error = got_ref_open(&target_ref, repo, target, 0);
if (error) {
if (error->code == GOT_ERR_NOT_REF) {
error = NULL;
+ target_ref = NULL;
continue;
}
goto done;
@@ -1881,6 +1882,20 @@ cmd_clone(int argc, char *argv[])
goto done;
break;
}
+
+ if (!fpa.configs_created && target_ref) {
+ error = create_config_files(fpa.config_info.proto,
+ fpa.config_info.host, fpa.config_info.port,
+ fpa.config_info.remote_repo_path,
+ fpa.config_info.git_url,
+ fpa.config_info.fetch_all_branches,
+ fpa.config_info.mirror_references,
+ fpa.config_info.symrefs,
+ fpa.config_info.wanted_branches,
+ fpa.config_info.wanted_refs, fpa.repo);
+ if (error)
+ goto done;
+ }
}
if (verbosity >= 0)
blob - 6cac7e61e2407f2c053f4cf8256c67ae466489a6
blob + 4fa55782d6cfa72a92ffedfb310e3ac0e508e55c
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -373,7 +373,8 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
break;
}
}
- continue;
+ if (default_branch)
+ continue;
}
if (strstr(refname, "^{}")) {
if (chattygot) {
blob - 35d7c0ba41e646078b5beea834a05d4d28891363
blob + 58ef8f4044adf772026d09c3bfc6ee1dc2e947ef
--- regress/cmdline/clone.sh
+++ regress/cmdline/clone.sh
@@ -754,6 +754,79 @@ test_parseargs "$@"
test_done "$testroot" "$ret"
}
+test_clone_dangling_headref() {
+ local testroot=`test_init clone_dangling_headref`
+ local testurl=ssh://127.0.0.1/$testroot
+ local commit_id=`git_show_head $testroot/repo`
+
+ got branch -r $testroot/repo -d master > /dev/null
+ got branch -r $testroot/repo -c $commit_id foo
+
+ got ref -l -r $testroot/repo > $testroot/stdout
+
+ echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+ echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
+ # refs/heads/master is missing because it was deleted above
+
+ cmp -s $testroot/stdout $testroot/stdout.expected
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ got clone -q -b foo $testurl/repo $testroot/repo-clone
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ echo "got clone command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ got ref -l -r $testroot/repo-clone > $testroot/stdout
+
+ echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+ echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
+ echo "refs/remotes/origin/foo: $commit_id" >> $testroot/stdout.expected
+
+ cat > $testroot/got.conf.expected <<EOF
+remote "origin" {
+ server 127.0.0.1
+ protocol ssh
+ repository "$testroot/repo"
+ branch { "foo" }
+}
+EOF
+ cmp -s $testroot/repo-clone/got.conf $testroot/got.conf.expected
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/got.conf.expected \
+ $testroot/repo-clone/got.conf
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cat > $testroot/config.expected <<EOF
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
+
+[remote "origin"]
+ url = ssh://127.0.0.1$testroot/repo
+ fetch = refs/heads/foo:refs/remotes/origin/foo
+ fetch = refs/tags/*:refs/tags/*
+EOF
+ cmp -s $testroot/repo-clone/config $testroot/config.expected
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/config.expected \
+ $testroot/repo-clone/config
+ fi
+ test_done "$testroot" "$ret"
+}
+
test_parseargs "$@"
run_test test_clone_basic
run_test test_clone_list
@@ -765,3 +838,4 @@ run_test test_clone_multiple_branches
run_test test_clone_branch_and_reference
run_test test_clone_reference_mirror
run_test test_clone_multiple_branches
+run_test test_clone_dangling_headref
fix cloning of repositories with dangling head reference