Skip to main content
DevOps Insightsguides & answers

Git · troubleshooting

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

Git found .git/index.lock, the file it uses to stop two commands changing the staging area at once, so it refused to start. Either another Git command really is running, or one crashed and left the lock behind.

Reproduced on Git 2.50.1, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 9 sections

Before you start

  • A terminal in the repository, and the path printed in the message.

Run this first

step 1 of 1
ls -l "$(git rev-parse --git-dir)/index.lock"; ps -ef | grep '[g]it '

Look for A lock with no process: safe to remove

Shows whether the lock exists for this checkout and whether any Git process could own it.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Is any git process running in this repository?

Cause space

3 of 3 still possible

  • Another Git command is still runningCommon
  • A Git command was killed or crashed and left the lockCommon
  • The lock belongs to a worktree or submoduleOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    ls -l "$(git rev-parse --git-dir)/index.lock"; ps -ef | grep '[g]it '

    Shows whether the lock exists for this checkout and whether any Git process could own it.

    Look for A lock with no process: safe to remove

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

Another Git command is still running

Common

A git commit -a or git commit with paths waiting in an editor in another terminal, a long rebase or merge, an IDE or Git client working in the same repository, or a second step of a script or CI job running Git at the same time.

Confirm

ps -ef | grep '[g]it '

A git process working in this repository

Fix

  • Let it finish, or close the editor or tool that started it. The lock disappears on its own.
  • In scripts and CI, do not run two Git commands on the same checkout in parallel.

A Git command was killed or crashed and left the lock

Common

Ctrl-C at the wrong moment, a cancelled CI job, a full disk, or a machine that lost power while Git was writing the index.

Confirm

ls -l .git/index.lock; ps -ef | grep '[g]it '

The lock exists and no git process is running

Fix

  • Once you are sure nothing is running, delete the lock named in the message, then run git status to check the staging area is what you expect.
rm .git/index.lock

Only after confirming no Git process is running. In a worktree, use the path from the message. Reproduced on Git 2.50.1: commands worked again at once.

The lock belongs to a worktree or submodule

Occasional

Linked worktrees and submodules keep their index under the main repository's .git directory, so the lock is not in the folder you are working in.

Confirm

git rev-parse --git-dir

The directory that holds this checkout's index.lock

Fix

  • Use the exact path from the error message; the same rules apply: check for running processes, then remove it.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

Before Git changes its staging area (the index), it creates index.lock so that no other Git command changes it at the same time, and removes it when done. If a Git command is killed or crashes, the lock stays, and every later command that needs the index stops, telling you to check for running processes first.

Words used on this page

Index
Git's staging area: the next commit as it stands. Stored in .git/index.
index.lock
A file Git creates while changing the index and removes afterwards. Its presence means a change is in progress, or was interrupted.
What is actually happening

Reproduced on Git 2.50.1 with a leftover .git/index.lock: git add, git commit -a and git checkout -b all failed with fatal: Unable to create '.../.git/index.lock': File exists., followed by Another git process seems to be running in this repository, and exited 128.

Two details make it confusing. git status still worked, so the repository looks healthy. And git stash failed with a different message, error: could not write index, for the same cause.

A live command can hold the lock legitimately: while git commit -a waited for its editor, a git add in another terminal failed with this error. A plain git commit, with files already staged, held no lock while its editor was open.

In a linked worktree the lock lives in the main repository, at .git/worktrees/NAME/index.lock, which is the path the message prints.

How to tell this is your problem
WhereWhat you see
git add, commit, checkout, merge, rebasefatal: Unable to create '/path/.git/index.lock': File exists. Another git process seems to be running in this repository...
git stasherror: could not write index

How to know it is actually fixed

  • git add or git commit works, and git status shows what you expect.

Stopping it happening again

  • Do not run Git commands in parallel on one checkout in scripts or CI.
  • Let commands finish rather than interrupting them mid-write.

Security considerations

  • Deleting the lock while a Git command is still running can corrupt the index that command is writing. Check for running Git processes first.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it