llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-format Author: Marco Barbone (DiamonDinoia) <details> <summary>Changes</summary> Dear team, this is my first contribution. I used Claude to investigate the problem as I do not know the codebase too well. I read the policy and AI assistance is allowed. Let me know if I am violating any policy or if there are any problems I am more than happy to fix them. Thanks for you patience. `git-clang-format` uses a fixed path (`.git/clang-format-index`) for its temporary index file. When concurrent git operations interact with this file (most commonly via the [pre-commit](https://pre-commit.com/) framework), git's internal locking creates `.git/clang-format-index.lock` which persists after abnormal exits, **blocking all subsequent commits**. The fix replaces the fixed path with a unique temporary file via `tempfile.mkstemp()`. ## How to reproduce 1. Add `git-clang-format --staged` as a [pre-commit](https://pre-commit.com/) hook: ```yaml # .pre-commit-config.yaml repos: - repo: local hooks: - id: clang-format-staged name: clang-format (staged hunks) entry: git-clang-format --binary clang-format --staged language: python additional_dependencies: [clang-format==22.*] pass_filenames: true types_or: [c++, c, cuda] files: \.(c|cc|cpp|h|hpp|cu|cuh)$ ``` 2. Stage C/C++ files and run git commit repeatedly. After a few commits (especially ones where clang-format modifies files), the hook leaves behind .git/clang-format-index.lock. 3. All subsequent commits fail with: ``` fatal: Unable to create '/path/to/repo/.git/clang-format-index.lock': File exists. Another git process seems to be running in this repository, e.g. an editor opened by 'git commit'. Please make sure all processes are terminated then try again. If it still fails, a git process may have crashed in this repository earlier: remove the file manually to continue. error: `git update-index --add -z --index-info` failed ``` The only recovery is rm .git/clang-format-index.lock. ### Root cause create_temporary_index() in clang/tools/clang-format/git-clang-format writes to a fixed, non-unique path: ``` path = os.path.join(gitdir, temp_index_basename) # always ".git/clang-format-index" ``` When git update-index operates on this file, git creates clang-format-index.lock. If the process is interrupted (pre-commit timeout, signal, or concurrent git operations from other hooks in the same pipeline), the lock file is never cleaned up. The temporary_index_file() context manager removes the index file on exit but not the .lock file that git creates alongside it. ### Fix: Replace the fixed path with tempfile.mkstemp(), so each invocation gets a unique filename. This eliminates both the stale lock problem and any potential race between concurrent invocations. ``` --- Full diff: https://github.com/llvm/llvm-project/pull/187379.diff 1 Files Affected: - (modified) clang/tools/clang-format/git-clang-format (+7-1) ``````````diff diff --git a/clang/tools/clang-format/git-clang-format b/clang/tools/clang-format/git-clang-format index dcc0a5347f5d2..ef578467bbc5d 100755 --- a/clang/tools/clang-format/git-clang-format +++ b/clang/tools/clang-format/git-clang-format @@ -31,6 +31,7 @@ import os import re import subprocess import sys +import tempfile usage = "git clang-format [OPTIONS] [<commit>] [<commit>|--staged] [--] [<file>...]" @@ -707,7 +708,12 @@ def create_temporary_index(tree=None): If `tree` is not None, use that as the tree to read in. Otherwise, an empty index is created.""" gitdir = run("git", "rev-parse", "--git-dir") - path = os.path.join(gitdir, temp_index_basename) + # Use a unique filename to avoid stale .lock files when concurrent git + # operations (e.g. pre-commit hooks) race with this process. + fd, path = tempfile.mkstemp( + prefix=temp_index_basename + "-", dir=gitdir + ) + os.close(fd) if tree is None: tree = "--empty" run("git", "read-tree", "--index-output=" + path, tree) `````````` </details> https://github.com/llvm/llvm-project/pull/187379 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
