@@ -56,6 +56,12 @@ static unsigned char refname_disposition[256] = {
5656 */
5757#define REF_HAVE_OLD 0x10
5858
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+
5965/*
6066 * Try to read one refname component from the front of refname.
6167 * 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)
27882794 return ret ;
27892795}
27902796
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 );
27932800
27942801int rename_ref (const char * oldrefname , const char * newrefname , const char * logmsg )
27952802{
@@ -2847,7 +2854,9 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
28472854 goto rollback ;
28482855 }
28492856 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 )) {
28512860 error ("unable to write current sha1 into %s" , newrefname );
28522861 goto rollback ;
28532862 }
@@ -2863,7 +2872,8 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
28632872
28642873 flag = log_all_ref_updates ;
28652874 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 ))
28672877 error ("unable to write current sha1 into %s" , oldrefname );
28682878 log_all_ref_updates = flag ;
28692879
@@ -3052,11 +3062,11 @@ int is_branch(const char *refname)
30523062}
30533063
30543064/*
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 .
30573067 */
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 )
30603070{
30613071 static char term = '\n' ;
30623072 struct object * o ;
@@ -3085,6 +3095,17 @@ static int write_ref_sha1(struct ref_lock *lock,
30853095 errno = save_errno ;
30863096 return -1 ;
30873097 }
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+ {
30883109 clear_loose_ref_cache (& ref_cache );
30893110 if (log_ref_write (lock -> ref_name , lock -> old_sha1 , sha1 , logmsg ) < 0 ||
30903111 (strcmp (lock -> ref_name , lock -> orig_ref_name ) &&
@@ -3775,19 +3796,24 @@ int ref_transaction_commit(struct ref_transaction *transaction,
37753796 goto cleanup ;
37763797 }
37773798
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+ */
37793805 for (i = 0 ; i < n ; i ++ ) {
37803806 struct ref_update * update = updates [i ];
3781- unsigned int flags = update -> flags ;
37823807
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 ;
37853811 update -> lock = lock_ref_sha1_basic (
37863812 update -> refname ,
37873813 ((update -> flags & REF_HAVE_OLD ) ?
37883814 update -> old_sha1 : NULL ),
37893815 NULL ,
3790- flags ,
3816+ update -> flags ,
37913817 & update -> type );
37923818 if (!update -> lock ) {
37933819 ret = (errno == ENOTDIR )
@@ -3797,34 +3823,60 @@ int ref_transaction_commit(struct ref_transaction *transaction,
37973823 update -> refname );
37983824 goto cleanup ;
37993825 }
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 )) {
38083828 int overwriting_symref = ((update -> type & REF_ISSYMREF ) &&
38093829 (update -> flags & REF_NODEREF ));
38103830
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 )) {
38133833 /*
38143834 * The reference already has the desired
38153835 * value, so we don't need to write it.
38163836 */
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(): */
38183873 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 */
38223874 strbuf_addf (err , "Cannot update the ref '%s'." ,
38233875 update -> refname );
38243876 ret = TRANSACTION_GENERIC_ERROR ;
38253877 goto cleanup ;
38263878 } else {
3827- /* freed by write_ref_sha1 (): */
3879+ /* freed by commit_ref_update (): */
38283880 update -> lock = NULL ;
38293881 }
38303882 }
@@ -3833,15 +3885,14 @@ int ref_transaction_commit(struct ref_transaction *transaction,
38333885 /* Perform deletes now that updates are safely completed */
38343886 for (i = 0 ; i < n ; i ++ ) {
38353887 struct ref_update * update = updates [i ];
3836- int flags = update -> flags ;
38373888
3838- if (( flags & REF_HAVE_NEW ) && is_null_sha1 ( update -> new_sha1 ) ) {
3889+ if (update -> flags & REF_DELETING ) {
38393890 if (delete_ref_loose (update -> lock , update -> type , err )) {
38403891 ret = TRANSACTION_GENERIC_ERROR ;
38413892 goto cleanup ;
38423893 }
38433894
3844- if (!(flags & REF_ISPRUNING ))
3895+ if (!(update -> flags & REF_ISPRUNING ))
38453896 string_list_append (& refs_to_delete ,
38463897 update -> lock -> ref_name );
38473898 }
0 commit comments