これは単純な git シナリオだと思っていましたが、何が足りないのでしょうか?
master
ブランチとブランチがありますfeature
。 で作業を行いmaster
、 で作業を行いfeature
、さらに で作業を行いますmaster
。最終的には次のようになります (辞書順はコミットの順序を意味します)。
A--B--C------F--G (master)
\
D--E (feature)
git push origin master
リモートをmaster
最新の状態に保つのも、git push origin feature
( がオンのときにfeature
) 作業用のリモート バックアップを維持するのも、問題はありませんfeature
。これまでのところ、問題ありません。
しかし、今度はマスターのコミットfeature
の上にリベースしたいので、と を実行します。まだ大丈夫です。これで次のようになります。F--G
git checkout feature
git rebase master
A--B--C------F--G (master)
\
D'--E' (feature)
問題:feature
でリベースされた新しいブランチをバックアップしたいと思った瞬間git push origin feature
、リベースによりツリーが変更されたため、プッシュが拒否されますgit push --force origin feature
。 これは でのみ解決できます。
--force
必要かどうかわからないまま使うのは嫌です。では、本当に必要なのでしょうか? リベースすると、次は必ずpush
フルになるのでしょうか--force
?
この機能ブランチは他の開発者と共有されていないため、強制プッシュしても事実上問題はなく、データが失われることもありません。質問はより概念的なものです。
ベストアンサー1
問題は、git push
リモート ブランチをローカル ブランチに高速転送できることを前提としていることです。つまり、ローカル ブランチとリモート ブランチの違いは、ローカルでは最後に次のような新しいコミットがいくつかあることだけです。
Z--X--R <- origin/some-branch (can be fast-forwarded to Y commit)
\
T--Y <- some-branch
コミットを実行すると、git rebase
D と E が新しいベースに適用され、新しいコミットが作成されます。つまり、リベース後は次のような状態になります。
A--B--C------F--G--D'--E' <- feature-branch
\
D--E <- origin/feature-branch
このような状況では、リモート ブランチをローカルに早送りすることはできません。ただし、理論的にはローカル ブランチをリモートにマージできます (明らかにその場合は必要ありません)。ただし、git push
早送りマージのみを実行すると、エラーが発生します。
そして、--force
オプションが行うことは、リモート ブランチの状態を無視し、プッシュするコミットに設定することです。つまり、git push --force origin feature-branch
単にorigin/feature-branch
local で上書きするだけですfeature-branch
。
master
私の意見では、そのブランチで作業しているのが自分だけである限り、機能ブランチをリベースしてリモート リポジトリに強制的にプッシュすることは問題ありません。