ref_transaction_verify(): new function to check a reference's value
If NULL is passed to ref_transaction_update()'s new_sha1 parameter, then just verify old_sha1 (under lock) without trying to change the new value of the reference. Use this functionality to add a new function ref_transaction_verify(), which checks the current value of the reference under lock but doesn't change it. Use ref_transaction_verify() in the implementation of "git update-ref --stdin"'s "verify" command to avoid the awkward need to "update" the reference to its existing value. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Feb 17, 2015 at 18:00 UTC
16180334015ab44b0310b9d896e554a66c36a1a4
3 files changed
+67
-21
builtin/update-ref.c
+2
-5
@@ -282,7 +282,6 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
282
{
283
struct strbuf err = STRBUF_INIT;
284
char *refname;
285
- unsigned char new_sha1[20];
285
unsigned char old_sha1[20];
286
287
refname = parse_refname(input, &next);
@@ -293,13 +292,11 @@ static const char *parse_cmd_verify(struct ref_transaction *transaction,
292
PARSE_SHA1_OLD))
293
hashclr(old_sha1);
294
296
- hashcpy(new_sha1, old_sha1);
297
-
295
if (*next != line_termination)
296
die("verify %s: extra input: %s", refname, next);
297
301
- if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
302
- update_flags, msg, &err))
298
+ if (ref_transaction_verify(transaction, refname, old_sha1,
299
+ update_flags, &err))
300
die("%s", err.buf);
301
302
update_flags = 0;
refs.c
+39
-8
@@ -46,11 +46,17 @@ static unsigned char refname_disposition[256] = {
46
*/
47
#define REF_ISPRUNING 0x04
48
49
+/*
50
+ * Used as a flag in ref_update::flags when the reference should be
51
+ * updated to new_sha1.
52
+ */
53
+#define REF_HAVE_NEW 0x08
54
+
55
/*
56
* Used as a flag in ref_update::flags when old_sha1 should be
57
* checked.
58
*/
53
-#define REF_HAVE_OLD 0x08
59
+#define REF_HAVE_OLD 0x10
60
61
/*
62
* Try to read one refname component from the front of refname.
@@ -3577,10 +3583,17 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
3583
* not exist before update.
3584
*/
3585
struct ref_update {
3586
+ /*
3587
+ * If (flags & REF_HAVE_NEW), set the reference to this value:
3588
+ */
3589
unsigned char new_sha1[20];
3590
+ /*
3591
+ * If (flags & REF_HAVE_OLD), check that the reference
3592
+ * previously had this value:
3593
+ */
3594
unsigned char old_sha1[20];
3595
/*
3583
- * One or more of REF_HAVE_OLD, REF_NODEREF,
3596
+ * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
3597
* REF_DELETING, and REF_ISPRUNING:
3598
*/
3599
unsigned int flags;
@@ -3665,7 +3678,7 @@ int ref_transaction_update(struct ref_transaction *transaction,
3678
if (transaction->state != REF_TRANSACTION_OPEN)
3679
die("BUG: update called for transaction that is not open");
3680
3668
- if (!is_null_sha1(new_sha1) &&
3681
+ if (new_sha1 && !is_null_sha1(new_sha1) &&
3682
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
3683
strbuf_addf(err, "refusing to update ref with bad name %s",
3684
refname);
@@ -3673,7 +3686,10 @@ int ref_transaction_update(struct ref_transaction *transaction,
3686
}
3687
3688
update = add_update(transaction, refname);
3676
- hashcpy(update->new_sha1, new_sha1);
3689
+ if (new_sha1) {
3690
+ hashcpy(update->new_sha1, new_sha1);
3691
+ flags |= REF_HAVE_NEW;
3692
+ }
3693
if (old_sha1) {
3694
hashcpy(update->old_sha1, old_sha1);
3695
flags |= REF_HAVE_OLD;
@@ -3709,6 +3725,19 @@ int ref_transaction_delete(struct ref_transaction *transaction,
3725
flags, msg, err);
3726
}
3727
3728
+int ref_transaction_verify(struct ref_transaction *transaction,
3729
+ const char *refname,
3730
+ const unsigned char *old_sha1,
3731
+ unsigned int flags,
3732
+ struct strbuf *err)
3733
+{
3734
+ if (!old_sha1)
3735
+ die("BUG: verify called with old_sha1 set to NULL");
3736
+ return ref_transaction_update(transaction, refname,
3737
+ NULL, old_sha1,
3738
+ flags, NULL, err);
3739
+}
3740
+
3741
int update_ref(const char *action, const char *refname,
3742
const unsigned char *sha1, const unsigned char *oldval,
3743
unsigned int flags, enum action_on_err onerr)
@@ -3797,7 +3826,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3826
struct ref_update *update = updates[i];
3827
unsigned int flags = update->flags;
3828
3800
- if (is_null_sha1(update->new_sha1))
3829
+ if ((flags & REF_HAVE_NEW) && is_null_sha1(update->new_sha1))
3830
flags |= REF_DELETING;
3831
update->lock = lock_ref_sha1_basic(
3832
update->refname,
@@ -3819,8 +3848,9 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3848
/* Perform updates first so live commits remain referenced */
3849
for (i = 0; i < n; i++) {
3850
struct ref_update *update = updates[i];
3851
+ int flags = update->flags;
3852
3823
- if (!is_null_sha1(update->new_sha1)) {
3853
+ if ((flags & REF_HAVE_NEW) && !is_null_sha1(update->new_sha1)) {
3854
if (write_ref_sha1(update->lock, update->new_sha1,
3855
update->msg)) {
3856
update->lock = NULL; /* freed by write_ref_sha1 */
@@ -3836,14 +3866,15 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3866
/* Perform deletes now that updates are safely completed */
3867
for (i = 0; i < n; i++) {
3868
struct ref_update *update = updates[i];
3869
+ int flags = update->flags;
3870
3840
- if (update->lock) {
3871
+ if ((flags & REF_HAVE_NEW) && is_null_sha1(update->new_sha1)) {
3872
if (delete_ref_loose(update->lock, update->type, err)) {
3873
ret = TRANSACTION_GENERIC_ERROR;
3874
goto cleanup;
3875
}
3876
3846
- if (!(update->flags & REF_ISPRUNING))
3877
+ if (!(flags & REF_ISPRUNING))
3878
string_list_append(&refs_to_delete,
3879
update->lock->ref_name);
3880
}
refs.h
+26
-8
@@ -263,14 +263,19 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
263
*/
264
265
/*
266
- * Add a reference update to transaction. new_sha1 is the value that
267
- * the reference should have after the update, or null_sha1 if it should
268
- * be deleted. If old_sha1 is non-NULL, then it is the value
269
- * that the reference should have had before the update, or null_sha1 if
270
- * it must not have existed beforehand.
271
- * Function returns 0 on success and non-zero on failure. A failure to update
272
- * means that the transaction as a whole has failed and will need to be
273
- * rolled back.
266
+ * Add a reference update to transaction. new_sha1 is the value that
267
+ * the reference should have after the update, or null_sha1 if it
268
+ * should be deleted. If new_sha1 is NULL, then the reference is not
269
+ * changed at all. old_sha1 is the value that the reference must have
270
+ * before the update, or null_sha1 if it must not have existed
271
+ * beforehand. The old value is checked after the lock is taken to
272
+ * prevent races. If the old value doesn't agree with old_sha1, the
273
+ * whole transaction fails. If old_sha1 is NULL, then the previous
274
+ * value is not checked.
275
+ *
276
+ * Return 0 on success and non-zero on failure. Any failure in the
277
+ * transaction means that the transaction as a whole has failed and
278
+ * will need to be rolled back.
279
*/
280
int ref_transaction_update(struct ref_transaction *transaction,
281
const char *refname,
@@ -308,6 +313,19 @@ int ref_transaction_delete(struct ref_transaction *transaction,
313
unsigned int flags, const char *msg,
314
struct strbuf *err);
315
316
+/*
317
+ * Verify, within a transaction, that refname has the value old_sha1,
318
+ * or, if old_sha1 is null_sha1, then verify that the reference
319
+ * doesn't exist. old_sha1 must be non-NULL. Function returns 0 on
320
+ * success and non-zero on failure. A failure to verify means that the
321
+ * transaction as a whole has failed and will need to be rolled back.
322
+ */
323
+int ref_transaction_verify(struct ref_transaction *transaction,
324
+ const char *refname,
325
+ const unsigned char *old_sha1,
326
+ unsigned int flags,
327
+ struct strbuf *err);
328
+
329
/*
330
* Commit all of the changes that have been queued in transaction, as
331
* atomically as possible.