Używam git-svn i zauważyłem, że kiedy muszę naprawić konflikt scalania po wykonaniu a git svn rebase
, znaczenie opcji --ours
i --theirs
np. git checkout
Jest odwrócone. To znaczy, jeśli istnieje konflikt i chcę zachować wersję, która pochodzi z serwera SVN i wyrzucić zmiany, które wprowadziłem lokalnie, muszę użyć ours
, kiedy bym się tego spodziewał theirs
.
Dlaczego?
Przykład:
mkdir test
cd test
svnadmin create svnrepo
svn co file://$PWD/svnrepo svnwc
cd svnwc
echo foo > test.txt
svn add test.txt
svn ci -m 'svn commit 1'
cd ..
git svn clone file://$PWD/svnrepo gitwc
cd svnwc
echo bar > test.txt
svn ci -m 'svn commit 2'
cd ..
cd gitwc
echo baz > test.txt
git commit -a -m 'git commit 1'
git svn rebase
git checkout --ours test.txt
cat test.txt
# shows "bar" but I expect "baz"
git checkout --theirs test.txt
cat test.txt
# shows "baz" but I expect "bar"
Odpowiedzi:
Wydaje się to zgodne z tym, co robi rebase.
git svn rebase
pobierze wersje z rodzica SVN bieżącego HEAD i przebuduje bieżącą (niezatwierdzoną do SVN) pracę przeciwko niemu.git rebase
wspomina:Zauważ, że scalanie rebase działa poprzez ponowne odtworzenie każdego zatwierdzenia z gałęzi roboczej na wierzchu
<upstream>
gałęzi.Z tego powodu, gdy dochodzi do konfliktu scalania:
<upstream>
,Innymi słowy, strony są zamieniane .
Jeśli pogodzisz obie definicje:
test.txt
plik zbar
zawartością)test.txt
plik zbaz
zawartością) jest "ich" i każdy z tych lokalnych zatwierdzeń Git jest odtwarzany.Innymi słowy, SVN czy nie:
<upstream>
gałąź " " (na której wszystko jest odtwarzane i która jest częścią dotychczas zmienionych zatwierdzeń ") jest" nasza ".Dobra wskazówka mnemoniczna od CommaToast :
(i pierwszą rzeczą, jaką
git rebase upstream
robi to w celu pobraniaupstream
gałęzi, na której chcesz zmienić bazę: HEAD odnosi się doupstream
-ours
teraz.)Zamieszanie prawdopodobnie wynika z roli działającej gałęzi w klasyku
git merge
.Podczas łączenia:
Jak wspomniano na
git rebase
stronie podręcznika , scalanie podczas rebase oznacza zamianę strony.Innym sposobem na powiedzenie tego samego jest rozważenie, że:
Przy scalaniu :
, nie zmieniamy bieżącej gałęzi `` B '', więc nadal mamy to, nad czym pracowaliśmy (i łączymy się z inną gałęzią)
Ale w przypadku rebase zmieniamy stronę, ponieważ pierwszą rzeczą, którą robi rebase, jest pobranie gałęzi upstream! (aby odtworzyć aktualne zatwierdzenia na górze)
A
git rebase upstream
najpierw zmieniHEAD
B na gałąź upstreamHEAD
(stąd zamiana „nasz” i „ich” w porównaniu do poprzedniej „bieżącej” gałęzi roboczej)., a następnie rebase odtworzy „swoje” zatwierdzenia w nowej „naszej” gałęzi B:
Jedynym dodatkowym krokiem
git svn rebase
jest to, że „pobieranie” svn jest wykonywane najpierw w zdalnej gałęzi Git reprezentującej zatwierdzenia SVN.Masz początkowo:
, najpierw aktualizujesz gałąź śledzenia SVN o nowe zatwierdzenia pochodzące z SVN
, następnie przełączasz bieżącą gałąź na stronę SVN (która staje się „naszą”)
, przed odtworzeniem zatwierdzeń, nad którymi pracowałeś (ale które są teraz „ich” podczas rebase)
źródło
git rebase
stronie podręcznika ...