1

当我运行git revert时,可能会发生冲突。git 是否依赖于 3-way-merge,正如问题合并内部(参见下表)中所描述的那样,它是否也适用于revert?

在此处输入图像描述

还原的合并基础是什么?在使用 git 和 meld 进行交互式变基的 3 路合并中的三个文件是什么?这很清楚,但很难想象这是为了恢复。

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

(如果我想C在最后恢复。)

4

1 回答 1

5

是的,有一个基地。(旁注:自从我几年前查看它以来,这段代码已经发生了很大变化。我为我最近挑选的答案挑选了其中一些,你已经链接到这里。)

两者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指向数据为Cparent指向数据为B。对变量的赋值base是设置合并基础的内容,而next-vs-base是要引入的内容。对于cherry-pick,提交的父级(可能通过 选择-m)是合并基础。对于还原,提交本身是合并基础,而父项(也可能来自-m)是要引入的内容。

获得相同效果的另一种方法(多年前就是这样做的,直到最近,我认为这仍在使用)是反向应用由git format-patch. 在这种情况下,构造的基本版本是第二个哈希(B来自A..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 值来伪造 3 路合并(如果git am给出--3way)。因此,通过反向应用文本补丁,我们将获得新文件作为基础文件和原始文件作为目标文件,就像sequencer.c代码一样。

于 2016-05-11T00:34:22.870 回答