首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >git revert也使用3-way-merge吗?

git revert也使用3-way-merge吗?
EN

Stack Overflow用户
提问于 2016-05-11 07:27:44
回答 1查看 341关注 0票数 1

当我运行git revert时,可能会发生冲突。git是否依赖于问题merge internals中所描述的三向合并(参见下表)也适用于revert

恢复的合并基础是什么?在What are the three files in a 3-way merge for interactive rebasing using git and meld?中,这一点非常清楚,但很难想象这是一种还原。

代码语言:javascript
复制
A - B - C - D - C^-1

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

EN

回答 1

Stack Overflow用户

发布于 2016-05-11 08:34:23

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

git cherry-pickgit revert都由相同的源文件(builtin/revert.csequencer.c)实现。

正如您所说,棘手的部分是决定为合并基础伪装什么。在您的示例中,我们将撤消BC的差异。以下是实际的源代码(用sequencer.c编写),略有删减:

代码语言:javascript
复制
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 {

这是一个精挑细选的案例,之所以包括在内只是为了完整。

代码语言:javascript
复制
        const char *p;

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

当我们进入这里时,commit指向C的数据,parent指向B的数据。变量base的赋值用于设置合并基础,next-vs-base用于引入。对于cherry-pick,提交的父级(可能通过-m选择)是合并基础。对于revert,提交本身是合并基,而父对象(也可能来自-m)是引入的内容。

获得相同效果的另一种方法(这是很多年前的方法,直到最近,我还认为这种方法仍然在使用)是反向应用git format-patch产生的提交。在这种情况下,构造的基础版本是第二个散列(文本diff的A..B部分的B部分):

代码语言:javascript
复制
/*
 * 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值来伪造三向合并(如果git am被赋予--3way)。因此,通过反向应用文本补丁,我们将获得新文件作为基础,原始文件作为目标,就像sequencer.c代码一样。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37150543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档