私は、他の開発者とのプロジェクトで数か月間 Git を使用しています。私はSVNで数年の経験があるので、関係に多くの荷物を持ってきたと思います。
Git は分岐とマージに優れていると聞いたことがありますが、これまでのところ、そのようには見えません。確かに、分岐は非常に単純ですが、マージしようとすると、すべてがうまくいきません。今、私はSVNからそれに慣れていますが、ある標準以下のバージョン管理システムを別のシステムと交換しただけのようです。
私のパートナーは、私の問題は意地悪にマージしたいという私の欲求から生じていること、そして多くの状況でマージの代わりにリベースを使用する必要があることを教えてくれました。たとえば、彼が作成したワークフローは次のとおりです。
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature
基本的に、機能ブランチを作成し、常にマスターからブランチにリベースし、ブランチからマスターにマージします。注意すべき重要なことは、ブランチは常にローカルのままであるということです。
これが私が始めたワークフローです
clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch
本質的な違いが 2 つあります (私が思うに): 私はリベースの代わりに常にマージを使用し、フィーチャー ブランチ (およびフィーチャー ブランチのコミット) をリモート リポジトリにプッシュします。
リモート ブランチを使用する理由は、作業中に作業をバックアップしたいからです。リポジトリは自動的にバックアップされ、問題が発生した場合に復元できます。私のラップトップはそうではないか、それほど完全ではありません。したがって、他の場所にミラーリングされていないコードをラップトップに置くのは嫌いです。
リベースの代わりにマージする理由は、マージが標準のように見え、リベースが高度な機能のように見えるからです。私の直感では、私がやろうとしていることは高度なセットアップではないので、リベースは不要なはずです。私は Git に関する新しいプラグマティック プログラミングの本も熟読しましたが、それらはマージを広範囲にカバーし、リベースについてはほとんど言及していません。
とにかく、私は最近のブランチで自分のワークフローに従っていましたが、それを master にマージしようとすると、すべてがうまくいきませんでした。重要ではないはずのものとの衝突がたくさんありました。対立は私には意味がありませんでした。すべてを整理するのに 1 日を要し、最終的にリモート マスターへの強制的なプッシュが行われました。
このようなものの「正しい」ワークフローは何ですか? Git は分岐とマージを非常に簡単にするはずですが、私はそれを見ていません。
2011 年 4 月 15 日更新
これは非常によくある質問のようです。最初に質問してから 2 年間の経験を更新したいと思います。
少なくとも私たちの場合、元のワークフローは正しいことがわかりました。言い換えれば、これが私たちがしていることであり、機能します。
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature
実際、生のマージではなくスカッシュ マージを行う傾向があるため、ワークフローは少し異なります。(注: これは議論の余地があります。以下を参照してください。 ) これにより、機能ブランチ全体を master 上の単一のコミットに変えることができます。次に、機能ブランチを削除します。これにより、ブランチ上でコミットが少し乱雑であっても、マスター上でコミットを論理的に構造化することができます。だから、これは私たちがすることです:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature
スカッシュ マージの論争- 何人かのコメンターが指摘しているように、スカッシュ マージはフィーチャー ブランチのすべての履歴を破棄します。名前が示すように、すべてのコミットを 1 つにまとめます。小さな機能の場合、これは 1 つのパッケージに凝縮されるので理にかなっています。より大きな機能の場合、特に個々のコミットがすでにアトミックである場合は、おそらく良い考えではありません。それは本当に個人的な好みに帰着します。
Github と Bitbucket (その他?) のプル リクエスト- マージ/リベースがプル リクエストにどのように関連するのか疑問に思っている場合は、マスターにマージする準備が整うまで、上記のすべての手順に従うことをお勧めします。手動で git とマージする代わりに、PR を受け入れるだけです。これはスカッシュ マージを行わないことに注意してください (少なくともデフォルトではそうではありません) が、非スカッシュ、非早送りがプル リクエスト コミュニティで受け入れられているマージ規則です (私の知る限り)。具体的には、次のように機能します。
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin
私は Git が大好きになり、SVN には戻りたくありません。苦労している場合は、そのまま続けてください。最終的には、トンネルの終わりに光が見えます.