web-dev-qa-db-ja.com

githubでプルリクエストをマージするかリベースするか

私は、長年の機能ブランチがほとんどない2人のプロジェクトに積極的に取り組んでいます(既存の最長ブランチは3週間です)。

午後は、マージとリベース、および長所と短所を理解するために費やしました。コードレビューのためにgithubにプッシュする前に、ある程度の進歩を遂げ、ローカルコミットをクリーンアップするためにリベースを組み込むことを計画しています。私は頻繁にコミットするのが好きで、テストを自動化しているので、リベースされたコミットにバグをもたらす可能性があるというリベースに対する主な議論はそれほど重要ではないようです。私はこのタイプのリベースに対するいくつかの議論を見てきましたが、それほど論争の的ではないようです。私の混乱は、コードレビューが完了した後、機能ブランチをリベースすることとマスターにマージすることです。他の誰もそれに依存しておらず、コードレビュープロセスによって多くの小さな意味のない構文コミットが生成されたことを知っています。これらはどちらもリベースを提案しているようです。

私の理解は、私のプロジェクトのリベースには履歴をきれいに保つという利点があるため、変更が導入された理由のgitのせいでより良い要約を見ることができるということです。また、履歴を線形に保つのに役立ち、git bisectを使用しやすくなります(履歴が線形であるか、すべてのコミットが完全であり、意図的に中断されていないか)。また、プルリクエストを送信する前に別のコミットでファイルの名前を変更して編集するのを忘れた現在の例を修正して、不必要な大きな差分につながっています。このプロジェクトでは、これらはいずれもgit-mergeワークフローを使用することによる画期的な欠点のようには見えません(コードベースは実際の欠点を体験するにはまだ十分に大きくない可能性があります)が、大きな短所がない場合は良いでしょう。

私が目にする欠点は、私はgitの専門家ではないため、マージよりもリベースの方が実際に問題を解決する方がはるかに簡単だと思われることです。第二に、私たちはgithubのプルリクエストに対して多くのアクティブなコメントを行っており、SHAをリベースして変更することでそれらのコメントを壊したり失うことをためらっていますコメントは失われますが、それらは正しいコミットを参照しなくなるため、他の方法で参照されているコミットを見つけ出さなければなりません。現実私はおそらくまだ部分的に壊れているコミットを持っているでしょう。

この 記事 についてマージとリベースについて、この状況について次のアドバイスを提供しています:

レビューが完了し、対象ブランチに統合する準備ができました。おめでとう!機能ブランチを削除しようとしています。これ以降、他の開発者がこれらの変更をフェッチマージしないので、これは履歴をサニタイズするチャンスです。この時点で、履歴を書き直して、元のコミットと厄介な「pr再作業」および「マージ」コミットを、フォーカスされた小さなコミットセットに折りたたむことができます。これらのコミットの明示的なマージの作成はオプションですが、価値があります。これは、機能がマスターになった時期を記録します。

上記の分析が正しい方向に進んでいるかどうかを知りたいと思っています。現在、私は上記のアドバイスで説明されているように、リベースを慎重に使用することに傾いています。しかし、私は彼らが提案することを実際に行う方法さえ混乱しています。明示的なマージを作成するにはどうすればよいですか? featureのコピーであるローカルブランチを作成してから、rebase -iそのブランチで履歴を希望のように見せてから、masterとマージしますか?または、featureを直接マスターにリベースしてから、rebase -i必要に応じてコミットをスカッシュします。このアプローチが彼らが提案しているものである場合、最後に明示的なマージを作成するにはどうすればよいですか?

7
emschorsch

私が決定した解決策は最も単純であり、私にとって最も有利な解決策は、リベースしてからマージすることでした。 githubを使用してプルリクエストを行ったり来たりしていくつかの小さな変更をコミットした後、それをマスターブランチにマージします。私のローカルセットアップでは、次のことを行いました。

git pull
git checkout feature
git rebase -i HEAD~8  # combine small commits and separate file moving
git checkout master
git merge --no-ff feature  # comment this with `close #<pull_request_number>`
git Push

利点は次のとおりです。

  • マスターブランチでは、履歴がより簡潔で簡潔になります
  • 最後の明示的なマージにより、プルリクエストがマージコミットにリンクされます。

欠点は次のとおりです。

  • プルリクエストのリベースされたコミットは、混乱を招く可能性のあるマスターのコミットにリンクしなくなりました。
  • 実際に戻って、リベースされた各コミットが新しいリベースされたコンテキストで機能することを確認しなかったため、バグが発生する可能性はわずかです

これが推奨されるアプローチなのか、少々ハックなのかわからないので、どちらかに固執する必要があります。しかし、これに起因する問題がないか確認します。他の人からのさまざまな提案に非常に柔軟です。

3
emschorsch

あなたはすでにあなた自身の答えで質問に答えたようですが、私はまだこれを共有したいと思っています。

リモートリポジトリにプッシュするまで、mergeを使用するかrebaseを使用するかは問題ではありません。 rebaseを使用すると、ブランチRailsはきれいに見えます。線形のままであり、mergeのように拡張されないためです。

どちらの方法でも、rebasemergeの両方を使用すると、競合の修正を余儀なくされる可能性が高く、これらの競合は完全に異なる可能性があります。

したがって、ブランチで単独で作業している場合(このブランチをリモートリポジトリにプッシュすることはまだできません)、最初のプルリクエストの前にrebasingを実行することをお勧めします。ブランチがリポジトリに留まり、将来再びブランチで作業する場合、mergeが先の方法です。rebaseは、議論されたブランチの履歴を台無しにし、異なる開発者が異なるコードを使用する可能性があります。

1
Andy