From: Stefan Sperling Subject: Re: fix cloning of repositories with dangling head reference To: Omar Polo Cc: gameoftrees@openbsd.org Date: Tue, 8 Nov 2022 17:25:39 +0100 On Tue, Nov 08, 2022 at 05:01:35PM +0100, Omar Polo wrote: > > @@ -1881,6 +1882,20 @@ cmd_clone(int argc, char *argv[]) > > goto done; > > break; > > } > > + > > + if (!fpa.configs_created && target_ref) { > > Reached this point target_ref is either NULL or a free'd pointer. > It's fine; the integral number doesn't change after passing it to > got_ref_close, but I just felt to pointing it out. Oh, indeed. What we want is to ensure that a known branch exist that will end up being written into the config file. It might be better to abuse 'pe' as a flag, see below. Less risk of future changes starting to pass the variable around after it's been freed. > > + 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 > > forgot to cmp stdout and stdout.expected Good catch, also fixed below. diff b43d5a6cd3a253c93c9cc25574997ac4aac7a4f9 cf5e25eb694afb46dddc7e27ef35da2117a0a45f commit - b43d5a6cd3a253c93c9cc25574997ac4aac7a4f9 commit + cf5e25eb694afb46dddc7e27ef35da2117a0a45f blob - c0c38ea47dfbd657ee0c14d0e8829767ad691ae6 blob + b444c533995567c4ece649cbcf950cd7f365361e --- got/got.c +++ got/got.c @@ -1881,6 +1881,20 @@ cmd_clone(int argc, char *argv[]) goto done; break; } + + if (!fpa.configs_created && pe != NULL) { + 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 + 6881cc1cec543e7bfd4986adaba1e99620dfeabd --- regress/cmdline/clone.sh +++ regress/cmdline/clone.sh @@ -754,6 +754,87 @@ 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/foo" > $testroot/stdout.expected + echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected + echo "refs/remotes/origin/foo: $commit_id" >> $testroot/stdout.expected + + 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 + + cat > $testroot/got.conf.expected < $testroot/config.expected <