Skip to content

Commit 3ad8b5b

Browse files
committed
Merge branch 'mh/ref-remove-empty-directory'
Deletion of a branch "foo/bar" could remove .git/refs/heads/foo once there no longer is any other branch whose name begins with "foo/", but we didn't do so so far. Now we do. * mh/ref-remove-empty-directory: (23 commits) files_transaction_commit(): clean up empty directories try_remove_empty_parents(): teach to remove parents of reflogs, too try_remove_empty_parents(): don't trash argument contents try_remove_empty_parents(): rename parameter "name" -> "refname" delete_ref_loose(): inline function delete_ref_loose(): derive loose reference path from lock log_ref_write_1(): inline function log_ref_setup(): manage the name of the reflog file internally log_ref_write_1(): don't depend on logfile argument log_ref_setup(): pass the open file descriptor back to the caller log_ref_setup(): improve robustness against races log_ref_setup(): separate code for create vs non-create log_ref_write(): inline function rename_tmp_log(): improve error reporting rename_tmp_log(): use raceproof_create_file() lock_ref_sha1_basic(): use raceproof_create_file() lock_ref_sha1_basic(): inline constant raceproof_create_file(): new function safe_create_leading_directories(): set errno on SCLD_EXISTS safe_create_leading_directories_const(): preserve errno ...
2 parents 538569b + 4463977 commit 3ad8b5b

File tree

6 files changed

+351
-195
lines changed

6 files changed

+351
-195
lines changed

cache.h

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,8 +1072,9 @@ int adjust_shared_perm(const char *path);
10721072

10731073
/*
10741074
* Create the directory containing the named path, using care to be
1075-
* somewhat safe against races. Return one of the scld_error values
1076-
* to indicate success/failure.
1075+
* somewhat safe against races. Return one of the scld_error values to
1076+
* indicate success/failure. On error, set errno to describe the
1077+
* problem.
10771078
*
10781079
* SCLD_VANISHED indicates that one of the ancestor directories of the
10791080
* path existed at one point during the function call and then
@@ -1097,6 +1098,49 @@ enum scld_error {
10971098
enum scld_error safe_create_leading_directories(char *path);
10981099
enum scld_error safe_create_leading_directories_const(const char *path);
10991100

1101+
/*
1102+
* Callback function for raceproof_create_file(). This function is
1103+
* expected to do something that makes dirname(path) permanent despite
1104+
* the fact that other processes might be cleaning up empty
1105+
* directories at the same time. Usually it will create a file named
1106+
* path, but alternatively it could create another file in that
1107+
* directory, or even chdir() into that directory. The function should
1108+
* return 0 if the action was completed successfully. On error, it
1109+
* should return a nonzero result and set errno.
1110+
* raceproof_create_file() treats two errno values specially:
1111+
*
1112+
* - ENOENT -- dirname(path) does not exist. In this case,
1113+
* raceproof_create_file() tries creating dirname(path)
1114+
* (and any parent directories, if necessary) and calls
1115+
* the function again.
1116+
*
1117+
* - EISDIR -- the file already exists and is a directory. In this
1118+
* case, raceproof_create_file() removes the directory if
1119+
* it is empty (and recursively any empty directories that
1120+
* it contains) and calls the function again.
1121+
*
1122+
* Any other errno causes raceproof_create_file() to fail with the
1123+
* callback's return value and errno.
1124+
*
1125+
* Obviously, this function should be OK with being called again if it
1126+
* fails with ENOENT or EISDIR. In other scenarios it will not be
1127+
* called again.
1128+
*/
1129+
typedef int create_file_fn(const char *path, void *cb);
1130+
1131+
/*
1132+
* Create a file in dirname(path) by calling fn, creating leading
1133+
* directories if necessary. Retry a few times in case we are racing
1134+
* with another process that is trying to clean up the directory that
1135+
* contains path. See the documentation for create_file_fn for more
1136+
* details.
1137+
*
1138+
* Return the value and set the errno that resulted from the most
1139+
* recent call of fn. fn is always called at least once, and will be
1140+
* called more than once if it returns ENOENT or EISDIR.
1141+
*/
1142+
int raceproof_create_file(const char *path, create_file_fn fn, void *cb);
1143+
11001144
int mkdir_in_gitdir(const char *path);
11011145
extern char *expand_user_path(const char *path);
11021146
const char *enter_repo(const char *path, int strict);

0 commit comments

Comments
 (0)