int refs_update_symref(struct ref_store *refs, const char *ref,
const char *target, const char *logmsg)
+{
+ return refs_update_symref_extended(refs, ref, target, logmsg, NULL);
+}
+
+int refs_update_symref_extended(struct ref_store *refs, const char *ref,
+ const char *target, const char *logmsg,
+ struct strbuf *referent)
{
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
ref_transaction_update(transaction, ref, NULL, NULL,
target, NULL, REF_NO_DEREF,
logmsg, &err) ||
- ref_transaction_commit(transaction, &err)) {
+ ref_transaction_prepare(transaction, &err)) {
ret = error("%s", err.buf);
+ goto cleanup;
}
+ if (referent && refs_read_symbolic_ref(refs, ref, referent) == NOT_A_SYMREF) {
+ struct object_id oid;
+ if (!refs_read_ref(refs, ref, &oid)) {
+ strbuf_addstr(referent, oid_to_hex(&oid));
+ ret = NOT_A_SYMREF;
+ }
+ }
+
+ if (ref_transaction_commit(transaction, &err))
+ ret = error("%s", err.buf);
+cleanup:
strbuf_release(&err);
if (transaction)
ref_transaction_free(transaction);
return (update->flags & REF_HAVE_OLD) &&
(!is_null_oid(&update->old_oid) || update->old_target);
}
-
int refs_update_symref(struct ref_store *refs, const char *refname,
const char *target, const char *logmsg);
+int refs_update_symref_extended(struct ref_store *refs, const char *refname,
+ const char *target, const char *logmsg,
+ struct strbuf *referent);
+
enum action_on_err {
UPDATE_REFS_MSG_ON_ERR,
UPDATE_REFS_DIE_ON_ERR,