何が起きたのか
git add、git commit、または git pull を実行したら、こんなエラーが出た:
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 all processes
are stopped then try again. If it still fails, a git process
may have crashed in this repository earlier: remove the file manually
and restart.
Git は .git/index.lock をミューテックスとして使用している。インデックスを変更する操作が始まると、Git はこのファイルを作成する。操作が正常に完了すると、Git はそれを削除する。Git が操作の途中でクラッシュしたり、Ctrl+C で強制終了されたり、別のターミナルでまだ実行中だったりすると、このファイルが残ったままになる。その後の Git コマンドはこのファイルを見つけ、ファイルが消えるまでインデックスへの操作を拒否する。
ステップ1:別の Git プロセスが実際に動いているか確認する
まだ何も削除しないこと。まず、ロックが本当に古くなったものであり、実行中の操作を保護していないことを確認する。
Linux / macOS の場合
# リポジトリに触れている git プロセスを確認する
ps aux | grep git
作業ディレクトリがリポジトリと一致する git プロセスを探す。エディタも確認すること — VS Code、Vim、JetBrains IDE はいずれも、ステータスバー、blame ガター、差分パネルのためにバックグラウンドで git プロセスを起動している。これらのどれかが原因である可能性がある。
Windows(PowerShell)の場合
Get-Process | Where-Object { $_.Name -like "*git*" }
Windows(Git Bash / WSL)の場合
ps aux | grep git
# または
tasklist | grep git
実行中の Git プロセスが見つかった場合は、それを終了させるか完了するまで待ってから、元のコマンドを再試行する。何も実行されていない場合は、ロックの削除に進む。
ステップ2:ロックファイルの存在を確認する
ls -la .git/index.lock
次のような出力が表示される:
-rw-r--r-- 1 ubuntu ubuntu 0 May 8 02:14 .git/index.lock
タイムスタンプを確認する。Git プロセスが実行されていないのに、20分前や昨日から残っているファイルは古くなったロックだ。削除しても問題ない。
ステップ3:古いロックファイルを削除する
Linux / macOS
rm -f .git/index.lock
Windows(PowerShell)
Remove-Item .git\index.lock -Force
Windows(Git Bash)
rm -f .git/index.lock
-f フラグは、確認と削除の間にファイルが消えた場合のエラーを防ぐ — どちらにしても害はない。
ステップ4:Git が正常に動作していることを確認する
# 読み取り専用の確認 — 副作用なし
git status
エラーなしでワーキングツリーの出力が表示されたら問題ない。元々やろうとしていた操作を再実行する:
git add .
git commit -m "your message"
# または
git pull origin main
エッジケース:複数のロックファイル
ハードクラッシュによって、インデックスだけでなく他の Git オブジェクトにもロックファイルが散らばることがある。index.lock を削除してもまだエラーが発生する場合は、.git ディレクトリ全体を確認する:
# .git ディレクトリ内のすべての .lock ファイルを検索する
find .git -name "*.lock" -type f
よく見つかるファイル:
.git/index.lock— 最もよくある原因、インデックス操作をブロックする.git/refs/heads/main.lock— ref の更新をブロックする(失敗したプッシュやコミットによって残る).git/HEAD.lock— まれ、HEAD の書き込みをブロックする.git/packed-refs.lock— pack-ref 操作をブロックする
実行中の Git プロセスがない場合は、一度にすべて削除する:
find .git -name "*.lock" -type f -delete
なぜ繰り返し起きるのか(そして防ぐ方法)
エディタのプラグインが最大の原因
VS Code の Git パネル、JetBrains のバージョン管理ウィンドウ、Sublime Merge — これらはすべてバックグラウンドで数秒ごとに git status をポーリングしている。リフレッシュ中にクラッシュすると古いロックが残る。簡単な対策が2つある:ターミナルから Git を実行する前にエディタを閉じる、またはエディタの Git 統合を別のワークツリーに向けることで、メインの .git ディレクトリに触れないようにする。
ターミナルセッションの中断
コミット中に Ctrl+C を押したり、SSH が切断されたり、コンテナが再起動したりすると、クリーンアップなしに Git が終了する。リモートマシンに SSH で接続して作業する場合は、tmux や screen の中で Git コマンドを実行すること — セッションが切断後も生き残り、Git が正常に完了する:
tmux new -s work
# ここで git コマンドを実行する
# 後で再接続する場合: tmux attach -t work
並列で動く CI/CD パイプライン
2つのパイプラインジョブが同じクローンディレクトリで同時に git fetch を実行すると競合が起きる。一方は成功し、もう一方はこのエラーを投げる。修正は簡単だ:各ジョブに新しいクローンを与えること。GitHub Actions では、永続的なワークスペースを持つ共有セルフホストランナーを使っているチームでこの問題が起きやすい。同じブランチでの実行を直列化するために concurrency グループを追加する:
# .github/workflows/deploy.yml
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true
クイックリファレンス
- 実行中のプロセスを確認:
ps aux | grep git - すべてのロックファイルを検索:
find .git -name "*.lock" - インデックスロックを削除:
rm -f .git/index.lock - すべてのロックを削除(実行中プロセスなし):
find .git -name "*.lock" -delete - 確認:
git status

