@@ -2906,6 +2906,14 @@ char *git_config_prepare_comment_string(const char *comment)
29062906 return prepared ;
29072907}
29082908
2909+ /*
2910+ * How long to retry acquiring config.lock when another process holds it.
2911+ * The lock is held only for the duration of rewriting a small file, so
2912+ * 100 ms covers any realistic contention while still failing fast if
2913+ * a stale lock has been left behind by a crashed process.
2914+ */
2915+ #define CONFIG_LOCK_TIMEOUT_MS 100
2916+
29092917static void validate_comment_string (const char * comment )
29102918{
29112919 size_t leading_blanks ;
@@ -2989,7 +2997,8 @@ int repo_config_set_multivar_in_file_gently(struct repository *r,
29892997 * The lock serves a purpose in addition to locking: the new
29902998 * contents of .git/config will be written into it.
29912999 */
2992- fd = hold_lock_file_for_update (& lock , config_filename , 0 );
3000+ fd = hold_lock_file_for_update_timeout (& lock , config_filename , 0 ,
3001+ CONFIG_LOCK_TIMEOUT_MS );
29933002 if (fd < 0 ) {
29943003 error_errno (_ ("could not lock config file %s" ), config_filename );
29953004 ret = CONFIG_NO_LOCK ;
@@ -3334,7 +3343,8 @@ static int repo_config_copy_or_rename_section_in_file(
33343343 if (!config_filename )
33353344 config_filename = filename_buf = repo_git_path (r , "config" );
33363345
3337- out_fd = hold_lock_file_for_update (& lock , config_filename , 0 );
3346+ out_fd = hold_lock_file_for_update_timeout (& lock , config_filename , 0 ,
3347+ CONFIG_LOCK_TIMEOUT_MS );
33383348 if (out_fd < 0 ) {
33393349 ret = error (_ ("could not lock config file %s" ), config_filename );
33403350 goto out ;
0 commit comments