1

マスターが上流のブランチに追いつこうとしているという興味深い問題に遭遇しました。ただし、途中の特定のポイントでマスターをテストしたいので、特定のポイントでのみアップストリームをマスターにリベースするようにします。

次の状態を想定します。

          --F--G--H--> master
         /
        /
----A--B--C--D--E--I--J--> upstream

最初に C と D をリベースしてからテストしたいと思います。私もです:

$ git checkout upstream
$ git checkout D
$ git checkout -b upstreamD
$ git rebase -i master
$ git checkout master
$ git merge upstreamD

これは、リベースする C と D を示しています。リベースが成功した後、次のようになりました。

          --F--G--H--C--D--> master
         /
        /
----A--B--C--D--E--I--J--> upstream
             ^
         upstreamD

次に、テスト中などに不要になったため、アップストリームを削除しました(いつでも取得できるため)。

$ git branch -d upstreamD
$ git branch -d upstream
$ git remote rm upstream

テストを行い、すべて問題ないので、戻って新しく作成したリモートを使用してアップストリームを取得し、そのマスターをブランチ アップストリームに配置します。

だから、今私は次のようなものを持っていると思います(マスターとアップストリームにはより多くのコミットがあることに注意してください):

          --F--G--H--C--D--K--L--> master
         /
        /
----A--B--C--D--E--I--J--M--N--> upstream

そして、もう少しリベースしたいので、上記と同じ手順を実行します。

$ git checkout upstream
$ git checkout J
$ git checkout -b upstreamJ
$ git rebase -i master

しかし、今では、C、E、I、J のようなものをリベースするようになりました。奇妙なことに、私は E、I、J しか期待していませんでした。C は既にマスターになっています (たとえ別の SHA1 の下にあったとしても、履歴が異なるため) )。

http://www.kernel.org/pub/software/scm/git/docs/git-rebase.htmlには、次のように記載されています。

アップストリーム ブランチにすでに行った変更が含まれている場合 (たとえば、アップストリームに適用されたパッチをメールで送信したため)、そのコミットはスキップされます。

git がこのスキップを実行する方法を説明している場所はどこにも見つかりませんでした。C が既にマスターにあるかどうかをどのように確認し、C を再度リベースする必要があると判断し、D をリベースしないと判断するのはなぜですか?

4

1 に答える 1

4

git-rebase(1)から:

HEAD.. でのコミットと同じテキストの変更を導入する HEAD でのコミットは省略されることに注意してください (つまり、異なるコミット メッセージまたはタイムスタンプですでにアップストリームで受け入れられているパッチはスキップされます)。

git format-patch(これは、具体的には--ignore-if-in-upstreamオプションを介して実装されているようです。)

これは、リベースがパッチを自動的にスキップするには、パッチがテキスト的に同一である必要があることを意味します (コミット メタデータや SHA ID などではなく、パッチのみ)。

上記の例では、コミット C に解決しなければならない競合があった可能性が高いと思われます。この結果、パッチは異なります。コミット D が競合しなかった場合でも、テキストは同一であるため、C をスキップしなかったのにリベースがそれをスキップしたのはなぜですか。

私の意見では、このシナリオを処理する最善の方法は、次のように--ontoオプションを使用することです。git rebase

git rebase --onto master D

D は、リベースした最後のコミットです。他にも方法があります。インタラクティブにリベースし、すでに存在することがわかっているコミットを削除することはその 1 つです。

の自動スキップ ロジックはgit rebase「ベスト エフォート」のロジックであると考えています。機能する場合は素晴らしいですが、これまで見てきたように、機能しない場合に備える必要があります。

HTH。

于 2012-10-11T18:19:11.797 に答える