1. ホーム
  2. git

[解決済み] リベースの後、同じブランチに Git のコミットが複製される

2022-04-20 13:12:23

質問

Pro Git で提示されたシナリオは、以下の通りです。 リベースの危険性 . 著者は基本的に、重複したコミットを避ける方法を教えてくれます。

公開リポジトリにプッシュしたコミットをリベースしないでください。

私の特殊な状況をお話します。Pro Gitのシナリオとはちょっと違うようですが、それでも重複したコミットをしてしまうことがあるからです。

例えば、2つのリモートブランチと、それに対応するローカルブランチがあるとします。

origin/master    origin/dev
|                |
master           dev

4つのブランチにはすべて同じコミットが含まれており、私はこれから dev :

origin/master : C1 C2 C3 C4
master        : C1 C2 C3 C4

origin/dev    : C1 C2 C3 C4
dev           : C1 C2 C3 C4

数回コミットした後、その変更を origin/dev :

origin/master : C1 C2 C3 C4
master        : C1 C2 C3 C4

origin/dev    : C1 C2 C3 C4 C5 C6  # (2) git push
dev           : C1 C2 C3 C4 C5 C6  # (1) git checkout dev, git commit

に戻らねばならない。 master をクリックすると、すぐに修正できます。

origin/master : C1 C2 C3 C4 C7  # (2) git push
master        : C1 C2 C3 C4 C7  # (1) git checkout master, git commit

origin/dev    : C1 C2 C3 C4 C5 C6
dev           : C1 C2 C3 C4 C5 C6

そして、戻る dev 私は、実際の開発にクイックフィックスを含めるために変更をリベースしています。

origin/master : C1 C2 C3 C4 C7
master        : C1 C2 C3 C4 C7

origin/dev    : C1 C2 C3 C4 C5 C6
dev           : C1 C2 C3 C4 C7 C5' C6'  # git checkout dev, git rebase master

GitX/gitk でコミットの履歴を表示させると、次のようなことがわかります。 origin/dev は、2つの同じコミットを含んでいます。 C5'C6' であり、Gitとは異なるものです。では、もし私が変更を origin/dev これがその結果です。

origin/master : C1 C2 C3 C4 C7
master        : C1 C2 C3 C4 C7

origin/dev    : C1 C2 C3 C4 C5 C6 C7 C5' C6'  # git push
dev           : C1 C2 C3 C4 C7 C5' C6'

Pro Gitでの説明を理解しきれていないのかもしれないので、2つほど教えていただきたいのですが。

  1. なぜGitはリベースの際にこれらのコミットを重複させるのですか?を適用するだけでなく、そうする特別な理由があるのでしょうか? C5C6 の後に C7 ?
  2. どうすれば回避できますか?した方が賢明でしょうか?

どのように解決するのですか?

ここでは rebase を使うべきではありません。単純なマージで十分です。リンク先の Pro Git book では、基本的にこの状況を正確に説明しています。内部構造は若干異なるかもしれませんが、私はこのように考えています。

  • C5C6 から一時的に引き出されます。 dev
  • C7 が適用されます。 dev
  • C5 そして C6 の上に再生されます。 C7 新しい差分を作成し、新しいコミットを作成します。

ということで、あなたの dev というブランチを作成します。 C5C6 は事実上存在しなくなりました。 C5'C6' . にプッシュすると origin/dev の場合、git は C5'C6' を新しいコミットとして、履歴の末尾に追加します。実際 C5C5'origin/dev を見ると、内容は同じでも行番号が違うことに気づくでしょう -- つまりコミットのハッシュが違うのです。

Pro Gitのルールをもう一度説明します。 ローカルリポジトリ以外の場所に存在するコミットをリベースしてはならない . 代わりにマージを使用してください。