2017-10-31 4 views
0

:私はgit rebase c6 c5 --onto c6は私がc3を再生できるようにすることがわかった feature | c3 - merge_master - c6 / / \ master | c1 - c2 - c5 ------------- merge_feature - c7 スカッシュ、私はどのようにスカッシュ、このようなマージされたブランチの全てのコミット知りたいのですがマージされたブランチ

と、私はこの master | c1 - c2 - c5 - squash_c3_c6 - c7

を持つことを目指しおよびc6にはc3'c6'がありますが、私はいつもc3c6です。

は、私は大きなリポジトリ(6K以上の支店を!)を処理するためのスクリプトでこれを行う必要がありますので、私はgit rebase -i

任意のアイデアを使用することはできませんか?

答えて

0

あなたが望むものを得ることはできませんが、あなたがすることはうまくいくかもしれません。

Gitでは、「スカッシュ」は「コピー」を意味します。より具体的には、「squash merge」は、というマージアクションマージ(動詞としてという単語)を実行するGitのマージ機構を使用しますが、通常のコミットを行います。 ;およびいくつかのコミットが両方の上にある

C3--C6 <-- feature 
/
C1 
    \ 
    C2--C5 <-- master 

masterまたはfeatureなどの支店名が実際すなわち先端はブランチのコミット、コミットだけを指していることに注意してください:たとえば、あなたがこれを持っていた、と仮定C1などのブランチ)。 git checkout master && git merge --squash featureを実行すると、その後になります。

  • は枝のコミット共有最後の場所としてC1を選択してください。
  • 現在のブランチの先端にC5を選択してください。master;
  • featureの先端にC6を選択してください。

これらは、マージ処理(「マージ」を動詞として使用)への入力です。次に、Gitはします:

  • C1C5対比較:これは "私たちは何が変更されたか" です。
  • と比較してください。C1C6:これは「変更されたもの」です。

Gitは両方の変更セットを結合しようとします。すべてがうまくいけば、結果はインデックスと作業ツリーに置かれます(コミットのためにステージングされます)。 --squashを使って自動的に--no-commitを有効にしたので、Gitはコミットすることなくこの時点で停止しますが、あらかじめロードされたコミットメッセージを作成します。

あなたは今普通は(マージコミット-これはない単語を使用していますコミットのタイプを記述する、形容詞としてをマージ)コミットせた、git commitを実行することができます。それは普通のコミットしたいだけで何のようになります。

C3--C6 <-- feature 
/
C1 
    \ 
    C2--C5--C7_which_is_3_plus_6 <-- master (HEAD) 

この時点でブランチ名featureを行うための唯一の賢明なことは、それを削除され、元を放棄することはC3C6(彼らは最終的に意志、あるいはおそらく非常にコミットすぐに、ガベージコレクションされます:ブランチを削除すると、ブランチを保護するブランチのreflogも削除されます)。

truemerge.logを設定するかである数C7のログメッセージは、あなたがそれになりたいものですが、あなたはGitリポジトリの構成方法に応じて、あなたはそれがC3C6から既存のログ・メッセージを組み合わせることをデフォルトに取得することができます2以上、または--logを使用してください)。新しいは、元C3C6(マイナスすでにC5によって複製何も)で行われたものを取ることC7をコミット

注意。おそらく、このように完全にfeatureを削除しても安全です。

残念ながら、それはあなたが持っているものではありません。あなたは既にマージは、あなたが描いたグラフを与え、featureの先端から到達可能なコミットがあります

featuremasterのマージベースが今
C3--C4--C6 <-- feature 
//
C1--C2--C5 <-- master 

C1をコミットするのではなく、C2をコミットしていません。これは、masterから開始し、逆方向に作業すると、C5、次にC2、次にC1となります。 featureから開始して後方に進むと、C6、次にC4、次にC3C2の両方が同時に検出されます。 C1

これは、C2ではなく、C1が、両方のブランチにある両方のブランチのヒントに対して最も近いコミットであることを意味します。その後、masterにするときgit merge --squashをします使用:

  • デフC2C5 VS:私たちは何が変更されましたか。
  • diff C2C6:変更内容
  • 変更を組み合わせて、あなたは、新しいがC7をコミットすることができますによる暗黙の--no-commit

に停止:

C3--C4--C6 <-- feature 
//
C1--C2--C5----C7 <-- master 

ここでも、featureで行う唯一の賢明なことは、それを削除することです。結果はシーケンス...--C1--C2--C5--C7になります。 これは前とコミットのと同じ順序で、そしてより重要なのは、C7に関連したツリー(ソースの内容が)限りC4自体はevil mergeないよう、あなたがC4せずに取得したいツリーと同じである必要がありますC6C4の部分を元に戻しません。

C4には、C3からの変更が含まれており、明らかにC6には、C6の変更が含まれているためです。これは、Gitがgit diff C2 C6を実行したときに、C3C6の両方の変更が見られたことを示しています。これらは、動詞としてのマージの2つの入力の1つの一部です。したがって、新しいC7には、必要な変更がすべて含まれています。

はそれが--logmerge.log設定によっては、持っていない何、ログメッセージの自動集団です。しかし、C7のログメッセージは、C1のような前回のコミットを見つけたり、git log --pretty=short --no-merges <hash>..featureを使って好きなように編集することができます。

0

あなたが探しているものはgit filter-brabchで、マージコミットから2番目の親を削除すると思います。

ような何か(テストしていません!)

git filter-branch --parent-filter 'read pkey pvalue rest && echo "$pkey $pvalue"' branch_first_commit..branch 

(それはSEDやawkので速いかもしれないが、私は引用して、いくつかのミスを犯すことを恐れてんだ。それはまた、最初のコミットに失敗する場合があります)

説明古い履歴が競合する可能性があるため、ブランチ履歴の再生を確実に自動的に行うことはできません。しかし、 "squashed merge"は削除された第2の親とのマージだけです。そしてあなたはすでにマージがあるので、両親を削除するだけです。

0

私はgit filter-branch --parent-filterと一緒に遊んだので、すべてのマージされたブランチコミットを自分のマスターに平らにすると便利ですが、コミットの正しい順序は=>C1--C3--C2--C4--C5です。結果は良いですが、歴史は矛盾するようになりました。私はC1--C2--C3--C4--C5のようなものを期待していましたが、これでもC3とC4を押しつぶすことになりました。

@torek説明のおかげで、C2とC3は、 "機能ブランチからのコミット"または "マージブランチからのコミット"のような起源の概念なしで、C4の同等の祖先であることが分かりました。そして、 "マージコミット"がありますが、マージを行うコミットだけです。

私は、rebase interactive modeをスクリプト化する方法があることを発見しました。私は、リベースインタラクティブでこれをスクリプト化するつもりです。

お知らせします。

関連する問題