Подтвердить что ты не робот

Как мне вернуть конфликты слияния git после слияния неправильно?

Я пытаюсь объединить 2 ветки, которые имеют много изменений в них, несколько с конфликтами слияния. Я объединил файлы с помощью git mergetool, но впоследствии понял, что я объединил пару из них неправильно. Я в основном хочу вернуться в конфликтное состояние для этих файлов папок, поэтому я могу повторно запустить mergetool и исправить свои ошибки. Я не хочу выбрасывать все мое слияние, так как большая часть из них верна.

Я попробовал сбросить настройки в свою голову, а затем сделать git checkout -m other_branch -- my_file безрезультатно. Я закончил загрузку в HEAD, вытащил файл из другой ветки и просто сделал git add --patch в файле, только выполнив то, что я хотел. Но должен быть лучший способ...

4b9b3361

Ответ 1

Сначала проверьте, было ли у вас конфликтное состояние в индексе (до сброса в HEAD), через

$ git ls-files --stage --abbrev my_file

Вы должны получить что-то вроде следующего:

100644 257cc56  1        my_file
100644 b7d6715 2        my_file
100644 5716ca5  3        my_file

Если вы этого не сделаете, вам нужно будет использовать git update-index, например Charles Bailey или использовать временные файлы. Если у вас есть это, то

$ git checkout -m my_file

должен работать (я это проверил).

Ответ 2

Вы можете сделать это с помощью git update-index с помощью опций --cacheinfo или --index-info, чтобы удалить запись 0 в индексе для данного файла и заполнить 1, 2 и 3 записи с базовой, локальной и удаленной версиями соответственно, но это будет неудобно.

Вероятно, будет легче извлечь различные версии во временные файлы и вручную запустить инструмент слияния, написание ответа на правильный файл и добавление результата успешного слияния.

например.

git show $(git merge-base HEAD MERGE_HEAD):file >base-file
git show HEAD:file >local-file
git show MERGE_HEAD:file >remote-file

Запустите mergetool вручную, набрав file.

git add file

Ответ 3

Вы можете использовать:

git checkout [--ours|--theirs|--merge] <paths>

чтобы проверить путь (ы), найденный на ветке, которая объединяется в или из или для воссоздания конфликтующего слияния.

Страница git -checkout имеет немного больше этой проблемы.

Как заметил Чарльз Бейли, это не работает, когда объединенный файл уже добавлен в индекс. Я немного поиграл, и вот script, который должен выполнить эту работу:

#!/bin/bash
#
# Distributed under the GNU General Public License, version 2.0.
#
# git-goat:
#
#   Restore a merge conflict, after it has already been resolved.

# Lifted from contrib/completion/git-completion.bash
__gitdir ()
{
    if [ -z "${1-}" ]; then
        if [ -n "${__git_dir-}" ]; then
            echo "$__git_dir"
        elif [ -d .git ]; then
            echo .git
        else
            git rev-parse --git-dir 2>/dev/null
        fi
    elif [ -d "$1/.git" ]; then
        echo "$1/.git"
    else
        echo "$1"
    fi
}

into=$(git describe --all HEAD)
from=$(cat $(__gitdir)/MERGE_HEAD)
base=$(git merge-base $into $from)

case "$1" in --ours|--theirs|--merge) whose=$1; shift; esac

[ -z "$1" ] && echo "fatal: at least one file has to be specified" && exit

for file in "[email protected]"
do
    (
        echo -e "0 0000000000000000000000000000000000000000\t$file"
        git ls-tree $base $file | sed -e "s/\t/ 1\t/"
        git ls-tree $into $file | sed -e "s/\t/ 2\t/"
        git ls-tree $from $file | sed -e "s/\t/ 3\t/"
    ) | git update-index --index-info
    git checkout ${whose:-"--merge"} $file
done

Обратите внимание, что я не очень много тестировал. Если вы обнаружите какие-либо проблемы или получили другие улучшения здесь, это может быть "гроздь".

Ответ 4

Если вы случайно согласитесь сказать "да" в разрешенное разрешение конфликта без сохранения изменений с mergetool, я думаю, вы можете просто спрятать поэтапные изменения и повторить слияние.

git stash
git merge <other branch>