@@ -30,6 +30,13 @@ static unsigned char refname_disposition[256] = {
30
30
* pruned.
31
31
*/
32
32
#define REF_ISPRUNING 0x0100
33
+
34
+ /*
35
+ * Used as a flag in ref_update::flags when the lockfile needs to be
36
+ * committed.
37
+ */
38
+ #define REF_NEEDS_COMMIT 0x0200
39
+
33
40
/*
34
41
* Try to read one refname component from the front of refname.
35
42
* Return the length of the component found, or -1 if the component is
@@ -2747,8 +2754,9 @@ static int rename_ref_available(const char *oldname, const char *newname)
2747
2754
return ret ;
2748
2755
}
2749
2756
2750
- static int write_ref_sha1 (struct ref_lock * lock , const unsigned char * sha1 ,
2751
- const char * logmsg );
2757
+ static int write_ref_to_lockfile (struct ref_lock * lock , const unsigned char * sha1 );
2758
+ static int commit_ref_update (struct ref_lock * lock ,
2759
+ const unsigned char * sha1 , const char * logmsg );
2752
2760
2753
2761
int rename_ref (const char * oldrefname , const char * newrefname , const char * logmsg )
2754
2762
{
@@ -2807,7 +2815,9 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2807
2815
}
2808
2816
lock -> force_write = 1 ;
2809
2817
hashcpy (lock -> old_sha1 , orig_sha1 );
2810
- if (write_ref_sha1 (lock , orig_sha1 , logmsg )) {
2818
+
2819
+ if (write_ref_to_lockfile (lock , orig_sha1 ) ||
2820
+ commit_ref_update (lock , orig_sha1 , logmsg )) {
2811
2821
error ("unable to write current sha1 into %s" , newrefname );
2812
2822
goto rollback ;
2813
2823
}
@@ -2824,7 +2834,8 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2824
2834
lock -> force_write = 1 ;
2825
2835
flag = log_all_ref_updates ;
2826
2836
log_all_ref_updates = 0 ;
2827
- if (write_ref_sha1 (lock , orig_sha1 , NULL ))
2837
+ if (write_ref_to_lockfile (lock , orig_sha1 ) ||
2838
+ commit_ref_update (lock , orig_sha1 , NULL ))
2828
2839
error ("unable to write current sha1 into %s" , oldrefname );
2829
2840
log_all_ref_updates = flag ;
2830
2841
@@ -2996,23 +3007,15 @@ int is_branch(const char *refname)
2996
3007
}
2997
3008
2998
3009
/*
2999
- * Write sha1 into the ref specified by the lock. Make sure that errno
3000
- * is sane on error .
3010
+ * Write sha1 into the open lockfile, then close the lockfile. On
3011
+ * errors, rollback the lockfile and set errno to reflect the problem .
3001
3012
*/
3002
- static int write_ref_sha1 (struct ref_lock * lock ,
3003
- const unsigned char * sha1 , const char * logmsg )
3013
+ static int write_ref_to_lockfile (struct ref_lock * lock ,
3014
+ const unsigned char * sha1 )
3004
3015
{
3005
3016
static char term = '\n' ;
3006
3017
struct object * o ;
3007
3018
3008
- if (!lock ) {
3009
- errno = EINVAL ;
3010
- return -1 ;
3011
- }
3012
- if (!lock -> force_write && !hashcmp (lock -> old_sha1 , sha1 )) {
3013
- unlock_ref (lock );
3014
- return 0 ;
3015
- }
3016
3019
o = parse_object (sha1 );
3017
3020
if (!o ) {
3018
3021
error ("Trying to write ref %s with nonexistent object %s" ,
@@ -3037,6 +3040,17 @@ static int write_ref_sha1(struct ref_lock *lock,
3037
3040
errno = save_errno ;
3038
3041
return -1 ;
3039
3042
}
3043
+ return 0 ;
3044
+ }
3045
+
3046
+ /*
3047
+ * Commit a change to a loose reference that has already been written
3048
+ * to the loose reference lockfile. Also update the reflogs if
3049
+ * necessary, using the specified lockmsg (which can be NULL).
3050
+ */
3051
+ static int commit_ref_update (struct ref_lock * lock ,
3052
+ const unsigned char * sha1 , const char * logmsg )
3053
+ {
3040
3054
clear_loose_ref_cache (& ref_cache );
3041
3055
if (log_ref_write (lock -> ref_name , lock -> old_sha1 , sha1 , logmsg ) < 0 ||
3042
3056
(strcmp (lock -> ref_name , lock -> orig_ref_name ) &&
@@ -3738,19 +3752,23 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3738
3752
goto cleanup ;
3739
3753
}
3740
3754
3741
- /* Acquire all locks while verifying old values */
3755
+ /*
3756
+ * Acquire all locks, verify old values if provided, check
3757
+ * that new values are valid, and write new values to the
3758
+ * lockfiles, ready to be activated. Only keep one lockfile
3759
+ * open at a time to avoid running out of file descriptors.
3760
+ */
3742
3761
for (i = 0 ; i < n ; i ++ ) {
3743
3762
struct ref_update * update = updates [i ];
3744
- int flags = update -> flags ;
3745
3763
3746
3764
if (is_null_sha1 (update -> new_sha1 ))
3747
- flags |= REF_DELETING ;
3765
+ update -> flags |= REF_DELETING ;
3748
3766
update -> lock = lock_ref_sha1_basic (update -> refname ,
3749
3767
(update -> have_old ?
3750
3768
update -> old_sha1 :
3751
3769
NULL ),
3752
3770
NULL ,
3753
- flags ,
3771
+ update -> flags ,
3754
3772
& update -> type );
3755
3773
if (!update -> lock ) {
3756
3774
ret = (errno == ENOTDIR )
@@ -3760,30 +3778,59 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3760
3778
update -> refname );
3761
3779
goto cleanup ;
3762
3780
}
3781
+ if (!(update -> flags & REF_DELETING ) &&
3782
+ (update -> lock -> force_write ||
3783
+ hashcmp (update -> lock -> old_sha1 , update -> new_sha1 ))) {
3784
+ if (write_ref_to_lockfile (update -> lock , update -> new_sha1 )) {
3785
+ /*
3786
+ * The lock was freed upon failure of
3787
+ * write_ref_to_lockfile():
3788
+ */
3789
+ update -> lock = NULL ;
3790
+ strbuf_addf (err , "Cannot update the ref '%s'." ,
3791
+ update -> refname );
3792
+ ret = TRANSACTION_GENERIC_ERROR ;
3793
+ goto cleanup ;
3794
+ }
3795
+ update -> flags |= REF_NEEDS_COMMIT ;
3796
+ } else {
3797
+ /*
3798
+ * We didn't have to write anything to the lockfile.
3799
+ * Close it to free up the file descriptor:
3800
+ */
3801
+ if (close_ref (update -> lock )) {
3802
+ strbuf_addf (err , "Couldn't close %s.lock" ,
3803
+ update -> refname );
3804
+ goto cleanup ;
3805
+ }
3806
+ }
3763
3807
}
3764
3808
3765
3809
/* Perform updates first so live commits remain referenced */
3766
3810
for (i = 0 ; i < n ; i ++ ) {
3767
3811
struct ref_update * update = updates [i ];
3768
3812
3769
- if (!is_null_sha1 (update -> new_sha1 )) {
3770
- if (write_ref_sha1 (update -> lock , update -> new_sha1 ,
3771
- update -> msg )) {
3772
- update -> lock = NULL ; /* freed by write_ref_sha1 */
3813
+ if (update -> flags & REF_NEEDS_COMMIT ) {
3814
+ if (commit_ref_update (update -> lock ,
3815
+ update -> new_sha1 , update -> msg )) {
3816
+ /* The lock was freed by commit_ref_update(): */
3817
+ update -> lock = NULL ;
3773
3818
strbuf_addf (err , "Cannot update the ref '%s'." ,
3774
3819
update -> refname );
3775
3820
ret = TRANSACTION_GENERIC_ERROR ;
3776
3821
goto cleanup ;
3822
+ } else {
3823
+ /* freed by the above call: */
3824
+ update -> lock = NULL ;
3777
3825
}
3778
- update -> lock = NULL ; /* freed by write_ref_sha1 */
3779
3826
}
3780
3827
}
3781
3828
3782
3829
/* Perform deletes now that updates are safely completed */
3783
3830
for (i = 0 ; i < n ; i ++ ) {
3784
3831
struct ref_update * update = updates [i ];
3785
3832
3786
- if (update -> lock ) {
3833
+ if (update -> flags & REF_DELETING ) {
3787
3834
if (delete_ref_loose (update -> lock , update -> type , err )) {
3788
3835
ret = TRANSACTION_GENERIC_ERROR ;
3789
3836
goto cleanup ;
0 commit comments