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);
+ return refs_update_symref_extended(refs, ref, target, logmsg, NULL, 0);
}
int refs_update_symref_extended(struct ref_store *refs, const char *ref,
const char *target, const char *logmsg,
- struct strbuf *referent)
+ struct strbuf *referent, int create_only)
{
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
- int ret = 0;
+ int ret = 0, prepret = 0;
transaction = ref_store_transaction_begin(refs, &err);
- if (!transaction ||
- ref_transaction_update(transaction, ref, NULL, NULL,
- target, NULL, REF_NO_DEREF,
- logmsg, &err) ||
- ref_transaction_prepare(transaction, &err)) {
+ if (!transaction) {
+ error_return:
ret = error("%s", err.buf);
goto cleanup;
}
+ if (create_only) {
+ if (ref_transaction_create(transaction, ref, NULL, target,
+ REF_NO_DEREF, logmsg, &err))
+ goto error_return;
+ prepret = ref_transaction_prepare(transaction, &err);
+ if (prepret && prepret != TRANSACTION_CREATE_EXISTS)
+ goto error_return;
+ } else {
+ if (ref_transaction_update(transaction, ref, NULL, NULL,
+ target, NULL, REF_NO_DEREF,
+ logmsg, &err) ||
+ ref_transaction_prepare(transaction, &err))
+ goto error_return;
+ }
+
if (referent && refs_read_symbolic_ref(refs, ref, referent) == NOT_A_SYMREF) {
struct object_id oid;
if (!refs_read_ref(refs, ref, &oid)) {
}
}
+ if (prepret == TRANSACTION_CREATE_EXISTS)
+ goto cleanup;
+
if (ref_transaction_commit(transaction, &err))
- ret = error("%s", err.buf);
+ goto error_return;
cleanup:
strbuf_release(&err);