45

ページを読むと、次のgit pullような厳しい警告が表示されますgit pull --rebase

これは潜在的に危険な操作モードです。歴史を書き換えますが、その歴史をすでに公開しているとはうまくいきません。git-rebase(1) を注意深く読んでいない限り、このオプションを使用しないでください。

このgit rebaseページでは、多くの説明が表示されますが、この種の警告はありません。

さらに、私は何人かの人々がそう言っているのを見てきました

git fetch
git rebase

と同じです

git pull --rebase

他の人は少し違うと言いますが。

真実は何ですか?

4

3 に答える 3

45

真実は、それらが異なるということです。これは、それを美しく説明する非常に役立つWebページです。

http://gitolite.com/git-pull--rebase.html

ほとんどの場合気付かないgit pull --rebase重要な魔法もgit fetch; git rebaseありますが、アップストリームのメンテナがこれらの厳しい警告をすべて悪意を持って無視し、パブリック ブランチの履歴を書き直すことにした場合は、あなたのブランチに相談することで本当に助けになりますローカル reflog を使用し、よりインテリジェントな方法でローカル リベースを実行します。

とはいえ、これはまだリベースなので、まだ履歴を書き換えています! したがって、すべての標準的な船尾警告が引き続き適用されます。ただし、プライベート (つまり、非公開) ブランチで作業している場合は、問題ありません。

厳戒態勢についてもう少しお話しします。それらは有効ですが、個人的には、ほとんどの人がリベースについて少し偏執的すぎるgit rebaseと思います。たとえば、若い頃に夜中に寝室に忍び込み、妹か何かを食べました。それほど怖くないはずです。

  • プライベート ブランチの場合は、思いのままにリベースします
  • それが公開ブランチである場合は、本当に必要でない限りリベースしないでください。もしそうする場合は、その影響を理解していることを確認し、影響を受ける可能性のある人があなたが行ったことについて適切に知らされていることを確認してください。不快な驚きを感じ、何が起こったのかを理解するために多くの時間を無駄にします.

それはとても簡単です。そして、はい、私は人々に定期的git rebase -iにプライベート ブランチを利用するよう積極的に奨励するところまで行きます。パブリック/アップストリームのどこかにプッシュする前に履歴を磨くことは良いことです.「おっと、3コミット前に犯した間違いを修正する」のようなコミットでいっぱいのプロジェクトの履歴を通り抜けたいと思う人はいないからです. (OTOH、完璧な歴史を求めてリベースに完全に夢中にならないでください。私たちは人間です。間違いを犯します。それに対処してください。)

git pull --rebase魔法に関する最後の観察。アップストリームのパブリック ブランチが賢明な方法でリベースされている場合 (たとえば、コミットを押しつぶしたり修正したり、そこに置くべきではないコミットを削除したり)、魔法はあなたに有利に働きます。ただし、アップストリームのリベースが誤ってコミットをドロップした場合、魔法は黙ってコミットを元に戻すことを防ぎます。この場合、ドロップされたコミットを元に戻したい場合は、代わりに を使用する必要がありますgit fetch; git rebase

于 2012-07-17T22:02:33.737 に答える
34

Git のルールは、履歴が共有、公開、またはプッシュされた後は、履歴を変更しようとしてはならないということです。もちろん、本当にそうしたい場合や十分な権限がある場合はそうすることができますが、他の人を台無しにする可能性があるため、細心の注意を払って行う必要があります。

幸いなことに、単一のアップストリーム リポジトリ (オリジン) を備えた典型的な Git の展開があり、それが宇宙のすべての善と真実のソースである場合git pull --rebase、心ゆくまで使用することができ、完全に安全であり、私の意見ではあなたはもっと正気な(つまり直線的な)歴史を持っています。私と私のチームはそれを継続的に使用しています。

ただし、複数のリモートを持ち始めてgit pull --rebase <arguments>、毎回同じターゲットに対してリベースしなくなったり、プライマリ アップストリームで実行する前にブランチを別のリポジトリにプッシュし始めたりすると、問題が発生し始める可能性があります。git pull --rebase

変更を別のリモート/リポジトリと共有してから、それらの変更を変更するときはいつでも(コミットメッセージ/コンテンツが変更されていなくても、変更の値がSHA、親などの変更に等しい場合)、人を台無しにすることができます誰が古い変更をしたか。

rebase sanity の範囲を超えない限り、それはあなたgit pull --rebaseにとって非常に良いことです。

git pull --rebaseそれは、エラー、との違いについての質問には答えませんgit fetch && git rebase @{u}。先に進んで、私は何の違いも認識していないと言います。違いがあるとしても、Git を何年も使用してきた間に気付かなかったほど微妙です。おそらく、複数のリポジトリがあり、「オリジン」がこのブランチの上流ではない場合、ブランチがフェッチする必要がある正しいリポジトリをシステムが把握するということですか?

そして、たとえ git-rebase で非常にうまくいかなかったとしても、もちろん、git log -gand/orを使用して元のリベース前の環境に簡単に戻すことができますgit reset --hard ORIG_HEAD。強制プッシュを行わないでください (ほとんどすべての Git サーバーでデフォルトで許可されていません)。

編集済み

時間が経つにつれて、私の理解は広がりました。git pull --rebaseリベース作業を行うための呼び出しgit rebaseなので、その意味ではそれらの間に違いはありません。ただし、 git-pull は実際に呼び出しますgit rebase --onto @{u} $(git merge-base HEAD @{u}@{1})

OK、その構文 ("@{u}@{1}") はおそらく少し不透明で、起動を単純化していますが、要点は、fetch コマンドを実行する前に、アップストリームへのマージ ベースが何であったかを検出することです。これはどのような違いを生むのでしょうか?

まあ、通常の場合はありません。ただし、アップストリームが指している場所を変更している場合、またはアップストリーム自体がリベースされている場合は、かなりの数になります。アップストリームが書き直されてからgit rebase @{u}、古いコミットがどれだけ書き直されたかによっては、非常に不幸になり、二重コミットや競合が発生する可能性があります。

ただし、背後にある魔法git pull --rebaseは、あなたのものであり、あなたのものだけが @{u} の上に適用されます。

OK、これ簡略化です。アップストリームが 100 コミ​​ット前からリベースを実行し (実際には履歴には 101 件以上のコミットがあります) 実行git fetch 前にを実行したgit pull --rebase場合、Git は適切な履歴マージベースが何であったかを正確に判断できません。あなたのローカルコミットは.

その結果、git fetch有害と見なされます (ローカル コミットがあり、アップストリームが書き換えられた場合)。ただし、実際の経験則は、「共有、公開、またはプッシュされた後は履歴を変更しようとしないこと」であり、これが私が始めたところです。

TL;DR:

git fetch有害と見なされます (したがって、 を使用しますgit pull --rebase)。また、共有、公開、またはプッシュされた後は、履歴を変更しようとしないでください (とりわけ、git fetch有害になるため)。

于 2011-06-08T20:54:29.040 に答える