2009-11-04 2 views
17

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

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

ответ

12

Во-первых, проверьте, если вы конфликтовали состояние в индексе (перед сбросом в ГОЛОВА), через

$ 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 said, или использовать временные файлы. Если у вас это есть, то

$ git checkout -m my_file 

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

+0

Просто попытался 'GIT оформления заказа -m' и она работает, даже если я получаю только один один поставил версию файла (то есть после того, как' мерзавца add' или успешного использования 'мерзавца mergetool'). Возможно, это более новая функция Git (я использую 2.1.3). – siegi

6

Вы можете сделать это с 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 

Run mergetool вручную, запись в file.

git add file 
0

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

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

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

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

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

#!/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 

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

+1

Возможно, стоит отметить, что это работает только в том случае, если вы не вышли из слияния, сохраняя «успешно», поскольку это приводит к тому, что mergetool «добавляет» разрешенный файл и удаляет конфликтующие записи из индекса. –

+0

Charles Bailey, вы уверены, что вы говорите правильно? Сценарий для меня очень похож на то, что он точно восстановил индекс до состояния/до/добавить! Это не относится к: {1,2,3}: первоначально, а скорее адресует коммиты через HEAD, MERGE_HEAD и «merge-base ...». –

+0

@TilmanVogel: Пожалуйста, проверьте версию ответа, о которой я прокомментировал, а не обновление в ответ на мои комментарии. –

0

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

git stash 
git merge <other branch> 
Смежные вопросы