2016-05-10 13 views
1

git revertを実行すると、競合が発生する可能性があります。 gitは、merge internalsの質問(下の表を参照)にも示されているように、3ウェイマージに頼っていますか?revertgit revertは3方向マージも使用していますか?

enter image description here

元に戻すためのマージベースは何ですか? What are the three files in a 3-way merge for interactive rebasing using git and meld?ではかなり明確ですが、これを元に戻すために想像するのは難しいです。

A - B - C - D - C^-1 

(私は最後にCを元に戻したい場合。)

答えて

3

はい、ベースがあります。 (サイドノート:このコードは数年前に見たときから大きく変わってきましたが、ここでリンクしている私の最近のチェリーピックの答えのいくつかを取り上げました)。

git cherry-pickgit revertは両方とも同じソースファイル(builtin/revert.csequencer.c)。

あなたが言うように、トリッキーな部分は、マージベースのために何を偽造するかを決めることです。あなたの例では、B -to-Cの差分を元に戻しています。ここでは、実際のソースコードが(sequencer.c中)ですが、多少のストリップダウン:

if (opts->action == REPLAY_REVERT) { 
     base = commit; 
     base_label = msg.label; 
     next = parent; 
     next_label = msg.parent_label; 
     strbuf_addstr(&msgbuf, "Revert \""); 
     strbuf_addstr(&msgbuf, msg.subject); 
     strbuf_addstr(&msgbuf, "\"\n\nThis reverts commit "); 
     strbuf_addstr(&msgbuf, oid_to_hex(&commit->object.oid)); 

     if (commit->parents && commit->parents->next) { 
       strbuf_addstr(&msgbuf, ", reversing\nchanges made to "); 
       strbuf_addstr(&msgbuf, oid_to_hex(&parent->object.oid)); 
     } 
     strbuf_addstr(&msgbuf, ".\n"); 
} else { 

 const char *p; 

     base = parent; 
     base_label = msg.parent_label; 
     next = commit; 
     next_label = msg.label; 

私たちはここに入力し、commitポイントへ[これはチェリーピックケースで、ちょうど万全を期すために含ま] Cおよびparentのデータは、Bのデータを示しています。変数baseへの代入はマージベースを設定するもので、next -vs-baseは何を持ってくるかです。チェリーピックの場合、コミットの親(おそらく-mで選択)がマージベースです。復帰の場合、コミット自体はマージベースであり、親(おそらく-mから)は何をもたらすかです。

これとは別のやり方は、これが何年も前に行われた方法であり、最近まで私はこれがまだ使用されていたと考えています。git format-patchによって生成されたコミットを逆適用することです。構築ベースのバージョンが第2のハッシュ(テキスト差分のA..B部分からB部)である。この場合には、:

/* 
* This represents a "patch" to a file, both metainfo changes 
* such as creation/deletion, filemode and content changes represented 
* as a series of fragments. 
*/ 
struct patch { 
[snip] 
    char old_sha1_prefix[41]; 
    char new_sha1_prefix[41]; 

static void reverse_patches(struct patch *p) 
{ 
[snip] 
      swap(p->old_sha1_prefix, p->new_sha1_prefix); 

reverse_patches機能、すなわち、一連のパッチにテキストを抽出した後に呼び出され、 index行からハッシュを抽出するコードの後に​​、AB部分を古いプレフィックスフィールドと新しいプレフィックスフィールドに入れます。そして、(reverse_patchesの後に)実際に各パッチを適用するとき、gitは保存された古いsha1値と新しいsha1値を​​使って、3ウェイマージ(git am--3wayの場合)を偽造します。したがって、テキストパッチを逆適用すると、sequencer.cコードの場合と同様に、新しいファイルをベースとして、オリジナルをターゲットとして取得します。

関連する問題