git resetとかgit commit --amendをやると既存コミットが書き変わる。
通常、こういった操作は自分しか触らないローカルブランチで、しかもpush前にしかやらない(と思ってる)。
コミットを書き換えると、そのコミットをpullしている他の人にも影響するからなんだけど、
実際にやってみたらどうなるんだ?!というのを試してみた。
こんなシチュエーションを考えてみた
- あるリポジトリを二人の作業者がcloneして作業している(my_repo/your_repo)
- 二人はmasterを共有ブランチとしてtopicブランチからmerge, pushしている
- my_repoの作業者が残念なコミットをpushしたことに後から気づき、masterを直接書き換えて誤魔化そうとした
- your_repoの作業者は残念なコミットまでpullしている
ケース1:git resetで闇に葬ろうとも、他人のブランチから蘇る
my_repo]$ git log --oneline --decorate | head -n 2
78cc640 (HEAD, origin/master, my-topic, master) my cool commit
1e9525d fifth commit
my_repo]$ git reset --hard HEAD~
my_repo]$ git push -f origin master
何も知らないyour_repo作業者は自分の変更をコミットしてmergeする
your_repo]$ git ci -m "sixth commit"
your_repo]$ git checkout master && git pull
your_repo]$ git push origin master
この時点で消したはずのコミットが元に戻ってる
(your_repoにmy cool commitが残っているので、それがpushで復元されている)
my_repo]$ git pull
my_repo]$ git log --oneline --decorate | head -n 2
957a166 (HEAD, origin/master, master) sixth commit
78cc640 (my-topic) my cool commit
ケース2:git commit --amendで書き換えると、他人のブランチでコンフリクトを起こす(rebaseでも同じ)
my_repo]$ git log --oneline --decorate | head -n 2
78cc640 (HEAD, origin/master, my-topic, master) my cool commit
1e9525d fifth commit
my_repo]$ vi cool.rb
my_repo]$ git add cool.rb
my_repo]$ git commit --amend
my_repo]$ git push -f origin master
何も知らないyour_repo作業者は自分の変更をコミットしてmergeしようとして・・・
your_repo]$ git ci -m "sixth commit"
your_repo]$ git checkout master && git pull
....
CONFLICT (add/add): Merge conflict in cool.rb
your_repo作業者がmasterブランチを更新しようとしてコンフリクトが発生する。
作業者自身はブランチを触っていないため何が起きたかわからなくなる。
とりあえず状況を確認すると・・・編集した覚えのないファイルがコンフリクト
(ローカルに取り込んでいたmy cool commitと、--amendされた後のmy cool commitの内容が衝突している)
your_repo]$ git status
....
# both added: cool.rb
こうなると、my_repo作業者に内容を確認するなりcloneし直すなりしないと先に進めなくなる。
ちなみに、git rebaseでコミットをまとめた場合も同じことが起こる。