git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] credential-cache--daemon: allow a concurrently created socket dir

From
Farid Zakaria <farid.m.zakaria@gmail.com>
Date
Nov 1, 2026, 23:29 UTC
Message-ID
<20261101-fz-credential-cache-race-v1-1-28f0bac51e11@gmail.com>
In-Reply-To
<20261101-fz-credential-cache-race-v1-0-28f0bac51e11@gmail.com>

When no daemon is running, two "git credential-cache store" run at the same time each try to start one. If the socket directory does not exist yet, both daemons try to create it. The one that comes second dies:

    fatal: unable to mkdir '<home>/.cache/git/credential': File exists
That client then fails with "cache daemon did not start".

The fix is to ignore EEXIST from mkdir(), and check the directory's permissions the same way as for one that already existed.

Signed-off-by: Farid Zakaria <farid.m.zakaria@gmail.com>
---
 builtin/credential-cache--daemon.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c
index 65cc619bec..0dfa11e2ec 100644
--- a/builtin/credential-cache--daemon.c
+++ b/builtin/credential-cache--daemon.c
@@ -273,8 +273,18 @@ static void init_socket_directory(const char *path)
 		 */
 		if (safe_create_leading_directories_const(the_repository, dir) < 0)
 			die_errno("unable to create directories for '%s'", dir);
-		if (mkdir(dir, 0700) < 0)
-			die_errno("unable to mkdir '%s'", dir);
+		if (mkdir(dir, 0700) < 0) {
+			if (errno != EEXIST)
+				die_errno("unable to mkdir '%s'", dir);
+			/*
+			 * Another daemon created it first; check it like one
+			 * that already existed.
+			 */
+			if (stat(dir, &st))
+				die_errno("unable to stat '%s'", dir);
+			if (st.st_mode & 077)
+				die(_(permissions_advice), dir);
+		}
 	}
 
 	if (chdir(dir))
-- 
2.55.0
Previous: Farid ZakariaNext: Patrick Steinhardt
Message 2 of 14 in “credential-cache: fix two races when daemons start at once”
  1. 0/2 credential-cache: fix two races when daemons start at onceFarid Zakaria, Nov 1, 2026
  2. 1/2 credential-cache--daemon: allow a concurrently created socket dirFarid Zakaria, Nov 1, 2026
  3. Patrick SteinhardtNov 3, 2026
  4. Farid ZakariaNov 4, 2026
  5. Jeff KingNov 4, 2026
  6. 2/2 credential-cache--daemon: do not take over a running daemon's socketFarid Zakaria, Nov 1, 2026
  7. Patrick SteinhardtNov 3, 2026
  8. Farid ZakariaNov 4, 2026
  9. Junio C HamanoNov 3, 2026
  10. Jeff KingNov 4, 2026
  11. 0/3 credential-cache: fix two races when daemons start at onceFarid Zakaria, Nov 4, 2026
  12. 1/3 credential-cache--daemon: do not apply core.sharedRepositoryFarid Zakaria, Nov 4, 2026
  13. 2/3 credential-cache--daemon: allow a concurrently created socket dirFarid Zakaria, Nov 4, 2026
  14. 3/3 credential-cache--daemon: do not take over a running daemon's socketFarid Zakaria, Nov 4, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.