refs.c: change ref_transaction_create to do error checking and return status

Do basic error checking in ref_transaction_create() and make it return non-zero on error. Update all callers to check the result of ref_transaction_create(). There are currently no conditions in _create that will return error but there will be in the future. Add an err argument that will be updated on failure. Signed-off-by: Ronnie Sahlberg <sahlberg@google.com> Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ronnie Sahlberg committed Apr 16, 2014 at 15:26 UTC b416af5bcdca3ac8426220f09efbfca2f1bec6e0
3 files changed +56 -14
builtin/update-ref.c
+3 -1
@@ -226,7 +226,9 @@ static const char *parse_cmd_create(struct strbuf *input, const char *next)
226 if (*next != line_termination)
227 die("create %s: extra input: %s", refname, next);
228
229 - ref_transaction_create(transaction, refname, new_sha1, update_flags);
229 + if (ref_transaction_create(transaction, refname, new_sha1,
230 + update_flags, &err))
231 + die("%s", err.buf);
232
233 update_flags = 0;
234 free(refname);
refs.c
+12 -6
@@ -3449,18 +3449,24 @@ int ref_transaction_update(struct ref_transaction *transaction,
3449 return 0;
3450 }
3451
3452 -void ref_transaction_create(struct ref_transaction *transaction,
3453 - const char *refname,
3454 - const unsigned char *new_sha1,
3455 - int flags)
3452 +int ref_transaction_create(struct ref_transaction *transaction,
3453 + const char *refname,
3454 + const unsigned char *new_sha1,
3455 + int flags,
3456 + struct strbuf *err)
3457 {
3457 - struct ref_update *update = add_update(transaction, refname);
3458 + struct ref_update *update;
3459 +
3460 + if (!new_sha1 || is_null_sha1(new_sha1))
3461 + die("BUG: create ref with null new_sha1");
3462 +
3463 + update = add_update(transaction, refname);
3464
3459 - assert(!is_null_sha1(new_sha1));
3465 hashcpy(update->new_sha1, new_sha1);
3466 hashclr(update->old_sha1);
3467 update->flags = flags;
3468 update->have_old = 1;
3469 + return 0;
3470 }
3471
3472 void ref_transaction_delete(struct ref_transaction *transaction,
refs.h
+41 -7
@@ -10,6 +10,38 @@ struct ref_lock {
10 int force_write;
11 };
12
13 +/*
14 + * A ref_transaction represents a collection of ref updates
15 + * that should succeed or fail together.
16 + *
17 + * Calling sequence
18 + * ----------------
19 + * - Allocate and initialize a `struct ref_transaction` by calling
20 + * `ref_transaction_begin()`.
21 + *
22 + * - List intended ref updates by calling functions like
23 + * `ref_transaction_update()` and `ref_transaction_create()`.
24 + *
25 + * - Call `ref_transaction_commit()` to execute the transaction.
26 + * If this succeeds, the ref updates will have taken place and
27 + * the transaction cannot be rolled back.
28 + *
29 + * - At any time call `ref_transaction_free()` to discard the
30 + * transaction and free associated resources. In particular,
31 + * this rolls back the transaction if it has not been
32 + * successfully committed.
33 + *
34 + * Error handling
35 + * --------------
36 + *
37 + * On error, transaction functions append a message about what
38 + * went wrong to the 'err' argument. The message mentions what
39 + * ref was being updated (if any) when the error occurred so it
40 + * can be passed to 'die' or 'error' as-is.
41 + *
42 + * The message is appended to err without first clearing err.
43 + * err will not be '\n' terminated.
44 + */
45 struct ref_transaction;
46
47 /*
@@ -248,7 +280,7 @@ struct ref_transaction *ref_transaction_begin(void);
280 * it must not have existed beforehand.
281 * Function returns 0 on success and non-zero on failure. A failure to update
282 * means that the transaction as a whole has failed and will need to be
251 - * rolled back. On failure the err buffer will be updated.
283 + * rolled back.
284 */
285 int ref_transaction_update(struct ref_transaction *transaction,
286 const char *refname,
@@ -262,11 +294,15 @@ int ref_transaction_update(struct ref_transaction *transaction,
294 * that the reference should have after the update; it must not be the
295 * null SHA-1. It is verified that the reference does not exist
296 * already.
297 + * Function returns 0 on success and non-zero on failure. A failure to create
298 + * means that the transaction as a whole has failed and will need to be
299 + * rolled back.
300 */
266 -void ref_transaction_create(struct ref_transaction *transaction,
267 - const char *refname,
268 - const unsigned char *new_sha1,
269 - int flags);
301 +int ref_transaction_create(struct ref_transaction *transaction,
302 + const char *refname,
303 + const unsigned char *new_sha1,
304 + int flags,
305 + struct strbuf *err);
306
307 /*
308 * Add a reference deletion to transaction. If have_old is true, then
@@ -282,8 +318,6 @@ void ref_transaction_delete(struct ref_transaction *transaction,
318 * Commit all of the changes that have been queued in transaction, as
319 * atomically as possible. Return a nonzero value if there is a
320 * problem.
285 - * If err is non-NULL we will add an error string to it to explain why
286 - * the transaction failed. The string does not end in newline.
321 */
322 int ref_transaction_commit(struct ref_transaction *transaction,
323 const char *msg, struct strbuf *err);