1

私は次のようなレポを持っています(または持っていることを目指しています!):

Master *-----*--*----------C---
        \                   \
Project1 \-*-------A----B----M2---A'--B'---
          \              \             \
Project2   \----------*---M1------------M2---

マージM2を実行したいのですが、 AB完全に無視したいと思います。次に、マスターからの新しい変更の上に、必要に応じてA'B'を手動で (例: チェリーピック) 再作成します。

Project2 は Master に基づいていますが、Project1 からの変更がマージされています。

望ましい結果:

  1. ファイルに関して、ポイントM2をCの同一のコピーにしたいと考えています。

  2. Project2 がそこからマージできるように、Project1 には独自の線形履歴が必要です。

コンテキスト: Master は Drupal の主要なコードベースです。Project1 は、いくつかのプロジェクトと共有したい特定のパッチを維持するために使用するブランチです。Project2 (およびその他の多く) は Project1 からマージされます。

私は考えました:

  1. git merge -s recursive -X theirs masterこれに関する問題は、AFAIKがtheirs何かが競合する場合にのみ優先することです。したがって、A の変更が競合しない場合、それはM2に存在し、これは A' が不完全であることを意味します。

  2. git revert B..A ; git merge Cこれは機能しますが、面倒で長い歴史が残ります。

  3. ありますがgit merge -s ours、ないようですgit merge -s theirs

  4. git reset --hard Cこれは、Project1 を Project2 にマージする可能性を (私が思うに) 壊すため、したくありません。もう 1 つの方法は、Project1 を C にリベースすることですが、これは Project2 にマージできないことを意味します。

4

2 に答える 2

2

私はあなたの計画に反対するようアドバイスします – あなたは git をだまそうとしているのです。Git はだまされるのが好きではありません。また、あなたは自分の歴史を「偽造」しています。M2、A'、および B' はすべて 1 つのコミット (マージ) である必要があります。

しかし、先に進みたい場合は、次のようにします。

git merge --no-commit C
rm -rf *
git checkout C .
git commit

保持したい gitignored ファイルがある場合は、前にそれらをバックアップし、rm後でそれらを復元します。

または、次のこともできます(実際にはもっときれいです)

git checkout C
git symbolic-ref HEAD refs/heads/Project1
git update-ref MERGE_HEAD C
git commit
于 2012-12-10T14:29:29.783 に答える
1

これは、「配管」コマンドで実行できます。

$ git checkout Project1
$ git diff HEAD..master | patch -p1 
$ git add -A .
$ git commit-tree `git write-tree` -p master -p Project1 \
      -m "Merge to clean Master at v1.2"
0c5290081989cc28ff3977fbfe3951db7b7778b0
$ git reset --hard 0c5290081989cc28ff3977fbfe3951db7b7778b0

は、私が現在いる場所 ( B ) と私が行きたい場所 ( Cgit diff HEAD..master ) から 1 つの大きなパッチで取得する方法を教えてくれます。もちろん、パッチはそれを適用します。

git add -A .作業ツリーのすべての変更をインデックスに追加します。

次に、次の行でこれのマージ コミットを作成しgit-write-treeます。 はインデックスから新しいツリー オブジェクトを作成し、その SHA1 を引数として に出力します。これは、2 つの親、Project1 の現在のヘッド ( B )git commit-treeを持つコミットを作成します。とマスター ( C ) を入力し、適切なメッセージを送信します。

Git はコミット オブジェクトを作成しますが、このコミットを使用するためにブランチを更新しません。最後の行は、現在のブランチである Project2 を、それが生成したコミット SHA1 に進める (早送りする) ことを git に伝えます。

そこから、必要に応じてパッチ A' と B' を再作成できます (たとえば、cherry-pick で試すことができます)。

于 2012-12-10T14:57:29.523 に答える