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

Reply via email to