summaryrefslogtreecommitdiffstats
path: root/refs.c
diff options
context:
space:
mode:
authorBence Ferdinandy <bence@ferdinandy.com>2024-11-22 13:28:49 +0100
committerJunio C Hamano <gitster@pobox.com>2024-11-25 03:46:36 +0100
commit9963746c841dc786529827b7b6755d0a3e208ad4 (patch)
tree166b1ceddff829fc5f7f46e77f6ee714442cd824 /refs.c
parentrefs: add TRANSACTION_CREATE_EXISTS error (diff)
downloadgit-9963746c841dc786529827b7b6755d0a3e208ad4.tar.xz
git-9963746c841dc786529827b7b6755d0a3e208ad4.zip
refs: add create_only option to refs_update_symref_extended
Allow the caller to specify that it only wants to update the symref if it does not already exist. Silently ignore the error from the transaction API if the symref already exists. Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/refs.c b/refs.c
index d80efd58f0..2efa6bcc5c 100644
--- a/refs.c
+++ b/refs.c
@@ -2116,26 +2116,38 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct
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)) {
@@ -2144,8 +2156,11 @@ int refs_update_symref_extended(struct ref_store *refs, const char *ref,
}
}
+ 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);