@@ -46,11 +46,17 @@ static unsigned char refname_disposition[256] = {
46
46
*/
47
47
#define REF_ISPRUNING 0x04
48
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
+
49
55
/*
50
56
* Used as a flag in ref_update::flags when old_sha1 should be
51
57
* checked.
52
58
*/
53
- #define REF_HAVE_OLD 0x08
59
+ #define REF_HAVE_OLD 0x10
54
60
55
61
/*
56
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)
3577
3583
* not exist before update.
3578
3584
*/
3579
3585
struct ref_update {
3586
+ /*
3587
+ * If (flags & REF_HAVE_NEW), set the reference to this value:
3588
+ */
3580
3589
unsigned char new_sha1 [20 ];
3590
+ /*
3591
+ * If (flags & REF_HAVE_OLD), check that the reference
3592
+ * previously had this value:
3593
+ */
3581
3594
unsigned char old_sha1 [20 ];
3582
3595
/*
3583
- * One or more of REF_HAVE_OLD, REF_NODEREF,
3596
+ * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
3584
3597
* REF_DELETING, and REF_ISPRUNING:
3585
3598
*/
3586
3599
unsigned int flags ;
@@ -3665,15 +3678,18 @@ int ref_transaction_update(struct ref_transaction *transaction,
3665
3678
if (transaction -> state != REF_TRANSACTION_OPEN )
3666
3679
die ("BUG: update called for transaction that is not open" );
3667
3680
3668
- if (!is_null_sha1 (new_sha1 ) &&
3681
+ if (new_sha1 && !is_null_sha1 (new_sha1 ) &&
3669
3682
check_refname_format (refname , REFNAME_ALLOW_ONELEVEL )) {
3670
3683
strbuf_addf (err , "refusing to update ref with bad name %s" ,
3671
3684
refname );
3672
3685
return -1 ;
3673
3686
}
3674
3687
3675
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
+ }
3677
3693
if (old_sha1 ) {
3678
3694
hashcpy (update -> old_sha1 , old_sha1 );
3679
3695
flags |= REF_HAVE_OLD ;
@@ -3709,6 +3725,19 @@ int ref_transaction_delete(struct ref_transaction *transaction,
3709
3725
flags , msg , err );
3710
3726
}
3711
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
+
3712
3741
int update_ref (const char * action , const char * refname ,
3713
3742
const unsigned char * sha1 , const unsigned char * oldval ,
3714
3743
unsigned int flags , enum action_on_err onerr )
@@ -3797,7 +3826,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3797
3826
struct ref_update * update = updates [i ];
3798
3827
unsigned int flags = update -> flags ;
3799
3828
3800
- if (is_null_sha1 (update -> new_sha1 ))
3829
+ if (( flags & REF_HAVE_NEW ) && is_null_sha1 (update -> new_sha1 ))
3801
3830
flags |= REF_DELETING ;
3802
3831
update -> lock = lock_ref_sha1_basic (
3803
3832
update -> refname ,
@@ -3819,8 +3848,9 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3819
3848
/* Perform updates first so live commits remain referenced */
3820
3849
for (i = 0 ; i < n ; i ++ ) {
3821
3850
struct ref_update * update = updates [i ];
3851
+ int flags = update -> flags ;
3822
3852
3823
- if (!is_null_sha1 (update -> new_sha1 )) {
3853
+ if (( flags & REF_HAVE_NEW ) && !is_null_sha1 (update -> new_sha1 )) {
3824
3854
if (write_ref_sha1 (update -> lock , update -> new_sha1 ,
3825
3855
update -> msg )) {
3826
3856
update -> lock = NULL ; /* freed by write_ref_sha1 */
@@ -3836,14 +3866,15 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3836
3866
/* Perform deletes now that updates are safely completed */
3837
3867
for (i = 0 ; i < n ; i ++ ) {
3838
3868
struct ref_update * update = updates [i ];
3869
+ int flags = update -> flags ;
3839
3870
3840
- if (update -> lock ) {
3871
+ if (( flags & REF_HAVE_NEW ) && is_null_sha1 ( update -> new_sha1 ) ) {
3841
3872
if (delete_ref_loose (update -> lock , update -> type , err )) {
3842
3873
ret = TRANSACTION_GENERIC_ERROR ;
3843
3874
goto cleanup ;
3844
3875
}
3845
3876
3846
- if (!(update -> flags & REF_ISPRUNING ))
3877
+ if (!(flags & REF_ISPRUNING ))
3847
3878
string_list_append (& refs_to_delete ,
3848
3879
update -> lock -> ref_name );
3849
3880
}
0 commit comments