refs: use transaction in `refs_create_symref()`

The `refs_create_symref()` function updates a symref to a given new target. To do this, it uses a ref-backend specific function `create_symref()`. In the previous commits, we introduced symref support in transactions. This means we can now use transactions to perform symref updates and don't have to resort to `create_symref()`. Doing this allows us to remove and cleanup `create_symref()`, which we will do in the following commit. Modify the expected error message for a test in 't/t0610-reftable-basics.sh', since the error is now thrown from 'refs.c'. This is because in transactional updates, F/D conflicts are caught before we're in the reference backend. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karthik Nayak committed May 7, 2024 at 14:58 UTC 300b38e46f951bab8c6c5cb779b59322be321081
3 files changed +41 -8
refs.c
+17 -7
@@ -2289,14 +2289,24 @@ int refs_create_symref(struct ref_store *refs,
2289 const char *refs_heads_master,
2290 const char *logmsg)
2291 {
2292 - char *msg;
2293 - int retval;
2292 + struct ref_transaction *transaction;
2293 + struct strbuf err = STRBUF_INIT;
2294 + int ret = 0;
2295
2295 - msg = normalize_reflog_message(logmsg);
2296 - retval = refs->be->create_symref(refs, ref_target, refs_heads_master,
2297 - msg);
2298 - free(msg);
2299 - return retval;
2296 + transaction = ref_store_transaction_begin(refs, &err);
2297 + if (!transaction ||
2298 + ref_transaction_update(transaction, ref_target, NULL, NULL,
2299 + refs_heads_master, NULL, REF_NO_DEREF,
2300 + logmsg, &err) ||
2301 + ref_transaction_commit(transaction, &err)) {
2302 + ret = error("%s", err.buf);
2303 + }
2304 +
2305 + strbuf_release(&err);
2306 + if (transaction)
2307 + ref_transaction_free(transaction);
2308 +
2309 + return ret;
2310 }
2311
2312 int create_symref(const char *ref_target, const char *refs_heads_master,
t/t0610-reftable-basics.sh
+1 -1
@@ -255,7 +255,7 @@ test_expect_success 'ref transaction: creating symbolic ref fails with F/D confl
255 git init repo &&
256 test_commit -C repo A &&
257 cat >expect <<-EOF &&
258 - error: unable to write symref for refs/heads: file/directory conflict
258 + error: ${SQ}refs/heads/main${SQ} exists; cannot create ${SQ}refs/heads${SQ}
259 EOF
260 test_must_fail git -C repo symbolic-ref refs/heads refs/heads/foo 2>err &&
261 test_cmp expect err
t/t1416-ref-transaction-hooks.sh
+23
@@ -134,4 +134,27 @@ test_expect_success 'interleaving hook calls succeed' '
134 test_cmp expect target-repo.git/actual
135 '
136
137 +test_expect_success 'hook captures git-symbolic-ref updates' '
138 + test_when_finished "rm actual" &&
139 +
140 + test_hook reference-transaction <<-\EOF &&
141 + echo "$*" >>actual
142 + while read -r line
143 + do
144 + printf "%s\n" "$line"
145 + done >>actual
146 + EOF
147 +
148 + git symbolic-ref refs/heads/symref refs/heads/main &&
149 +
150 + cat >expect <<-EOF &&
151 + prepared
152 + $ZERO_OID ref:refs/heads/main refs/heads/symref
153 + committed
154 + $ZERO_OID ref:refs/heads/main refs/heads/symref
155 + EOF
156 +
157 + test_cmp expect actual
158 +'
159 +
160 test_done