この記事の目次
.gitignoreへファイル名を書いたのに、git statusには変更が出続ける。規則の書き間違いだけでなく、そのファイルをすでにGitで追跡している場合にも起きます。.gitignoreが効かないときは、追跡状態と除外規則を別々に調べましょう。
Gitのaddとcommitを一度使った人向けの練習です。Gitと、mkdir・printf・catを使えるターミナルを用意します。架空のサイトのプレビューログを題材に、空の新しいフォルダだけで試します。実際のサイトや共有リポジトリで、以下のコマンドをそのまま実行しないでください。
除外規則を書く前に、追跡状態を調べる
.gitignoreは、Gitで追跡しないファイルの候補を指定するためのものです。すでに記録対象になったファイルを、後から自動で取り除く設定ではありません。この区別はGit公式のgitignoreの説明にも明記されています。
まず、対象がインデックスに載っているかを調べます。インデックスは、次のコミットに入れる内容を準備する場所です。まだコミットしていなくても、git addで登録したファイルは、この調査では追跡対象として扱います。
使うのはgit ls-files -- preview.logです。preview.logという名前が出れば、インデックスにあります。何も出ない場合は、そのパスでは登録されていません。git ls-filesの公式資料で確認できる一覧機能を、対象の一ファイルに絞って使います。
| 追跡状態 | 除外規則への一致 | 次に調べること |
|---|---|---|
| 追跡済み | 一致している | 追跡を続ける必要があるか判断する |
| 未追跡 | 一致している | 通常の追加候補から除外される状態か確認する |
| 未追跡 | 一致していない | 規則の綴りと対象パスを確かめる |
「変更が見えなくなるまでファイル名を足す」のではなく、どの行に当たるかを先に決めます。元のファイルを手元から消すかどうかは、さらに別の判断です。
ログを先に記録し、後から除外してみる
作業用フォルダの中で、まだ存在しないgit-ignore-practiceというフォルダを作ります。次のコマンドは、そこへ移動して新しいリポジトリを作る例です。すでに同名フォルダがある場合は別の名前を使い、既存の内容を上書きしません。
mkdir git-ignore-practice
cd git-ignore-practice
git init
printf 'local preview\n' > preview.log
git add -- preview.log
git -c user.name=Practice -c user.email=practice@example.invalid commit -m "Add practice log"
printf 'preview.log\n' > .gitignore
printf 'second preview\n' >> preview.log
git status --short -- preview.log .gitignore
-cで指定した名前とメールは、この一回の練習コミットに使う値です。Gitの全体設定を書き換える操作ではありません。出力には、preview.logの変更を示すMと、新しい.gitignoreを示す??が現れます。順序や空白ではなく、対象ファイルと状態を読みます。
この時点でpreview.logは除外規則に書かれていますが、先に追跡したファイルなので変更が出ます。最初の失敗は、Mを見て「.gitignoreが読み込まれていない」と決めることです。ここからは同じファイルに対して二種類の照会を行います。
規則の一致と、追跡の有無を別々に確かめる
練習フォルダの中で、次を実行してください。
git ls-files -- preview.log
git check-ignore -v --no-index -- preview.log
一つ目はpreview.logを表示します。二つ目は、どのファイルの何行目にある規則と一致したかを表示し、この例では.gitignore:1:preview.logと対象のpreview.logを確認できます。これで「規則には一致するが、すでに追跡している」という状態を確定できます。
git check-ignoreの公式資料によると、追跡済みファイルは通常の照会では対象外です。そこで--no-indexを付け、インデックスを参照せずに規則との一致を調べています。-vは規則の出所を詳しく表示する指定です。
二つ目の失敗は、--no-indexなしで何も表示されなかったことを「規則が不一致」と解釈することです。修正ではls-filesで追跡状態を確認したうえで、上のコマンドを使います。追跡済みという理由で対象外になった状態と、本当に規則に当たらない状態を混同しないようにします。
規則の書き間違いも比較できます。.gitignoreのpreview.logをpreview.logsへ変えると、二つ目のコマンドは何も出さなくなります。末尾のsを戻して一致する行が出れば、この失敗は修正できています。この練習には否定規則や複数階層の.gitignoreは置いていません。
手元に残し、指定したログだけを追跡から外す
今回のログは、その端末での確認内容だけを残す練習用ファイルです。履歴へ入れ続ける必要はない、と方針を決めてから次を実行します。
git rm --cached -- preview.log
git add -- .gitignore
git diff --cached --name-status
cat preview.log
差分の一覧では.gitignoreがA、preview.logがDになります。Aは追加、Dは削除ですが、ここで表示しているのは次のコミットに入る差分です。catでは元の二行を読めるため、手元のファイルまで消えたわけではないと確認できます。
git rmの--cachedの説明にある通り、この指定は作業用ファイルを残してインデックスから外します。--cachedを付けない削除とは動作が違います。確認のためにコマンドを短くして実行し直さないでください。
削除として準備された対象がpreview.logだけであることを見て、練習の変更を記録します。
git -c user.name=Practice -c user.email=practice@example.invalid commit -m "Ignore local preview log"
git ls-files -- preview.log
git status --short --ignored -- preview.log
ls-filesは何も表示せず、最後のコマンドでは!! preview.logが出るのが期待結果です。二つの感嘆符は、git statusの短い表示形式で無視されるファイルを表します。以後ログへ行を追加しても、通常の変更一覧には出なくなります。
共有すべきファイルまで、追跡を外さない
画面を作るHTMLや、他の人も必要な設定ファイルなら、変更が出ること自体は正常です。作業一覧を静かにしたいという理由だけで除外すると、次の人が同じサイトを再現するための材料を失うおそれがあります。ログの用途を確認してから選んだ今回の手順とは違います。
また、削除を含むコミットを別の作業コピーへ取り込むと、そちらでは追跡していたファイルが削除される場合があります。「--cachedだから全員の端末で残る」とは説明できません。共有中なら必要なファイルの保存と、今後それを作る手順を担当者と確認します。引き継ぎメモの記事は、その手順を残すときに使えます。
今回の操作は過去のコミットを書き換えません。すでに記録した内容を履歴から消す方法でも、Webサーバーへの配信を止める設定でもありません。更新前に残す対象の判断はバックアップの準備で、公開対象は利用しているビルドや配信の設定で別に確認します。
追跡から外れたことと、手元にあることを照合する
15〜20分を目安に、練習フォルダで最初から順に試します。最後は「git statusが静かになった」だけで終えず、次の四条件を照合してください。
- catでpreview.logの二行を読める。手元の内容は残っている。
- git ls-filesではpreview.logが出ない。インデックスから外れている。
- git check-ignore -vでpreview.logが.gitignoreの一行目に一致する。追跡解除後は--no-indexなしでも確認できる。
- ログへ三行目を加えても、git status --shortには変更が出ず、--ignoredを付けると!!が出る。
同じ結果にならなければ、現在のフォルダ、対象パス、追跡状態、規則の一致をこの順に見直します。公開・運用の無料レッスンの手順書へ記録する際も、Gitから外した範囲と、配信しない範囲を一つの項目にまとめないようにしてください。
TRY A LESSON
記事の内容を、課題で確かめる
記載内容へのご質問や訂正のご連絡は、hello@junkbranding.comまでお願いします。