Возвращает ли git также использование 3-way-merge?

Когда я запустил git revert, это может произойти, что происходит конфликт. Влияет ли git на 3-way-merge, так как он изображен в вопросе слияния внутренних элементов (см. Таблицу ниже) также для revert?

enter image description here

Что такое база слияния для возврата? В Каковы три файла в трехстороннем слиянии для интерактивного перезагрузки с использованием git и meld? это совершенно ясно, но трудно представить это для возвращения.

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

(Если я хочу вернуть C в конце.)

1
11 мая '16 в 2:27
источник поделиться
1 ответ

Да, есть база. (Замечание: этот код сильно изменился с тех пор, как я смотрел его много лет назад. Я взял некоторые из них для моего недавнего ответа на вишневый выбор, который вы здесь связали.)

Оба варианта git cherry-pick и git revert теми же исходными файлами (builtin/revert.c и sequencer.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) является тем, что нужно для -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 строк, помещая части A и B в старые и новые поля префикса. Затем (после reverse_patches) при фактическом применении каждого патча git использует сохраненные старые и новые значения sha1 для подделки трехстороннего слияния (если git am задано --3way). Таким образом, обратное применение текстового патча, мы получим новый файл в качестве базы и оригинала в качестве цели, как и для кода sequencer.c.

3
11 мая '16 в 3:34
источник

Посмотрите другие вопросы по меткам или Задайте вопрос