commit - ecdc3b498ad54d952c807b07a04c0cdb2b998f03
commit + e8a967e0cafdb6604275a9cbfcce988d4f363ef5
blob - cd12b5ed30dbe248b20f407ac20e93f91e120177
blob + 0420f2eb7bce0a7e9766b05bb32d65d93f222c90
--- got/got.c
+++ got/got.c
}
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
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
}
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
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"
}
run_test test_fetch_delete_branch
run_test test_fetch_update_tag
run_test test_fetch_reference
+run_test test_fetch_replace_symref