Skip to content

Commit 7af01f2

Browse files
hramrachgitster
authored andcommitted
worktree: fix worktree add race
Git runs a stat loop to find a worktree name that's available and then does mkdir on the found name. Turn it to mkdir loop to avoid another invocation of worktree add finding the same free name and creating the directory first. Signed-off-by: Michal Suchanek <[email protected]> Acked-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 36eb1cb commit 7af01f2

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

builtin/worktree.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ static int add_worktree(const char *path, const char *refname,
268268
struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
269269
struct strbuf sb = STRBUF_INIT;
270270
const char *name;
271-
struct stat st;
272271
struct child_process cp = CHILD_PROCESS_INIT;
273272
struct argv_array child_env = ARGV_ARRAY_INIT;
274-
int counter = 0, len, ret;
273+
unsigned int counter = 0;
274+
int len, ret;
275275
struct strbuf symref = STRBUF_INIT;
276276
struct commit *commit = NULL;
277277
int is_branch = 0;
@@ -295,8 +295,12 @@ static int add_worktree(const char *path, const char *refname,
295295
if (safe_create_leading_directories_const(sb_repo.buf))
296296
die_errno(_("could not create leading directories of '%s'"),
297297
sb_repo.buf);
298-
while (!stat(sb_repo.buf, &st)) {
298+
299+
while (mkdir(sb_repo.buf, 0777)) {
299300
counter++;
301+
if ((errno != EEXIST) || !counter /* overflow */)
302+
die_errno(_("could not create directory of '%s'"),
303+
sb_repo.buf);
300304
strbuf_setlen(&sb_repo, len);
301305
strbuf_addf(&sb_repo, "%d", counter);
302306
}
@@ -306,8 +310,6 @@ static int add_worktree(const char *path, const char *refname,
306310
atexit(remove_junk);
307311
sigchain_push_common(remove_junk_on_signal);
308312

309-
if (mkdir(sb_repo.buf, 0777))
310-
die_errno(_("could not create directory of '%s'"), sb_repo.buf);
311313
junk_git_dir = xstrdup(sb_repo.buf);
312314
is_junk = 1;
313315

0 commit comments

Comments
 (0)