@@ -56,6 +56,12 @@ static unsigned char refname_disposition[256] = {
56
56
*/
57
57
#define REF_HAVE_OLD 0x10
58
58
59
+ /*
60
+ * Used as a flag in ref_update::flags when the lockfile needs to be
61
+ * committed.
62
+ */
63
+ #define REF_NEEDS_COMMIT 0x20
64
+
59
65
/*
60
66
* Try to read one refname component from the front of refname.
61
67
* Return the length of the component found, or -1 if the component is
@@ -2788,8 +2794,9 @@ static int rename_ref_available(const char *oldname, const char *newname)
2788
2794
return ret ;
2789
2795
}
2790
2796
2791
- static int write_ref_sha1 (struct ref_lock * lock , const unsigned char * sha1 ,
2792
- const char * logmsg );
2797
+ static int write_ref_to_lockfile (struct ref_lock * lock , const unsigned char * sha1 );
2798
+ static int commit_ref_update (struct ref_lock * lock ,
2799
+ const unsigned char * sha1 , const char * logmsg );
2793
2800
2794
2801
int rename_ref (const char * oldrefname , const char * newrefname , const char * logmsg )
2795
2802
{
@@ -2847,7 +2854,9 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2847
2854
goto rollback ;
2848
2855
}
2849
2856
hashcpy (lock -> old_sha1 , orig_sha1 );
2850
- if (write_ref_sha1 (lock , orig_sha1 , logmsg )) {
2857
+
2858
+ if (write_ref_to_lockfile (lock , orig_sha1 ) ||
2859
+ commit_ref_update (lock , orig_sha1 , logmsg )) {
2851
2860
error ("unable to write current sha1 into %s" , newrefname );
2852
2861
goto rollback ;
2853
2862
}
@@ -2863,7 +2872,8 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
2863
2872
2864
2873
flag = log_all_ref_updates ;
2865
2874
log_all_ref_updates = 0 ;
2866
- if (write_ref_sha1 (lock , orig_sha1 , NULL ))
2875
+ if (write_ref_to_lockfile (lock , orig_sha1 ) ||
2876
+ commit_ref_update (lock , orig_sha1 , NULL ))
2867
2877
error ("unable to write current sha1 into %s" , oldrefname );
2868
2878
log_all_ref_updates = flag ;
2869
2879
@@ -3052,11 +3062,11 @@ int is_branch(const char *refname)
3052
3062
}
3053
3063
3054
3064
/*
3055
- * Write sha1 into the ref specified by the lock. Make sure that errno
3056
- * is sane on error .
3065
+ * Write sha1 into the open lockfile, then close the lockfile. On
3066
+ * errors, rollback the lockfile and set errno to reflect the problem .
3057
3067
*/
3058
- static int write_ref_sha1 (struct ref_lock * lock ,
3059
- const unsigned char * sha1 , const char * logmsg )
3068
+ static int write_ref_to_lockfile (struct ref_lock * lock ,
3069
+ const unsigned char * sha1 )
3060
3070
{
3061
3071
static char term = '\n' ;
3062
3072
struct object * o ;
@@ -3085,6 +3095,17 @@ static int write_ref_sha1(struct ref_lock *lock,
3085
3095
errno = save_errno ;
3086
3096
return -1 ;
3087
3097
}
3098
+ return 0 ;
3099
+ }
3100
+
3101
+ /*
3102
+ * Commit a change to a loose reference that has already been written
3103
+ * to the loose reference lockfile. Also update the reflogs if
3104
+ * necessary, using the specified lockmsg (which can be NULL).
3105
+ */
3106
+ static int commit_ref_update (struct ref_lock * lock ,
3107
+ const unsigned char * sha1 , const char * logmsg )
3108
+ {
3088
3109
clear_loose_ref_cache (& ref_cache );
3089
3110
if (log_ref_write (lock -> ref_name , lock -> old_sha1 , sha1 , logmsg ) < 0 ||
3090
3111
(strcmp (lock -> ref_name , lock -> orig_ref_name ) &&
@@ -3775,19 +3796,24 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3775
3796
goto cleanup ;
3776
3797
}
3777
3798
3778
- /* Acquire all locks while verifying old values */
3799
+ /*
3800
+ * Acquire all locks, verify old values if provided, check
3801
+ * that new values are valid, and write new values to the
3802
+ * lockfiles, ready to be activated. Only keep one lockfile
3803
+ * open at a time to avoid running out of file descriptors.
3804
+ */
3779
3805
for (i = 0 ; i < n ; i ++ ) {
3780
3806
struct ref_update * update = updates [i ];
3781
- unsigned int flags = update -> flags ;
3782
3807
3783
- if ((flags & REF_HAVE_NEW ) && is_null_sha1 (update -> new_sha1 ))
3784
- flags |= REF_DELETING ;
3808
+ if ((update -> flags & REF_HAVE_NEW ) &&
3809
+ is_null_sha1 (update -> new_sha1 ))
3810
+ update -> flags |= REF_DELETING ;
3785
3811
update -> lock = lock_ref_sha1_basic (
3786
3812
update -> refname ,
3787
3813
((update -> flags & REF_HAVE_OLD ) ?
3788
3814
update -> old_sha1 : NULL ),
3789
3815
NULL ,
3790
- flags ,
3816
+ update -> flags ,
3791
3817
& update -> type );
3792
3818
if (!update -> lock ) {
3793
3819
ret = (errno == ENOTDIR )
@@ -3797,34 +3823,60 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3797
3823
update -> refname );
3798
3824
goto cleanup ;
3799
3825
}
3800
- }
3801
-
3802
- /* Perform updates first so live commits remain referenced */
3803
- for (i = 0 ; i < n ; i ++ ) {
3804
- struct ref_update * update = updates [i ];
3805
- int flags = update -> flags ;
3806
-
3807
- if ((flags & REF_HAVE_NEW ) && !is_null_sha1 (update -> new_sha1 )) {
3826
+ if ((update -> flags & REF_HAVE_NEW ) &&
3827
+ !(update -> flags & REF_DELETING )) {
3808
3828
int overwriting_symref = ((update -> type & REF_ISSYMREF ) &&
3809
3829
(update -> flags & REF_NODEREF ));
3810
3830
3811
- if (!overwriting_symref
3812
- && !hashcmp (update -> lock -> old_sha1 , update -> new_sha1 )) {
3831
+ if (!overwriting_symref &&
3832
+ !hashcmp (update -> lock -> old_sha1 , update -> new_sha1 )) {
3813
3833
/*
3814
3834
* The reference already has the desired
3815
3835
* value, so we don't need to write it.
3816
3836
*/
3817
- unlock_ref (update -> lock );
3837
+ } else if (write_ref_to_lockfile (update -> lock ,
3838
+ update -> new_sha1 )) {
3839
+ /*
3840
+ * The lock was freed upon failure of
3841
+ * write_ref_to_lockfile():
3842
+ */
3843
+ update -> lock = NULL ;
3844
+ strbuf_addf (err , "Cannot update the ref '%s'." ,
3845
+ update -> refname );
3846
+ ret = TRANSACTION_GENERIC_ERROR ;
3847
+ goto cleanup ;
3848
+ } else {
3849
+ update -> flags |= REF_NEEDS_COMMIT ;
3850
+ }
3851
+ }
3852
+ if (!(update -> flags & REF_NEEDS_COMMIT )) {
3853
+ /*
3854
+ * We didn't have to write anything to the lockfile.
3855
+ * Close it to free up the file descriptor:
3856
+ */
3857
+ if (close_ref (update -> lock )) {
3858
+ strbuf_addf (err , "Couldn't close %s.lock" ,
3859
+ update -> refname );
3860
+ goto cleanup ;
3861
+ }
3862
+ }
3863
+ }
3864
+
3865
+ /* Perform updates first so live commits remain referenced */
3866
+ for (i = 0 ; i < n ; i ++ ) {
3867
+ struct ref_update * update = updates [i ];
3868
+
3869
+ if (update -> flags & REF_NEEDS_COMMIT ) {
3870
+ if (commit_ref_update (update -> lock ,
3871
+ update -> new_sha1 , update -> msg )) {
3872
+ /* freed by commit_ref_update(): */
3818
3873
update -> lock = NULL ;
3819
- } else if (write_ref_sha1 (update -> lock , update -> new_sha1 ,
3820
- update -> msg )) {
3821
- update -> lock = NULL ; /* freed by write_ref_sha1 */
3822
3874
strbuf_addf (err , "Cannot update the ref '%s'." ,
3823
3875
update -> refname );
3824
3876
ret = TRANSACTION_GENERIC_ERROR ;
3825
3877
goto cleanup ;
3826
3878
} else {
3827
- /* freed by write_ref_sha1 (): */
3879
+ /* freed by commit_ref_update (): */
3828
3880
update -> lock = NULL ;
3829
3881
}
3830
3882
}
@@ -3833,15 +3885,14 @@ int ref_transaction_commit(struct ref_transaction *transaction,
3833
3885
/* Perform deletes now that updates are safely completed */
3834
3886
for (i = 0 ; i < n ; i ++ ) {
3835
3887
struct ref_update * update = updates [i ];
3836
- int flags = update -> flags ;
3837
3888
3838
- if (( flags & REF_HAVE_NEW ) && is_null_sha1 ( update -> new_sha1 ) ) {
3889
+ if (update -> flags & REF_DELETING ) {
3839
3890
if (delete_ref_loose (update -> lock , update -> type , err )) {
3840
3891
ret = TRANSACTION_GENERIC_ERROR ;
3841
3892
goto cleanup ;
3842
3893
}
3843
3894
3844
- if (!(flags & REF_ISPRUNING ))
3895
+ if (!(update -> flags & REF_ISPRUNING ))
3845
3896
string_list_append (& refs_to_delete ,
3846
3897
update -> lock -> ref_name );
3847
3898
}
0 commit comments