冒頭まとめ

git statusやgit addで次のエラーが出たら、まずコマンドを実行している場所を確認します。

fatal: not a git repository (or any of the parent directories): .git

Gitが、その場所から利用できるリポジトリを見つけられていません。cloneでできたディレクトリへ移動せず、その親で操作している場合もあります。

cd repo
git status

repoは実際の保存先に置き換えます。既存のリポジトリを使うつもりなら、エラーを消すためにその場でgit initするのではなく、正しい場所を確認してください。

Gitは現在の場所から親へ探す

Gitの公式文書は、現在のディレクトリにリポジトリがなければ、親をたどって探すと説明しています。既定ではファイルシステムの境界を越えません。環境変数によって探索先が指定・制限されている場合もあります。

通常の作業ディレクトリでは、.gitに履歴や設定の管理情報があります。ただし、Gitが探すのは子ディレクトリではありません。Downloads/repoがリポジトリでも、Downloadsからgit statusを実行して、その中のrepoを自動で選ぶわけではありません。

反対に、リポジトリの下にあるrepo/srcからは、通常は親の管理情報を見つけられます。必ず一番上で実行しなければならない、という意味でもありません。

このエラーは、Gitのインストール失敗や通信障害を直接示すものではありません。少なくとも、表示されたGitのコマンドは起動しています。

現在の場所とclone先を確認する

macOS・Linux・Git Bashでは、次で現在の場所と隠しファイルを確認できます。

pwd
ls -a

Windowsのコマンドプロンプトでは次を使います。

cd
dir /a

リポジトリと思われる場所へ移動し、Git自身に確認させます。

git rev-parse --is-inside-work-tree
git rev-parse --show-toplevel

rev-parseの公式文書によると、最初の指定は作業ディレクトリ内ならtrueを表示し、後の指定は作業ディレクトリの最上位を表示します。今回のGit 2.51.1による確認では、リポジトリ外の最初のコマンドは、冒頭のエラーで終了コード128となりました。

cloneの公式文書は、新しいディレクトリにリポジトリを複製する操作を説明しています。保存先の名前を明示すると、移動先も分かりやすくなります。

git clone <repository-url> repo
cd repo
git status

<repository-url>は実際のURLへ置き換えます。cloneが失敗していた場合は、その出力を先に確認してください。

場所を移動せずに指定する方法もあります。

git -C repo status

-Cは、指定した場所でGitを実行するための指定です。エディターや自動処理から呼んでいる場合も、実際の作業場所がどこになっているかを確認します。

GitHub DesktopのIssue #11413には、指定した親ディレクトリではなく、その下のリポジトリ名のディレクトリに.gitが作られたという報告があります。今回のCLIの全文と同じ表示の報告ではありませんが、保存先の思い違いを確認する関連事例です。

新規管理とZIPからの取得を区別する

自分のファイルを新しくGitで管理し始めたい場合は、対象ディレクトリで初期化します。

cd my-project
git init
git status

initの公式文書は、空のリポジトリを作る、または既存のリポジトリを再初期化する操作と説明しています。新規初期化だけでは、ほかの場所にあった過去の履歴やリモート設定が戻るわけではありません。

GitHubのDownload ZIPで取得したものも、cloneとは異なります。GitHubのアーカイブ公式説明では、ZIPなどのアーカイブはファイルのスナップショットで、リポジトリの履歴を含まないと説明しています。

元の履歴と接続して作業したいなら、別の新しい場所へcloneします。ZIP側や元の作業ディレクトリに変更がある場合は、それを残したまま、必要なファイルをclone先へ移し、差分を確認してください。.gitを上書きするコピーは行いません。

.gitがあっても認識されない場合

空の.gitディレクトリを作るだけでは、リポジトリにはなりません。今回の確認でも、空の.gitだけがある場所のgit statusは同じエラーになりました。

Git 2.51.1の探索実装には、HEADの書式、オブジェクトの保存先、参照情報を確認する処理があります。ただし、それらが必ず同じ.gitの直下に全部あるとは限りません。

リポジトリ構成の公式文書によると、.gitはディレクトリではなく、実際の管理情報の場所を示すファイルの場合もあります。worktreeやsubmoduleで使われる構成です。今回作成したworktreeでは、.gitがファイルでもgit statusは成功しました。

したがって、.gitがファイルだから壊れていると判断して削除しないでください。参照先へアクセスできるか、元のリポジトリを移動していないかを確認します。

以前は正常だったのに管理情報がなくなっている場合は、作業ファイルと残っている管理情報を先に保全します。リモートから別の場所へcloneすれば、そのリモートにある履歴は取得できますが、未pushのコミットまで戻るとは限りません。それらはバックアップや元の管理情報からの復旧が必要です。

環境変数と探索範囲を確認する

正しい場所なのに見つからない場合は、Gitの探索に関係する環境変数を確認します。Windowsのコマンドプロンプトなら、次で該当する変数を表示できます。

set GIT_

macOS・Linux・Git Bashでは、必要な値だけを表示できます。

printf '%s\n' "$GIT_DIR" "$GIT_WORK_TREE" "$GIT_CEILING_DIRECTORIES" "$GIT_DISCOVERY_ACROSS_FILESYSTEM"

Gitの環境変数の公式説明に、それぞれの用途があります。

変数確認する内容
GIT_DIR通常の探索先ではなく、指定した管理情報の場所を使っていないか
GIT_WORK_TREE作業ディレクトリの場所を別に指定していないか
GIT_CEILING_DIRECTORIES親へたどる範囲を制限していないか
GIT_DISCOVERY_ACROSS_FILESYSTEMファイルシステムの境界を越える探索を許可するか

意図せず残った値か、道具が必要として設定した値かを確認します。全変数をまとめて削除するのではなく、誤っている指定だけを修正してください。

GIT_CEILING_DIRECTORIESは、指定した親ディレクトリへ上がる探索を制限します。現在のディレクトリ自体や、明示したGIT_DIRを除外する指定ではありません。今回も、子ディレクトリから親のリポジトリへ到達する探索を制限すると、同じ拒否を再現できました。

似たエラーの文言で確認先を分ける

GIT_DIRに存在しない場所を指定した確認では、次の別の文言になりました。

fatal: not a git repository: '/path/to/missing'

この場合は、現在の場所だけでなく、明示された管理情報のパスを確認します。

次の文言なら、探索がファイルシステムの境界で停止しています。

fatal: not a git repository (or any parent up to mount point ...)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

公式文書には、GIT_DISCOVERY_ACROSS_FILESYSTEMを有効にすると境界を越えて探索する説明があります。ただし、別のマウント先にあるリポジトリを使いたいなら、まずその実際の場所へ移動するか、git -Cで明示します。探索範囲を広げれば管理情報が復元されるわけではありません。

detected dubious ownershipは、見つかったリポジトリの所有者に関する拒否です。今回のエラーへの一般的な対処として、safe.directoryを追加する必要はありません。

GitHubのRepository not foundは、リモートのURLやアクセス権に関係する別の問題です。今回のgit statusの最小例は外部通信なしで発生しています。

解決手順のまとめ

現在の場所とclone先を確認し、リポジトリへ移動するかgit -Cで指定します。認識できたら、git rev-parse --show-toplevelで対象が意図した場所か確認してください。

新しく管理を始める場合だけgit initを使います。ZIP取得や管理情報の欠損から既存の履歴を使いたい場合は、元の変更を残し、cloneやバックアップからの復旧を検討します。

この記事ではLinux上のGit 2.51.1で、リポジトリ外、clone後の親ディレクトリ、子ディレクトリからの探索、空の.git、不正なGIT_DIR、探索範囲の制限、正常なworktreeの.gitファイルを確認しました。Windowsでのコマンド実行と、実際のマウント境界での再現は未検証です。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。