リベースと、プッシュされたコミットをリベースすることの意味


109

すでにプッシュしたコミットをリベースしてはいけないとよく言われます。その意味は何でしょうか?

回答:


80

ProGitの本は持っている良い説明を

あなたの質問に対する具体的な答えは、「リベースの危険」というタイトルのセクションにあります。そのセクションからの引用:

何かをリベースすると、既存のコミットを破棄し、類似しているが異なる新しいコミットを作成します。コミットをどこかにプッシュし、他の人がそれらをプルダウンして作業をベースにし、その後それらのコミットをgit rebaseで書き直して再度プッシュすると、共同編集者は作業を再マージする必要があり、しようとすると事態が乱雑になります彼らの仕事をあなたのものに戻しなさい。

更新:
以下のコメントに基づいて、Gitワークフローで問題が発生しているようです。以下は参考になる参考資料です。


説明ありがとう。したがって、理解を明確にするために、特定の変更をプッシュした後、git rebase(--interactive?)を使用してその履歴を書き換えるべきではありませんが、これは間違いなく失敗のレシピです。ブランチ(ブランチXから)を押してプッシュします。別の開発者がトピックブランチを変更した後、再度リベースするのはまったく正常です。基本的に、私はmergeかなり長い間使用してきましたが、私たちはdarwinweb.net/articles/86と同じ船に乗っていて、その歴史はほとんど使用できません。
Hemant Kumar

@ヘマント:パブリックリポジトリにプッシュした後にコミットをリベースすることは、一般的に悪い考えです。とはいえ、あなたが引用したdarwinweb記事のアドバイスは、ワークフローが類似している場合は妥当だと思われます。役立つかもしれない他の参考文献のリストについては、私の更新された応答を参照してください。
Tim Henigan

する「プライベート管理チーム」約「ProGit」ページへのリンクを更新してくださいgit-scm.com/book/en/...
Eimantas

したがって、技術的には、gitコミットは同じままですが、「既存のコミットを結合し、類似しているが異なる新しいコミットを作成する」とは、異なるsha1 idを持つ同じコミットだけです。共同編集者が自分の作業を再マージしなければならない理由を私が考えることができる唯一の明白な方法だと思います。
Ciasto piekarz 2018年

@Ciastopiekarz、これは上流のリポジトリの履歴を書き換えているためであり、他の開発者のローカルリポジトリがそのポインタを持っている可能性があります。現在、それらのポインターは古くなっています。gitクライアントには、古いポインターを使用し、残りを整理するために人間に依存する以外に選択肢はありません。これは再マージであり、手作業で整理する必要のある多くの混乱する変更があり、非常に面倒になる可能性があります。したがって、すでにアップストリームリポジトリにプッシュされているものをリベースしないことを推奨します。これは良いアドバイスです。深い知識を持つ専門家でない限り、無視しないでください。
Forbin

240

これを理解するには、gitの動作について少し理解する必要があります。gitリポジトリはツリー構造であり、ツリーのノードはコミットです。非常に単純なリポジトリの例を次に示します。 あなたがフォークするとき

masterブランチには4つのコミットがあり、各コミットにはID(この場合は、a、b、c、およびd)があります。現在、dがmasterブランチの最新のコミット(またはHEAD)であることがわかります。 ここに画像の説明を入力してください

ここには、masterとmy-branchの2つのブランチがあります。masterとmy-branchの両方にコミットaとbが含まれていることがわかりますが、その後、分岐が始まります。masterにはcとdが含まれ、my-branchにはeとfが含まれています。bは、マスターと比較してmy-branchの「マージベース」であると言われています。より一般的には、単に「ベース」です。これは理にかなっています。my-branchが以前のバージョンのマスターに基づいていたことがわかります。

my-branchが古くなり、masterの最新バージョンで最新にしたいとします。言い換えると、my-branchにはcとdが含まれている必要があります。マージを行うこともできますが、その場合、ブランチに奇妙なマージコミットが含まれ、プルリクエストの確認がはるかに困難になります。代わりに、リベースを行うことができます。

ここに画像の説明を入力してください

リベースすると、gitはブランチのベース(この場合はb)を見つけ、そのベースとHEADの間のすべてのコミット(この場合はeとf)を見つけて、ブランチのHEADでそれらのコミットを再生しますあなたは(この場合はマスター)にリベースしています。Gitは実際には、マスターの上に変更がどのように見えるかを表す新しいコミットを作成します。図では、これらのコミットはe 'およびf'と呼ばれています。Gitは以前のコミットを消去しません。eとfはそのままです。リベースに問題が発生した場合は、以前の状態に戻すことができます。

多くの異なる人々がプロジェクトで擬似的に作業している場合、プルリクエストはすぐに古くなります。「古くなった」プルリクエストとは、開発のメインラインで最新ではなくなったものであり、プロジェクトにマージする前に更新する必要があります。プルリクエストが失効する最も一般的な理由は競合によるものです。2つのプルリクエストの両方が同じファイル内の同様の行を変更し、1つのプルリクエストがマージされると、マージされていないプルリクエストは競合するようになります。場合によっては、プルリクエストが競合することなく陳腐化する可能性があります。コードベース内の別のファイルを変更すると、プルリクエストに対応する変更が必要になるため、新しいアーキテクチャに準拠する必要があります。または、誰かが誤ってユニットテストをマスターブランチ。理由にかかわらず、


68

リベースは履歴を書き換えます。その歴史について誰も知らなければ、それはまったく問題ありません。ただし、その歴史が公に知られている場合、Gitでの歴史の書き換えは、現実の世界と同じように機能します。陰謀が必要です。

陰謀は一緒に保つのが本当に難しいので、そもそも公共の支店をリベースすることを避ける方が良いです。

陰謀の成功例あることに注意してくださいpu。JunioC. Hamanoのgitリポジトリ(Git SCMの公式リポジトリ)のブランチは頻繁にリベースされています。これが機能する方法は、使用するほとんどすべての人puがGit開発者のメーリングリストにも登録されていることです。puブランチがリベースされているという事実は、メーリングリストとGit Webサイトで広く公開されています。


4
+1。pugit.git のブランチは、(パブリック)ワークフローでリベースを使用する方法の非常に役立つ例だと思います。慣れていない人のための一般的なアイデアは、コミットのないトピックブランチnext(マスターにマージする直前の不安定なブランチ)をリベースpunext、にリセットしてブランチを再構築し、すべてのトピックブランチをマージすることです。(出典:ドキュメント/ HOWTO /維持-git.txt git.kernel.org/?p=git​​/git.git;a=blob;f=Documentation/howto/...
カスカベル

25
「Gitでの履歴の書き換えは、現実の世界と同じように機能します。陰謀が必要です」
Sleeper Smith

「上記のように、puは使い捨てのブランチであるため、公表は必要ありません。」git-scm.com/docs/gitworkflows職場で も同様の処理を行います。「TEMP-something-latest」は、最新の変更を組み合わせた使い捨てブランチです。複数の機能ブランチをマージしたり、削除したりできますいつでも再作成できるため、開発すべきではありません。
pilkch

6

リベースはリポジトリの履歴を変更します。コミットを世に送り出し、他の人が利用できるようにしてから、コミット履歴の見方を変えると、古い履歴を持つ人と一緒に作業することが難しくなります。

有害だ考えられているリベースは良い概観だと思います。

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