2009-11-04 14 views
17

Próbuję scalić 2 gałęzie, które mają wiele zmian w nich, kilka z konfliktami scalania. Połączyłem pliki przy użyciu git mergetool, ale później zrozumiałem, że scaliłem kilka z nich niepoprawnie. Zasadniczo chcę wrócić do konfliktu dla tych plików par, więc mogę ponownie uruchomić mergetool i poprawić moje błędy. Nie chcę wyrzucać całego mojego scalenia, ponieważ większość z nich jest poprawna.Jak odzyskać konflikty git po niepoprawnym scaleniu?

Próbowałem resetowania do mojej głowy, a następnie robi git checkout -m other_branch -- my_file na próżno. Zakończyłem resetowanie do HEAD, odebranie pliku z innego oddziału i wykonanie tylko pliku git add --patch, a jedynie inscenizowanie tego, co chciałem. Ale nie musi być lepszy sposób ...

Odpowiedz

12

Po pierwsze, sprawdź, czy masz skonfliktowany stan w indeksie (przed kasowaniem do HEAD), poprzez

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

Powinieneś dostać coś jak następuje:

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

Jeśli tego nie zrobisz, będziesz musiał użyć git update-index, np. Charles Bailey said lub użyć plików tymczasowych. Jeśli masz to, to powinno działać (mam to zaznaczone).

+0

prostu starał 'git checkout -m' i działa nawet jeśli tylko jeden dostać jeden wystawił wersję pliku (to znaczy po' add' git lub udanego wykorzystania 'git mergetool'). Może to nowsza funkcja Git (używam 2.1.3). – siegi

6

Ty może zrobić z git update-index użyciem albo --cacheinfo lub --index-info opcji, aby usunąć wpis w indeksie dla danego pliku 0 i wypełniania 1, 2 i 3 wpisy odpowiednio z wersją podstawową, lokalną i zdalną, ale będzie to skrzypce.

Najprawdopodobniej łatwiej będzie wyodrębnić różne wersje do plików tymczasowych i ręcznie uruchomić narzędzie scalające, wpisując odpowiedź w poprawnym pliku i dodając wynik pomyślnego scalenia.

np.

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 ręcznie, pisząc do file.

git add file 
0

można użyć:

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

do kasy, ścieżka (ścieżki), jak ustalono w gałęzi są połączone do lub z lub odtworzyć konflikt seryjnej.

Strona podręcznika git-checkout zawiera nieco więcej informacji na ten temat.

Jak zauważył Charles Bailey, to nie działa, gdy połączony plik został już dodany do indeksu. Grałem trochę, a oto skrypt, który powinien wykonać zadanie:

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

Pamiętaj, że nie testowałem aż tak dużo. Jeśli napotkasz jakieś problemy lub masz inne ulepszenia, here to "sedno".

+1

Warto zauważyć, że działa to tylko wtedy, gdy nie zakończyłeś mergetool, zapisując "pomyślnie", ponieważ powoduje to, że mergetool "doda" rozwiązany plik i usunie sprzeczne wpisy z indeksu. –

+0

Charles Bailey, czy jesteś pewien, że to, co mówisz, jest poprawne? Skrypt do mnie bardzo przypomina dokładnie przywrócenie indeksu do stanu/przed/add został zrobiony! Nie odnosi się to do: {1,2,3}: początkowo, ale raczej adresowania commitów przez HEAD, MERGE_HEAD i 'merge-base ...'. –

+0

@TilmanVogel: Sprawdź wersję odpowiedzi, którą skomentowałem, a nie aktualizację w odpowiedzi na mój komentarz. –

0

Jeśli przypadkowo zgodzisz się na odpowiedź w odpowiedzi na konflikt, nie zapisując zmian z mergetool, myślę, że możesz po prostu przechować wprowadzone zmiany i ponowić scalenie.

git stash 
git merge <other branch> 
Powiązane problemy