.gitignoreの変更が原因で、ローカルブランチ切り替え時に未追跡ファイルが出て混乱した件

リモートでは .gitignore に追加済なのに

git checkout master

と切り替えたら、こんな感じの git status 結果に

Untracked files:
  newdir01/
  newdir02/
  newdir03/

「え、これらって .gitignore に入ってるはずじゃなかったっけ?」

そう思って確認したけど、自分のマシンでなくサーバー上なので状態が掴みにくい…

原因はローカルブランチがリモートの更新に追いついていなかったため

.gitignore が更新されたのはリモートの master ブランチのみ。
でも、ローカルの master ブランチは古いままで追いついてなかった!

だから、.gitignore に newdir01/ 〜 がまだ含まれていない状態でブランチを切り替えた結果、
ワーキングツリー上にそれらの未追跡ディレクトリが出てきてしまった、というわけです。

上記についてはリモートの .gitignore 変更をログで確認し、わかりました!

git log --oneline --decorate master -- .gitignore

git reset –hard originでローカルブランチを最新に追いつかせる

まずはリモートとの差分を把握

git fetch origin master
git diff master origin/master

サーバー上のローカルブランチを最新のリモートブランチに合わせる

git checkout master
git reset --hard origin/master

リモートには無いはずのマージコミットが、本番サーバー側のブランチに存在

  • あなたは 本番サーバーにSSHで入って、git fetchgit checkoutgit pull origin ... しかしていない。
  • ファイルの修正や add/commit/merge はしていない
  • でも git log を見ると、リモートには無いはずのマージコミットが、本番サーバー側のブランチに存在していた。
  • つまり、本番サーバー上だけでマージが発生しているように見える。

git pull コマンドが暗黙的に「マージ」してしまったのが原因だと思われます!

git fetch origin
git pull origin 本番ブランチ

本願のローカルの 本番ブランチ の状態が、リモートとずれていた場合
pull 時に 自動でマージコミットが作られます。 これがあなたのケースっぽいです!

ローカルブランチの履歴 ≠ リモートブランチの履歴
→ その差を pull 時に Git が「merge」で埋めようとした
→ 結果としてこのマージコミットが生まれた

git reflog や git log –graph

今後の対策

  • 本番サーバーでは git pull を使用しない!
  • 安全な更新方法
git fetch origin
git reset --hard origin/master

git reset –hard origin/master って毎回使っていいの?リスクは?

  • 本番サーバーでは基本 ローカルで開発しない
  • コミットも、ファイル変更も、add も、merge もしない

という条件であれば

git fetch --prune origin
  • 全体の情報は更新される
  • 削除されたブランチのゴミ情報は整理される
  • ローカルには必要なブランチしか作られない
操作持ってくる内容ローカルブランチになる?
git fetch origin全てのブランチのHEAD情報(参照だけ)❌ ならない
git checkout origin/fooリモートを直接参照するだけ
git checkout -b foo origin/fooローカルブランチとして作成