いつgit pull --rebaseを使用すればよいですか?


806

git pull --rebaseデフォルトで使用する人も、絶対に使用しないと主張する人もいます。私はマージとリベースの違いを理解していると思いますが、私はこれをのコンテキストに入れようとしていますgit pull。マージコミットメッセージをたくさん見たくないということですか、それとも他の問題がありますか?


1
git pull --rebaseに反対する人々のためのソース?Rebaseまたはgit rebaseはgit pull --rebase とは別のアクティビティです!
przemo_li

回答:


584

あなたは使うべきgit pull --rebaseとき

  • あなたの変更は別のブランチに値しません

確かに-では、なぜそうしないのですか?それはより明確で、コミットに論理的なグループ化を課しません。


わかりました、それはいくつかの説明が必要だと思います。Gitでは、おそらくご存じのとおり、分岐してマージすることをお勧めします。変更をプルするローカルブランチとリモートブランチは、実際には異なるブランチであり、git pullそれらをマージしようとしています。プッシュはそれほど頻繁ではなく、通常、完了した機能を構成する前にいくつかの変更を蓄積するため、それは合理的です。

ただし、場合によっては、何らかの理由で、リモートとローカルの2つが1つのブランチである方が実際には優れていると考える場合があります。SVNのように。ここが登場git pull --rebaseする場所です。マージする必要はなくなりました。実際には、リモートブランチの上でコミットします。それが実際の目的です。

危険かどうかは、ローカルブランチとリモートブランチを切り離せないものとして扱うかどうかという問題です。時にはそれが妥当な場合もあります(変更が小さい場合、または堅牢な開発の最初の段階で、重要な変更が小さなコミットによってもたらされる場合)。そうでない場合もあります(通常は別のブランチを作成しますが、それを行うのが面倒なので)。しかし、それは別の質問です。


17
同じブランチで作業するときに便利だと思いますが、ワークステーションを変更することができます。あるワークステーションから変更をコミットしてプッシュしてから、別のワークステーションでリベースをプルし、同じブランチで作業を続ける傾向があります。
Pablo Pazos

11
プルウィズ時に自動的にリベースするようにGitを設定することは、便利なベストプラクティスですgit config --global pull.rebase preserve (リベースを有効にすることに加えて、プリザーブはローカルでマージを行った場合にマージを保持しようとする)。
コリンDベネット

2
私はあなたが1つのブランチで作業しているときだけあなたがpull --rebaseを使うべきではないことに同意しません。他の状況で不可能でない限り、常に使用する必要があります。
トマーシュFejfar

@P Shved ...「しかし、時々-何らかの理由で-これらの2つ(リモートとローカル)が1つのブランチであった方が実際に優れていると思う」...これは可能ですか?ローカル環境では、ブランチとリモートブランチミラーをorigin / masterとして使用できます。yuoはここに入力を提供できますか?
Mandroid 2018

736

「git pull --rebase」が実際に何を意味するのかについて、別の見方をしたいと思います。

Subversion(またはCVS)を使用したことがある場合、「svn update」の動作に慣れている可能性があります。コミットする変更があり、変更が上流で行われたためにコミットが失敗した場合は、「svn update」を実行します。Subversionは、上流の変更を自分の変更とマージすることによって進行し、競合を引き起こす可能性があります。

Subversionが行ったことは、本質的には「プル-リベース」でした。ローカルの変更を新しいバージョンに関連するように再構成することは、その「リベース」の部分です。コミットが失敗する前に "svn diff"を実行し、その結果の差分を "svn diff"の出力と比較した場合、2つの差分の違いがリベース操作の実行結果です。

この場合のGitとSubversionの主な違いは、Subversionでは「自分の」変更は作業コピーのコミットされていない変更としてのみ存在するのに対し、Gitでは実際にローカルにコミットされていることです。言い換えると、Gitで歴史を分岐しました。あなたの歴史と上流の歴史は分かれていますが、共通の祖先があります。

私の意見では、ローカルブランチに上流のブランチを単純に反映させ、継続的な開発を行う通常の場合、正しいことは常に「--rebase」です。これは、意味的に実際に行っていることです。あなたと他の人たちは、ブランチの意図された線形の履歴にハッキングしています。他の誰かがあなたのプッシュしようとする少し前に偶然プッシュしたという事実は無関係であり、そのようなタイミングの事故のそれぞれが履歴にマージをもたらすことは逆効果です。

何かの理由で何かがブランチになる必要性を実際に感じた場合、それは私の意見では別の懸念事項です。しかし、変更をマージの形で表現したいという具体的で積極的な欲求がない限り、私の意見では、デフォルトの動作は「git pull --rebase」であるはずです。

あなたのプロジェクトの歴史を観察し、理解する必要がある他の人々を考慮してください。あちこちに何百ものマージが散らばっている履歴が欲しいですか、それとも意図的な発散的開発努力の実際のマージを表す少数のマージだけが欲しいですか?


18
@MarceloCantos明確にするために、私はgit(ツール)がデフォルトでリベースするべきだと言っているのではありません。リベースは本質的に歴史を破壊するので、それは危険です。ワークフローに関して言えば、ブランチをするつもりがなく、他の人たちも取り組んでいるブランチをハッキングしているだけの場合、「git pull --rebase」がユーザーのデフォルトの動作になるはずです。
コードを

1
すべきではないと言っていgit config --global branch.autosetupmerge alwaysますか?
Marcelo Cantos、2011年

9
@MarceloCantosいいえ、私はそうではありません;)個人的には、autosetupmergeをデフォルトのtrueのままにします(local <-> remote以外のブランチ間で4番目と4番目にマージする場合は、明示的に指定します)。私は人間として、明示的に分岐しない限りマージコミットを作成したくないので、私は通常の「マスターブランチの最新のグラブ」ワークフローの一部として常に「git pull --rebase」を使用していると言っています。
11年

9
+1 @scode。リベース/マージの質問に取り組んで多くの苦痛な時間を過ごした後、ようやくここにそれを否定する答えがあります。
AgileYogi 2012年

10
この答えは、適切なブランチを持つことの利点を正しく理解する機会を与えるのではなく、非分散バージョン管理システムのユーザーをGitに適応させる試みにすぎません。
Alexey Zimarev 2013

211

おそらくそれを説明する最良の方法は例を使用することです:

  1. アリスはトピックブランチAを作成し、作業を行います
  2. ボブは無関係なトピックブランチBを作成し、それに取り組んでいます
  3. アリスしgit checkout master && git pullます。マスターはすでに最新です。
  4. ボブはしgit checkout master && git pullます。マスターはすでに最新です。
  5. アリスは git merge topic-branch-A
  6. ボブの人はする git merge topic-branch-B
  7. ボブはgit push origin masterアリスの前に行います
  8. Aliceはgit push origin masterを実行しますが、早送りではないため拒否されます。
  9. Aliceはorigin / masterのログを調べ、コミットが自分のログと無関係であることを確認しました。
  10. アリスは git pull --rebase origin master
  11. アリスのマージコミットが解除され、ボブのコミットがプルされ、アリスのコミットがボブのコミット後に適用されます。
  12. アリスgit push origin masterはそうし、将来ログを見るときに役に立たないマージコミットを読む必要がないことを誰もが喜んでいます。

マージされる特定のブランチは例とは無関係であることに注意してください。この例のマスターは、リリースブランチまたはdevブランチと同じくらい簡単にできます。重要な点は、Alice&Bobがローカルブランチを共有リモートブランチに同時にマージしていることです。


2
いいね。私は明示的になりがちで、私のgit co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin master前に他人のマスターへのプッシュが起こった場合は繰り返します。私はあなたのレシピで簡潔な利点を見ることができますが。
HankCa、2017

素晴らしい説明@Cody Poll
Rajanikanta Pradhan

148

git pull --rebase同じブランチで他の人とコラボレーションするときに使用する必要があると思います。あなたはあなたの仕事→コミット→仕事→コミットサイクルにいます、そしてあなたがあなたの仕事をプッシュすることを決定したとき、あなたのプッシュは拒否されます、なぜなら同じブランチで並行した仕事があったからです。この時点で、私は常に行いますpull --rebase。(コミットをフラット化するために)スカッシュを使用しませんが、余分なマージコミットを回避するためにリベースします。

Gitの知識が増えるにつれ、私が使用した他のバージョン管理システムよりもずっと歴史に目を向けることになります。小さなマージコミットが大量にある場合、履歴で発生している全体像の焦点を失うのは簡単です。

これが実際にリベース(*)する唯一の時間であり、私のワークフローの残りの部分はマージベースです。しかし、あなたの最も頻繁なコミッターがこれを行う限り、歴史は結局ずっと良く見えます。

(*)Gitコースの指導中に、特定の状況で機能ブランチをリベースすることも提唱したため、学生にこれについて逮捕されました。そして、彼はこの答えを読んだ;)そのようなリベースも可能ですが、それは常に事前に準備された/合意されたシステムに従う必要があり、そのため「常に」適用されるべきではありません。そして、その時私は通常pull --rebaseどちらもしません、それが問題です;)


2
確かに、ログからマージコミットを隠すスクリプトを書くことができます
hasen

3
マージは、それが完全に些細ではありませんどの手段、あまりに差分を含めることができます
krosenvold

9
@hasen jはい。ただし、これらのマージの内容が重要になる可能性があります
krosenvold

この回答は、選択した回答と比較して曖昧で意見が分かれています。「同じブランチ」とは正確にはどういう意味ですか?しかし、選ばれた答えにはないいくつかの良い点があります。
iwein

1
参照を使用する方法は非常に多くあるため、「ブランチ」のあいまいさは意図的なものです。「作業明細」は1つのオプションにすぎません。
krosenvold

49

使用しない理由はないと思いますpull --rebase-特にGitにコードを追加して、git pullコマンドが常にアップストリームコミットに対してリベースできるようにしました。

履歴を見るとき、機能に取り組んでいる人/ギャルが同期を停止した時期を知ることは決して面白くありません。それは彼/彼女がそれをしている間彼/彼女のためにそれは役に立つかもしれません、しかしそれはそれが何のreflogためであるかです。それは他のすべての人にノイズを加えるだけです。


2
「歴史を振り返るとき、機能に取り組んでいる人が同期を停止した時期を知ることは決して面白くありません。」/しかし、それらの中間コミットが壊れたビルドである可能性が高いということではないですか?
eglasius、2011

10
はい、それらは「全体の状態」でもありません。それが私たちが彼らを望まない理由です。彼がどうやってそこに着いたのかではなく、彼が何を望んでいたのか知​​りたいのです。
ダスティン

4
場合はpull --rebase、必ず使用しなければならない、なぜしないpull、デフォルトでそれを行いますか?
ストラヤ2016年

2
あなたはあなた自身の意見を形成しなければならないでしょう。私はいくつか.gitconfigのオプションを正しく行うためにいくつか持っています。私はgit rebaseがデフォルトでgitタグなどと同様に間違っていると思います...同意しない場合は、意見を正当化する必要はありません。
ダスティン

8
「上流」からプルする場合、たとえばからmasterプルする場合、およびプルするブランチがまだ公開されていない場合、これは良いアドバイスのようです。一方、機能ブランチからその中に引っ張ると、逆masterのようになります:を使用する理由はありません--rebaseよね?それがデフォルトではない理由かもしれません。リベースは変更が階層の最上部から下にどのように渡されるかであり、マージはそれらが上に戻る方法であることがわかりました。 derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
jolvi

38

覚えてね:

  • プル=フェッチ+マージ
  • pull --rebase = fetch + rebase

したがって、ブランチを処理する方法を選択します。

マージとリベースの違いを理解した方がいいです:)


9

個人の好みに帰着すると思います。

変更をプッシュする前に、愚かな間違いを隠したいですか?もしそうなら、git pull --rebase完璧です。後でコミットをいくつか(または1つ)のコミットに押しつぶすことができます。(プッシュされていない)履歴にマージがある場合、後でマージするのは簡単ではありませんgit rebase

私は個人的にはすべてのばかげた間違いを公開してもかまわないので、リベースするのではなくマージする傾向があります。


8
この質問を表示している人への注意:この回答は、「いつgit pull --rebaseを使用すべきですか?」という質問とはまったく関係ありません。
therealklanni 2014年

3
@therealklanni質問との関連性が明確になるように回答を編集しました(願わくは意図を壊すことなく)。
–PaŭloEbermann、2014

ダーティで構造化されていない作業ログを共有することは、正直な努力ではなく、ただの怠惰です。開発とデバッグのうさぎの穴を追いかけて、人々の時間を浪費しています。とりとめのない結果を彼らに与えなさい。
クリスタ

8

git pull --rebase履歴の書き換えをコラボレーターから隠すことがありgit push --forceます。他の誰かが同じことをする前にコミットをプッシュするのを忘れた場合にgit pull --rebase のみ使用することをお勧めします。

何もコミットしなかったが、作業スペースがクリーンでない場合は、直前git stashgit pull。この方法では、履歴を静かに書き換えることはありません(これにより、一部の作業が静かに破棄される可能性があります)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.