commit - d7b899ab022b3f7c7a42ed1338efa4ad6be626c8
commit + f1bcca348e0d038b29d4d9bc6c87cbccf6893265
blob - b02072bccaf3d9b6fd8fbcc856402702d6307ba0
blob + 96e6346e20d7ac287590a46af4a3f785b7fc7f4c
--- got/got.c
+++ got/got.c
free(new_id_str);
return err;
}
+
+static const struct got_error *
+update_symref(const char *refname, struct got_reference *target_ref,
+ int verbosity, struct got_repository *repo)
+{
+ const struct got_error *err = NULL, *unlock_err;
+ struct got_reference *symref;
+
+ err = got_ref_open(&symref, repo, refname, 1);
+ if (err)
+ return err;
+
+ if (strcmp(got_ref_get_symref_target(symref),
+ got_ref_get_name(target_ref)) == 0)
+ goto done;
+ err = got_ref_change_symref(symref, got_ref_get_name(target_ref));
+ if (err)
+ goto done;
+
+ err = got_ref_write(symref, repo);
+ if (err)
+ goto done;
+
+ if (verbosity >= 0)
+ printf("Updated reference %s: %s\n", got_ref_get_name(symref),
+ got_ref_get_symref_target(symref));
+done:
+ unlock_err = got_ref_unlock(symref);
+ if (unlock_err && err == NULL)
+ err = unlock_err;
+ got_ref_close(symref);
+ return err;
+ return NULL;
+}
+
__dead static void
usage_fetch(void)
{
}
}
}
- if (delete_refs)
+ if (delete_refs) {
error = delete_missing_refs(&refs, verbosity, repo);
+ if (error)
+ goto done;
+ }
+
+ if (!remote->mirror_references) {
+ /* Update remote HEAD reference if the server provided one. */
+ TAILQ_FOREACH(pe, &symrefs, entry) {
+ struct got_reference *target_ref;
+ const char *refname = pe->path;
+ const char *target = pe->data;
+ char *remote_refname = NULL, *remote_target = NULL;
+
+ if (strcmp(refname, GOT_REF_HEAD) != 0)
+ continue;
+
+ if (strncmp("refs/heads/", target, 11) != 0)
+ continue;
+
+ if (asprintf(&remote_refname, "refs/remotes/%s/%s",
+ remote->name, refname) == -1) {
+ error = got_error_from_errno("asprintf");
+ goto done;
+ }
+ if (asprintf(&remote_target, "refs/remotes/%s/%s",
+ remote->name, target + 11) == -1) {
+ error = got_error_from_errno("asprintf");
+ free(remote_refname);
+ goto done;
+ }
+
+ error = got_ref_open(&target_ref, repo, remote_target,
+ 0);
+ if (error) {
+ free(remote_refname);
+ free(remote_target);
+ if (error->code == GOT_ERR_NOT_REF) {
+ error = NULL;
+ continue;
+ }
+ goto done;
+ }
+ error = update_symref(remote_refname, target_ref,
+ verbosity, repo);
+ free(remote_refname);
+ free(remote_target);
+ got_ref_close(target_ref);
+ if (error)
+ goto done;
+ }
+ }
done:
if (fetchpid > 0) {
if (kill(fetchpid, SIGTERM) == -1)
blob - 404c994afe6baff215d08dc8f14a1f9437434dac
blob + e4a422fced01a3e564e433af5872e46fb304c6af
--- regress/cmdline/fetch.sh
+++ regress/cmdline/fetch.sh
echo "HEAD: refs/heads/master" > $testroot/stdout.expected
echo "refs/heads/foo: $commit_id3" >> $testroot/stdout.expected
echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
- echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
+ echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \
>> $testroot/stdout.expected
echo "refs/remotes/origin/foo: $commit_id3" >> $testroot/stdout.expected
# refs/remotes/origin/master is umodified because it wasn't fetched
echo "HEAD: refs/heads/master" > $testroot/stdout.expected
echo "refs/heads/foo: $commit_id3" >> $testroot/stdout.expected
echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
- echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
+ echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \
>> $testroot/stdout.expected
echo "refs/remotes/origin/foo: $commit_id3" >> $testroot/stdout.expected
echo "refs/remotes/origin/master: $commit_id2" \
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"
+
+}
+
+function test_fetch_update_headref {
+ local testroot=`test_init fetch_update_headref`
+ local testurl=ssh://127.0.0.1/$testroot
+ local commit_id=`git_show_head $testroot/repo`
+
+ got clone -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 -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/remotes/origin/HEAD: refs/remotes/origin/master" \
+ >> $testroot/stdout.expected
+ echo "refs/remotes/origin/master: $commit_id" \
+ >> $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 -r $testroot/repo -c refs/heads/master refs/heads/foo
+ got ref -r $testroot/repo -s refs/heads/foo HEAD
+ got ref -l -r $testroot/repo > $testroot/stdout
+
+ echo "HEAD: refs/heads/foo" > $testroot/stdout.expected
+ echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
+ echo "refs/heads/master: $commit_id" >> $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 -q -r $testroot/repo-clone
+
+ 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/heads/master: $commit_id" >> $testroot/stdout.expected
+ echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \
+ >> $testroot/stdout.expected
+ echo "refs/remotes/origin/foo: $commit_id" \
+ >> $testroot/stdout.expected
+ echo "refs/remotes/origin/master: $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_update_tag
run_test test_fetch_reference
run_test test_fetch_replace_symref
+run_test test_fetch_update_headref