git checkout -b somebranch # from "A"
......some work commits here x, y, z .....
git checkout master
git pull # call new HEAD "B"
だから私たちは次のようなものを持っています
A -> a1 -> a2 -> B <= master
\
x -> y -> z <= somebranch
その後:
git checkout somebranch
git rebase master
A -> ... -> B <= master
\
x' -> y' -> z' <= somebranch
git checkout master
git merge somebranch # call new HEAD "C"
A -> ... -> B -------------> C <= master
\ /
x' -> y' -> z' <= somebranch
したがって、この時点で、 master を に巻き戻すだけで、不要なマージを簡単に元に戻すB
ことができます。ただし、プッシュする C
と (そして他の人がそれを見て、および/またはその上で作業を行った場合)、これは難しくなります。
簡単な解決策は、上のすべてのコミットを元に戻すことsomebranch
です:
git revert x'..z'
押します。
ここで、somebranch
再度マージする前に、(最初に行ったように) リベースする必要があります。これは機能しますが、マスターの履歴にノイズが発生します。
限られた数の人々が子供を見たり、コミットしたりし、彼らと調整できる場合、これを回避することは可能ですが、それは大変な作業です. 可能であれば、彼らが取り組んでいるすべてがコミットされ、プッシュされていることを確認する必要があります。その後、これをリベースできます。
A -> ... -> B -------------> C -> c1 -> c2 -> D <= master
\ /
x' -> y' -> z' <= somebranch
これに:
c1' -> c2' -> D' <= master
/
A -> ... -> B -------------> C -> c1 -> c2 -> D
\ /
x' -> y' -> z' <= somebranch
これで中央のブランチは孤立し、新しいヘッドにD'
は変更が反映されず、somebranch
そのまま残っているので後でマージできます。
これを行うには、次を使用します。
git rebase --onto B C c1
git push --force
他のすべての人はD'
、たとえば次のようにして、新しい head に更新する必要があります。
git fetch
git checkout master
git reset --hard origin/master
まだ依存している(そして、リベースしたときにまだチェーンに表示されていない)ローカル コミットを誰かが持っている場合は、それらを新しい履歴にリベースまたはチェリー ピックする必要があることに注意してください。これは潜在的に多くの (エラーが発生しやすい) 作業になるため、可能であれば回避することをお勧めします。C
c1..D