1. ホーム
  2. ギット

[解決済み】Gitで、あるブランチを別のブランチに「マージ」ではなく「上書き」するには?

2022-03-27 17:31:37

質問

2つのブランチがあります。 emailstaging . staging は最新のもので、もう古い変更点は必要ありません。 email ブランチを削除したくありません。

の内容をすべてダンプしたいだけなのです。 stagingemail というように、両方が同じコミットを指すようにします。それは可能ですか?

解決方法は?

を使用することができます。 'ours' マージ戦略 :

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our (=staging) branch head
$ git checkout email
$ git merge staging


2020-07-30を編集しました。

この質問と可能な解決策についてもう少し考えてみました。親を正しい順序でマージすることが絶対に必要で、このアクションを 1 つのコマンドライン呼び出しで実行する必要があり、配管コマンドを実行しても構わない場合は、次のようにすることができます。

$ git checkout A
$ git merge --ff-only $(git commit-tree -m "Throw away branch 'A'" -p A -p B B^{tree})

これは基本的に、(存在しない) merge -s theirs 戦略です。 結果の履歴は plumbing ブランチ

と比べると、あまり読みやすくもなく、覚えやすくもありません。 -s ours というスイッチがありますが、これは仕事です。結果として得られるツリーは、再びBブランチと同じになります。

$ git rev-parse A^{tree} B^{tree} HEAD^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44


2020-07-29を編集しました。

との違いについて、多くの混乱があるようです。 -s ours-X ours (後者は -s recursive --strategy-option ours )があります。この2つの方法を使った2つの結果を示す小さな例を紹介します。の質問と回答も読んでおくことをお勧めします。 (Git マージ) 'ours' 戦略、'ours' オプションと 'theirs' オプションはいつ使うのですか?

まず、2つのブランチと3つのコミット(1つのベースコミット、ブランチごとに1つのコミット)でリポジトリを設定します。サンプルのリポジトリはこちらです。 をGitHubで公開しています。

$ git init
$ echo 'original' | tee file1 file2 file3
$ git commit -m 'initial commit'
$ git branch A
$ git branch B
$ git checkout A
$ echo 'A' > file1
$ git commit -m 'change on branch A' file1
$ git checkout B
$ echo 'B' > file2
$ git commit -m 'change on branch B' file2

では、試しに 戦略オプション (この説明では、彼らのものを使うか、我々のものを使うかはあまり重要ではありません)。

$ git merge -X ours A
$ cat file*
A
B
original

結局は マージ の両方のブランチの内容(サンプルリポジトリでは、ブランチ "strategy-option")が含まれています。を使用した場合と比較してみましょう。 マージ戦略 (次のステップを実行する前に、リポジトリを再インストールするか、ブランチをリセットしてください)。

$ git merge -s ours A
$ cat file*
original
B
original

結果はかなり異なっています (サンプル リポジトリの "merge-strategy" ブランチ)。strategy オプションを使用すると、両方のブランチのマージ結果が得られ、strategy を使用すると、もう一方のブランチで発生したすべての変更が破棄されます。

また、merge-strategy で作成されたコミットは "our"ブランチの最新コミットとまったく同じツリーを指しており、一方 strategy-option は新しい、これまで見たことのないツリーを作成していることに気づかれることでしょう。

$ git rev-parse A^{tree} B^{tree} merge-strategy^{tree} strategy-option^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44
5b09d34a37a183723b409d25268c8cb4d073206e

OPは確かに、"I no longer need old changes in [...] branch" と "So I just want to dump all the contents of [A] into [B]" を要求しましたが、これは戦略オプションでは不可能です。Ours' マージ戦略を使うことは、多くの可能性のうちのひとつですが、おそらく最も簡単な方法でしょう。 write-treecommit-tree ).