検証用に別リポジトリをコピーして作業したあと、git add . を実行しても期待した複数ファイルがステージされず、「index関連の差分しか乗らない」「特定ディレクトリが1つの塊としてしか扱われない」状態になりました。調査すると、対象ディレクトリが意図せず gitlink として扱われていたのが原因でした。この記事では、実際にやった原因確認と対処を、再現しやすい形でまとめます。
忙しい人向け
原因は、対象ディレクトリが gitlink(submodule参照)として扱われていたことでした。 不要なネスト .git を消して、親リポジトリで再 git add すれば直ることが多いです。
問題発生時のファイル構成(例)
my-repo/
├─ .git/
├─ app/
│ ├─ .git/ ← これが残っていた(意図しないネスト)
│ ├─ src/
│ └─ package.json
└─ README.md
この状態だと、app/ 配下のファイル差分が親リポジトリ側で通常ファイルとして見えず、git add . 後に想定どおりステージされないことがあります。
発生環境
- OS: macOS(必要に応じて実バージョンを追記)
- Git: 2.50
- 使用クライアント: VSCode + CLI
- 作業状況: 親リポジトリ配下に別プロジェクトをコピーした直後
1. この記事でわかること
git add後に想定ファイルがステージされないときの主要原因- submodule(gitlink)化しているかどうかの判定方法
.gitignoreとキャッシュの噛み合わせ問題の確認方法git rm --cachedを使った安全な復旧手順- すぐ復旧するための最短手順
2. 症状
よくある症状は次のとおりです。
git add .をしてもgit statusに対象ファイルが出ない- ディレクトリ配下を編集したのに、親リポジトリでは「1件の変更」だけに見える
git diff --cachedで見ると通常ファイル差分ではなく、submodule 参照の更新のような表示になる- GUIでは変更が見えるのに、CLIでは見えない(または逆)
3. 前提条件
- 親リポジトリ配下に別プロジェクトをコピーした後、
git addの挙動がおかしくなったケースを対象にしています。 - 「submoduleを意図的に運用したい」ケースではなく、「意図せず gitlink 化した」ケース向けの手順です。
- コマンド例は macOS で確認していますが、Windows / Linux でも同等の確認コマンドで再現できます。
※ find や sed など一部コマンドの挙動差は **環境依存の可能性** があります。必要に応じて同等機能に置き換えてください。
4. 原因
主な原因は次の5つです。
- 対象ディレクトリに
.gitが残っており、親から見ると別リポジトリになっている - 意図せず submodule 化され、親リポジトリには
gitlink(mode160000)だけが記録されている .gitignoreのルールで対象ファイルが除外されている- すでに追跡済み/未追跡の状態が混在し、
git addの対象指定が不足している - 過去の誤操作で index キャッシュだけ残り、作業ツリーとの認識がズレている
特に 1 と 2 は「ディレクトリ配下をどれだけ編集しても、親では中身が見えない」状態を作るため、最優先で確認します。
5. 対処手順
ケースA: 意図しないネスト(今回やった対処法) .git を通常ディレクトリに戻す
# 1) 親リポジトリでいったんキャッシュから外す
git rm --cached -r path/to/dir
# 2) 子ディレクトリ側の .git を除去(本当に意図しない場合のみ)
rm -rf path/to/dir/.git
# 3) 親リポジトリとして再登録
git add path/to/dir
git status
rm -rf は取り消しにくいので、削除前にバックアップや git -C path/to/dir log --oneline で履歴要否を確認してください。
ケースB: 意図せず submodule 化されている
.gitmodules と index の gitlink を整理してから通常管理へ戻します。
git submodule deinit -f path/to/dir
git rm -f path/to/dir
rm -rf .git/modules/path/to/dir
# 必要なら .gitmodules の対象エントリを削除して再 add
git add .gitmodules
git add path/to/dir
ケースC: .gitignore で除外されている
- ルールを見直し、必要なら
!path/to/target-fileで再包含 - 既にキャッシュされている不要物は
git rm --cachedで整理 - 再度
git addしてgit diff --cachedで確認

