Как мне вернуть конфликты слияния git после слияния неправильно?
Я пытаюсь объединить 2 ветки, которые имеют много изменений в них, несколько с конфликтами слияния. Я объединил файлы с помощью git mergetool
, но впоследствии понял, что я объединил пару из них неправильно. Я в основном хочу вернуться в конфликтное состояние для этих файлов папок, поэтому я могу повторно запустить mergetool и исправить свои ошибки. Я не хочу выбрасывать все мое слияние, так как большая часть из них верна.
Я попробовал сбросить настройки в свою голову, а затем сделать git checkout -m other_branch -- my_file
безрезультатно. Я закончил загрузку в HEAD, вытащил файл из другой ветки и просто сделал git add --patch
в файле, только выполнив то, что я хотел. Но должен быть лучший способ...
Ответы
Ответ 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>