git pullとgit pull --rebaseの違い


311

私はいつかgitを使い始めましたが、複雑さを完全には理解していません。私の基本的な質問はここに違いを見つけることですgit pullし、をgit pull --rebase追加しているので、--rebase非常に異なる何かをしていないようオプションを:ちょうどプルを行います。

違いを理解してください。




回答:


326

git pull= git fetch+ git merge上流ブランチの追跡に反対

git pull --rebase= git fetch+ git rebase上流ブランチの追跡に反対

あなたはどのように知りたい場合git mergegit rebase異なり、これを読んで


12
それは言ってはいることは注目に値しますgit pull --rebaseと同じであるgit fetchgit rebaseそれがどのように基本的ですが、それはありません正確に同じ意味。いくつかの違いがありますが、その一部をここで説明します。gitolite.com/git-pull--rebase
w0rp

8
スコットマイヤーズの言葉を借りて、「便利な嘘」と呼んでいます。それは関係なくそれを説明する良い方法です。
w0rp 2015

非常に簡単に。違いがわかりません。何がそんなに重要fetchですか?
Green

240

時々、依存しているブランチをリベース/巻き戻しするアップストリームがあります。これは大きな問題になる可能性があります-ダウンストリームの場合、厄介な競合が発生します。

魔法は git pull --rebase

通常のgit pullは、大まかに言えば次のようなものです(これらの例ではすべて、originというリモートとfooというブランチを使用します)。

# assume current checked out branch is "foo"
git fetch origin
git merge origin/foo

一見すると、git pull --rebaseがこれを行うと思うかもしれません:

git fetch origin
git rebase origin/foo

しかし、アップストリームのリベースに「つぶし」が含まれている場合(つまり、コミットのパッチIDが順序だけでなく変更された場合)は、役に立ちません。

つまり、git pull --rebaseはそれ以上のことを行う必要があります。ここでは、その機能と方法について説明します。

あなたの出発点はこれだとしましょう:

a---b---c---d---e  (origin/foo) (also your local "foo")

時が経ち、あなたは自分の "foo"の上にいくつかのコミットをしました:

a---b---c---d---e---p---q---r (foo)

その間、反社会的な怒りの発作で、上流のメンテナーは彼の "foo"をリベースするだけでなく、スカッシュや2つも使用しました。彼のコミットチェーンは次のようになります。

a---b+c---d+e---f  (origin/foo)

この時点でgit pullを実行すると、混乱が生じます。git fetchでさえ; git rebase origin / fooはそれをカットしません。なぜなら、一方の側で「b」と「c」をコミットし、もう一方の側で「b + c」をコミットすると競合するためです。(同様に、d、e、およびd + eを使用)。

git pull --rebaseこの場合、何をしますか:

git fetch origin
git rebase --onto origin/foo e foo

これはあなたに与えます:

 a---b+c---d+e---f---p'---q'---r' (foo)

それでも競合が発生する可能性がありますが、それらは真の競合(p / q / rとa / b + c / d + e / fの間)であり、b / cがb + cと競合することによる競合ではありません。

から取られた(そしてわずかに変更された)回答:http :
//gitolite.com/git-pull--rebase


9
これが最良の答えです。a---b+c---d+e---f---p'---q'---r' (foo)リベースはハッシュを変更するので、最終結果をに変更したい場合があります。
バスティアン2014年

22
この回答は、gitolite.com / git-pull -- rebaseからそのままコピーして貼り付けたものであり、そのページのライセンスごとに帰属を含める必要があります。
ワイルドカード2015

これは素晴らしい説明です。しかし、私がコミットしたという状況があり、A承認された上流のリポジトリにPRを送信しました。その後git pull --rebase、上流のレポに対して反対したときA'、プルされた上流のレポの上に新しいコミットを取得しませんでした。実際にはまったくA'存在しませんでした。これAはシステムに統合されたためですか?それとも、アップストリームと私のリベースバージョンに違いがなかったためですか?
CMCDragonkai 2016

私は現在Gitチュートリアルを行っており、この応答を使用してをさらに理解していgit pull --rebaseます。しかし、この架空の状況で私を混乱させる1つのことは、上流のメンテナが、ローカルの開発者のリポジトリにすでに組み込まれているプロジェクト履歴を変更したことです。これは一般的に単に悪い習慣ではありませんか?彼がコミット/リライト履歴をスカッシュしたい場合は、これらのタイプの競合を回避するために、それを中央リポジトリに統合する前に行う必要があります。
bmcentee148 2017年

44

ローカルブランチに2つのコミットがあるとします。

      D---E master
     /
A---B---C---F origin/master

「git pull」の後、次のようになります。

      D--------E  
     /          \
A---B---C---F----G   master, origin/master

「git pull --rebase」の後、マージポイントGはなくなります。DとEは異なるコミットになることに注意してください。

A---B---C---F---D'---E'   master, origin/master

1
A --- B --- C --- D '--- E'-Fではないですか?
prgmrDev 2018

5
@prgmrDev Fの前にDとEが挿入されるのはなぜですか?
ジョン

1
正確には何をgit rebaseしているのではないですか?しかし、我々は話しているgit pull --rebase。そして、それらは異なるものです。
グリーン、

10

衝突がない非常に単純な場合

  • with rebase:ローカルコミットをリモートHEADの上にリベースし、マージ/マージコミットを作成 しませ
  • なし/通常:マージしてマージコミットを作成します

以下も参照してください。

man git-pull

より正確には、git pullは指定されたパラメーターでgit fetchを実行し、git mergeを呼び出して、取得したブランチヘッドを現在のブランチにマージします。--rebaseを使用すると、git mergeではなくgit rebaseが実行されます。

参照:
いつgit pull --rebaseを使用すべきですか?
http://git-scm.com/book/en/Git-Branching-Rebasing


3
そして衝突の場合には?
Rndm 2013

1
手動で、その後、それらを解決するように頼まれます-リベースを続行:git sdd modified-file; git rebase --continueまたはマージ:git add modified-file; git commit;どこmodified-fileローカルファイルを手動で/ mergetool変更された
drahnr

何がそんなに特別なのfetchですか?なぜ2つのrebaseフローを作成したのですか?1)git rebaseと2)git pull --rebase
Green

7

これはMergeとRebaseの違いを理解するために重要です。

リベースとは、変更が階層の最上位から下に向かって進む方法であり、マージとは、変更が上に戻る方法です。

詳細については、http://www.derekgourlay.com/archives/428を参照してください


あなたの答えは、上記の残りの答えでは明白ではないはるかに単純な説明を提供すると思います。ありがとう。
アーロンC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.