What's Actually Happening

A previous git operation (commit, add, merge, etc.) was interrupted before it could complete and clean up. Git creates a .git/index.lock file to prevent concurrent modifications to the index. If the process crashes or is killed, this lock file remains, blocking all subsequent git operations that need to modify the index.

The Error You'll See

When trying any git command:

bash
fatal: Unable to create '.git/index.lock': File exists.

Or:

``` fatal: Unable to create '/path/to/repo/.git/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 to let it complete before trying again. If this is not the case, please manually delete the file. ```

During commit:

bash
error: Unable to create '.git/index.lock': File exists.
fatal: index file corrupt

During add:

bash
fatal: Unable to create '.git/index.lock': File exists.
fatal: index file corrupt

Why This Happens

The .git/index.lock file exists when: - A git process was killed (Ctrl+C, kill command, system crash) - An IDE or editor crashed while running git - A git operation timed out - System ran out of disk space during operation - Another git process is legitimately running - The operation was interrupted by shutdown - Network issues during remote operations

Git creates this lock to ensure only one process modifies the index at a time. It should be deleted when the operation completes, but crashes leave it behind.

Step 1: Verify No Git Process is Running

First, ensure no git operation is actually in progress:

bash
ps aux | grep git

Or more specifically:

bash
pgrep -a git

If you see a running git process:

bash
# Wait for it to complete, or if it's stuck:
kill -9 <pid>

On Windows:

powershell
tasklist | findstr git
taskkill /F /PID <pid>

Step 2: Locate the Lock File

Find the lock file:

bash
ls -la .git/index.lock

For bare repositories:

bash
ls -la /path/to/repo.git/index.lock

For worktrees:

bash
ls -la .git/worktrees/<name>/index.lock

Step 3: Verify Index Integrity

Before removing the lock, check if the actual index is okay:

bash
git status

If this shows errors, the index might be corrupted:

bash
git fsck

Step 4: Remove the Lock File

If no git process is running and the index seems fine, remove the lock:

bash
rm .git/index.lock

Or with full path:

bash
rm /path/to/repo/.git/index.lock

On Windows (PowerShell):

powershell
Remove-Item .git\index.lock

On Windows (Command Prompt):

cmd
del .git\index.lock

Step 5: Verify the Fix

Try the blocked operation again:

bash
git status
git add .
git commit -m "Test commit"

All should work normally now.

Step 6: Handle Corrupted Index

If you still get errors after removing the lock:

bash
rm .git/index
git reset

Or recreate the index from HEAD:

bash
git read-tree HEAD

Step 7: Recover Lost Changes

If you had staged changes that might be lost:

```bash # Check for dangling objects git fsck --lost-found

# Look for blob data ls .git/lost-found/other/ ```

Recover from .git/lost-found/:

bash
# Each file is a lost object
for f in .git/lost-found/other/*; do
    echo "=== $f ==="
    git cat-file -t $(basename $f) 2>/dev/null && git cat-file -p $(basename $f) | head -20
done

Step 8: Prevent Future Locks

To avoid this issue:

  • Don't kill git processes abruptly (let them finish or fail naturally)
  • Ensure adequate disk space before large operations
  • Check for background git processes before closing IDEs
  • Use git gc periodically to clean up

Step 9: Handle Multiple Lock Files

Sometimes other lock files exist:

bash
find .git -name "*.lock" -type f

Remove stale locks:

bash
find .git -name "*.lock" -type f -delete

But be careful not to remove locks for running processes.

Step 10: Handle submodule Locks

For repositories with submodules:

```bash # Find submodule locks find .git/modules -name "*.lock" -type f

# Remove if stale find .git/modules -name "*.lock" -type f -delete ```

Verify the Fix

Confirm the lock is gone:

bash
ls .git/index.lock

Should return:

bash
ls: cannot access '.git/index.lock': No such file or directory

Test all git operations:

bash
git status
git log -1
git branch
git remote -v

Make a test commit:

bash
echo "test" > test.txt
git add test.txt
git commit -m "Test after lock removal"
git rm test.txt
git commit -m "Cleanup test file"

All operations should complete without errors. The repository is now back to a normal working state.