commit e8a967e0cafdb6604275a9cbfcce988d4f363ef5 from: Stefan Sperling date: Sat Mar 21 22:44:07 2020 UTC make replacing symrefs actually work in 'got fetch' commit - ecdc3b498ad54d952c807b07a04c0cdb2b998f03 commit + e8a967e0cafdb6604275a9cbfcce988d4f363ef5 blob - cd12b5ed30dbe248b20f407ac20e93f91e120177 blob + 0420f2eb7bce0a7e9766b05bb32d65d93f222c90 --- got/got.c +++ got/got.c @@ -1422,21 +1422,17 @@ update_ref(struct got_reference *ref, struct got_objec } if (got_ref_is_symbolic(ref)) { - struct got_reference *new_ref; - err = got_ref_alloc(&new_ref, got_ref_get_name(ref), new_id); - if (err) - goto done; - err = got_ref_delete(ref, repo); - if (err) - goto done; if (verbosity >= 0) { - printf("Deleted reference %s: %s\n", + printf("Replacing reference %s: %s\n", got_ref_get_name(ref), got_ref_get_symref_target(ref)); } - err = got_ref_write(new_ref, repo); + err = got_ref_change_symref_to_ref(ref, new_id); if (err) goto done; + err = got_ref_write(ref, repo); + if (err) + goto done; } else { err = got_ref_resolve(&old_id, repo, ref); if (err) blob - da0da7b7bf5a3d15f4fc771d125303ba08d29bbd blob + df306d5d03225bb3a1a0991de83bb445533c95be --- include/got_reference.h +++ include/got_reference.h @@ -123,6 +123,13 @@ got_ref_change_ref(struct got_reference *, struct got_ const struct got_error *got_ref_change_symref(struct got_reference *, char *); +/* + * Change a symbolic reference into a regular reference which points to + * the provided object ID. + */ +const struct got_error *got_ref_change_symref_to_ref(struct got_reference *, + struct got_object_id *); + /* Write a reference to its on-disk path in the repository. */ const struct got_error *got_ref_write(struct got_reference *, struct got_repository *); blob - ff1f037375b654994fbb0552899cb13e8766cdbb blob + 86409d0ebedc1d35c6333f13f4f8267d21581671 --- lib/reference.c +++ lib/reference.c @@ -1007,6 +1007,19 @@ got_ref_change_symref(struct got_reference *ref, char } const struct got_error * +got_ref_change_symref_to_ref(struct got_reference *symref, + struct got_object_id *id) +{ + if ((symref->flags & GOT_REF_IS_SYMBOLIC) == 0) + return got_error(GOT_ERR_BAD_REF_TYPE); + + symref->ref.ref.name = symref->ref.symref.name; + memcpy(symref->ref.ref.sha1, id->sha1, SHA1_DIGEST_LENGTH); + symref->flags &= ~GOT_REF_IS_SYMBOLIC; + return NULL; +} + +const struct got_error * got_ref_write(struct got_reference *ref, struct got_repository *repo) { const struct got_error *err = NULL, *unlock_err = NULL; blob - d62e1ba6753013cbf06768c9b370cf784c5224a9 blob + b59b39ef20a710f192c51ed6560b8c1b58bb3e67 --- regress/cmdline/fetch.sh +++ regress/cmdline/fetch.sh @@ -718,12 +718,77 @@ function test_fetch_reference { echo "refs/remotes/origin/master: $commit_id2" \ >> $testroot/stdout.expected echo "refs/tags/1.0: $tag_id" >> $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" + +} + +function test_fetch_replace_symref { + local testroot=`test_init fetch_replace_symref` + local testurl=ssh://127.0.0.1/$testroot + local commit_id=`git_show_head $testroot/repo` + + got clone -m -q $testurl/repo $testroot/repo-clone + ret="$?" + if [ "$ret" != "0" ]; then + echo "got clone command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo-clone -s refs/hoo/boo/zoo refs/heads/master + + got ref -l -r $testroot/repo-clone > $testroot/stdout + + echo "HEAD: refs/heads/master" > $testroot/stdout.expected + echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected + echo "refs/hoo/boo/zoo: refs/heads/master" >> $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + got fetch -r $testroot/repo-clone -R refs/hoo \ + 2> $testroot/stderr | grep ^Replacing > $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + echo "got fetch command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + echo "Replacing reference refs/hoo/boo/zoo: refs/heads/master" \ + > $testroot/stdout.expected + cmp -s $testroot/stdout $testroot/stdout.expected ret="$?" if [ "$ret" != "0" ]; then diff -u $testroot/stdout.expected $testroot/stdout + 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/master: $commit_id" >> $testroot/stdout.expected + echo "refs/hoo/boo/zoo: $commit_id" >> $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi test_done "$testroot" "$ret" } @@ -736,3 +801,4 @@ run_test test_fetch_empty_packfile run_test test_fetch_delete_branch run_test test_fetch_update_tag run_test test_fetch_reference +run_test test_fetch_replace_symref