用git整合分支的时候,大家更常用的是变基操作(git rebase)还是合并操作(git merge),你们觉得哪个比较好?
PHPz
PHPz 2017-05-02 09:44:25
0
2
832

git整合分支一般有两种方法——变基操作(git rebase)和合并操作(git merge),但是在你们实际的团队开发中,哪种方式用的最多,或者你们觉得那个好呢?

PHPz
PHPz

学习是最好的投资!

全員に返信(2)
Peter_Zhu

現実はこんな感じだと思います:

  1. git を使用する人の少なくとも半数は、(基本的な機能であっても) リベースの使用方法を知りません (この推定はおそらく非常に保守的です)

  2. 残念ながら、残りの半分だけがいつリベースを正しく行うべきかを本当に理解していません...

マージとリベースは、どちらかを選択するという問題ではなく、特定の状況に応じて選択する必要があります。実際には、ほとんどの開発者にとって、この「特定の状況」を 1 つずつ列挙するのは非常に難しいと言われています。チーム内の役割は比較的単一であり、頻繁に遭遇するものではないため、ここでは全員が理解し、遵守すべきガイドラインを 2 つだけ要約します。

  1. リモートから pull を実行するときは、常に rebase を使用してください (1 つの例外を除き、これについては後で説明します) pull 的时候,永远使用 rebase(除了一个例外,后面会讲)

  2. 当你完成了一个功能(假定你是单独开本地分支去做的)后打算合并到主干分支的时候,永远使用 merge

开发者应当理解:不同的合并策略影响的或许不是最终的代码结果,但却会影响 git 如何记录提交的历史(尽管很多时候这种理解只对个别人受益,而对自己没有什么影响)。其他的人在使用这些历史的时候(比如 code review 的时候,或者 bisect 的时候等等)会因为过去你做过的事情而感到无比幸福或痛苦。

第二点比较容易理解,把开发一个功能的具体细节隐藏在本地分支中,而把最终的结果作为一条完整的记录合并(merge)到主干分支去。

关键是第一点。大多数情况下大家会选择默认的 pull,也就是 fetch + merge,于是我们会看到主干上不停的出现 Merge commit xxx into xxx 之类的干扰信息。如果所有的人都图方便这么干,那就永远都别想有干净漂亮的历史树了,取而代之是类似这样的东西:

如果你去 clone 一个正确使用 git 的项目,你绝对不会看到上图这样乱七八糟的 master。为什么呢?答案就是:git pull --rebase,这条命令会使用 rebase 来代替默认的 pull 对合并的历史树进行变基处理,就可以避免因为无法快进(fast forward)而产生的额外合并记录。

现在绝大多数的 git 客户端都允许设置 git pull 的默认行为是 --rebase,所以掌握了这个诀窍可以让大部分的日常拉取操作都产生清爽漂亮的历史记录,但这并不是完美的结局。有一种例外是这样的:

  1. 在你使用 git merge 完成了一个功能分支向主干分支的合并之后(当然是 --no-ff

    🎜🎜機能を完了し (ローカル ブランチを個別に開いたと仮定して)、それをトランク ブランチにマージする予定がある場合は、常にマージを使用してください🎜🎜 🎜 🎜開発者は、さまざまなマージ戦略が最終的なコード結果には影響しない可能性がありますが、Git が送信履歴を記録する方法には影響することを理解する必要があります (ただし、多くの場合、この理解は個人に利益をもたらすだけで、自分自身にはほとんど影響しません)。他の人がこれらの履歴を使用すると (コード レビュー中や二分化中など)、あなたが過去に行ったことのせいで、非常に幸福になったり惨めになったりするでしょう。 🎜 🎜 2 番目のポイントは、ローカル ブランチで関数開発の具体的な詳細を非表示にし、最終結果を完全な記録としてトランク ブランチにマージすることです。 🎜 🎜重要なのは最初のポイントです。ほとんどの場合、誰もがデフォルトの pull (fetch + merge) を選択するため、Merge commit xxx into xxx がトランクに常に表示されます。 /em> およびその他の不穏な情報。誰もが便宜のためにこれを行うと、クリーンで美しい履歴ツリーは決して得られず、代わりに次のようなものになります。 🎜🎜 🎜 git を正しく使用するプロジェクトをクローンすると、上の写真のような乱雑なマスターが表示されることはありません。なぜ?答えは、 git pull --rebase です。このコマンドは、デフォルトの pull の代わりに rebase を使用して、マージされた履歴ツリーをリベースします。早送りできないため、追加のマージされたレコードを回避できます。 🎜 🎜現在、ほとんどの Git クライアントでは、git pull のデフォルト動作を --rebase に設定できるため、このトリックをマスターすれば、ほとんどの毎日の pull 操作が可能になります すべてが新鮮で美しい履歴レコードを生成します, しかし、これは完璧な終わりではありません。次のような例外があります: 🎜 🎜 🎜🎜 git merge を使用して機能ブランチをトランク ブランチにマージした後 (もちろん --no-ff) 🎜
  2. git fetch を実行すると、リモート トランクが数コミット先にあることがわかりますgit fetch 发现远程主干又领先你若干提交

  3. 此时你若 git pull --rebase,你会发现你刚才合并功能分支的记录没了……

这是因为变基会忽略合并记录,因此变基命令会有一个特别的参数叫做:--preserve-merges 用于重建被忽略的合并记录。所以比 git pull --rebase 更好的方案就是用 git fetch + git rebase -p 代替之。

当然这个仅针对上面提到的特殊情况,随着 git 的升级说不好哪一天就不存在这种问题了也不一定。我一般都不会遇到这种情况,因为我都是这么做的:

  1. 完成功能分支之后先不 merge,而是回到主干分支去 git pull --rebase

  2. 如果主干有更新,rebase 更新的内容到功能分支来预检一下,看看在加入了最近别人的改动之后我的功能是否依然 OK(在这个过程中可能会有冲突处理,别怪我没提醒哦)

  3. 一切就绪之后再次 git fetch 主干看看有没有变动(因为在第二步的进行期间没准又有人 push 了新的变化),有的话重复第二步,没有则——

  4. 合并功能分支到主干然后 push,收工。

我这么做可以避免前面提到的意外,看似复杂了些但其实做熟练了之后也没什么难度,更重要的原因是 git rebase -p 是有缺陷的:

  1. 不能和 git pull 连用,一条命令分成俩,怎么都觉得“亏”了(虽说你可以写脚本,但最好不要因为习惯了之后反而有时候会害了你)

  2. 由于无法和 git pull 配合使用,所以你必须指明目标分支给 rebase,这一点比较烦人,特别是很多 GUI 客户端压根不支持 git rebase -p 的时候(我经常会在 CLI/GUI 之间切换环境使用 git)

  3. ORIG_HEAD 会被破坏。

ORIG_HEAD 在很多情形下非常有用,比如说你可以用 git log -p -reverse ORIG_HEAD 来回看最近一次合并所产生的所有变化等等。--preserve-merges

この時点で git pull --rebase を実行すると、マージしたばかりの機能ブランチのレコードがなくなっていることがわかります...🎜🎜 🎜これは、rebase がマージされたレコードを無視するためです。そのため、rebase コマンドには、無視されたマージされたレコードを再構築するために使用される --preserve-merges という特別なパラメーターがあります。したがって、git pull --rebase よりも良い解決策は、代わりに git fetch + git rebase -p を使用することです。 🎜 🎜 もちろん、これは上記の特殊な状況に限ったものであり、git のアップグレードにより、この問題がいつかなくなるとは限りません。私はいつもこうしているので、通常はこのような状況には遭遇しません: 🎜 🎜🎜関数ブランチの完了後、最初にマージせず、トランクブランチgit pull --rebaseに戻ります🎜🎜 🎜🎜トランクが更新された場合は、更新されたコンテンツを関数ブランチにリベースして、他の人の最近の変更を追加した後も自分の関数がまだ問題ないかどうかを事前チェックします (このプロセスでは競合が発生する可能性があります。私を責めないでください)思い出させてないよ) ああ)🎜🎜 🎜🎜すべての準備ができたら、再度トランクを git fetch して、変更があるかどうかを確認します (第 2 ステップで誰かが新しい変更をプッシュした可能性があるため)。変更がある場合は、第 2 のステップを繰り返します。そうでない場合は、——🎜🎜 🎜🎜機能ブランチをトランクにマージしてプッシュしたら、これで終わりです。 🎜🎜 🎜これを行うことで、前述の事故を回避できます。少し複雑に見えますが、実際には、慣れれば難しくありません。より重要な理由は、git rebase -p に欠陥があることです。 🎜 🎜🎜 git pull と組み合わせて使用​​することはできません。1 つのコマンドが 2 つに分割されているため、とにかく「失われた」ように感じられます (スクリプトを作成することはできますが、そうすることは避けた方がよいでしょう)。慣れると害を及ぼすこともあります) 🎜🎜 🎜🎜git pull では使用できないため、リベースのターゲット ブランチを指定する必要がありますが、特に多くの GUI クライアントが git rebase -p をサポートしていないため、これは非常に面倒です> (gitを使用するためにCLI/GUI間で環境を頻繁に切り替えます)🎜🎜 🎜🎜ORIG_HEAD は破棄されます。 🎜🎜 🎜ORIG_HEAD は、さまざまな状況で非常に役立ちます。たとえば、git log -p -reverse ORIG_HEAD を使用して、最新のマージなどによって生じたすべての変更を確認できます。 --preserve-merges を使用すると、それが指すはずの場所が失われるため、最初にそれを置き換える正しいハッシュを見つける必要がありますが、これは少し面倒な場合があります。 🎜 🎜 上記の答えは、初心者の場合、現実の複雑さは常に想像を超えるものであることを示しています。本当に git を使いたい場合は、日々の作業に基づいて git の動作原理を理解する必要があります。公式 Web サイトの電子書籍 (中国語版) にアクセスして、その中の git 内部セクションを注意深く読むと、どのコマンドを使用するかがわかります。 🎜

追加のポイント: トランク ブランチ上の多くの重要でない干渉コミット レコードをチームが気にしない場合は、いつでもリベースを使用できます。これにより、少なくとも多くのフォークが発生しなくなります。また、それを適切に処理すれば、クリーンな (しかし冗長な) ブランチ履歴を取得できます。

いいねを押す +0
淡淡烟草味

必須ではありませんが、プッシュ後にすべてのテストが緑色になる必要があります

(特に長いブランチはありません。ほとんどは 2 ~ 3 日以内にマージされますが、1 週間以上かかることはほとんどありません)

通常はマージの難易度に応じて誰もが選択しますが、違いがない場合はリベースが優先されます...見た目が良いためです

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート