Eu uso git-svn e percebi que quando preciso consertar um conflito de mesclagem depois de executar um git svn rebase
, o significado das opções --ours
e --theirs
para, por exemplo, git checkout
é invertido. Ou seja, se houver um conflito e eu quiser manter a versão que veio do servidor SVN e descartar as alterações que fiz localmente, tenho que usar ours
, quando esperava que fosse theirs
.
Por que é que?
Exemplo:
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"
Respostas:
Isso parece consistente com o que um rebase faz.
git svn rebase
irá buscar revisões do SVN pai do HEAD atual e realocar o trabalho atual (não comprometido com o SVN) contra ele.git rebase
menciona:Observe que uma junção de rebase funciona repetindo cada commit do branch de trabalho no topo do
<upstream>
branch.Por causa disso, quando ocorre um conflito de mesclagem:
<upstream>
,Em outras palavras, os lados são trocados .
Se você reconciliar as duas definições:
test.txt
arquivo combar
conteúdo)test.txt
arquivo combaz
conteúdo) é "deles", e cada um desses commits Git locais estão sendo reproduzidos.Em outras palavras, SVN ou não:
<upstream>
branch " " (no topo do qual qualquer coisa é reproduzida, e que faz parte dos commits rebased até agora ") é" nosso ".Boa dica mnemônica da CommaToast :
(e a primeira coisa a
git rebase upstream
faz para verificar oupstream
branch no topo do qual você deseja realocar: HEAD refere-se aupstream
-ours
agora.)A confusão provavelmente vem do papel do ramo de trabalho em um clássico
git merge
.Quando você está mesclando:
Como a
git rebase
página do manual menciona, uma mesclagem durante um rebase significa que o lado foi trocado.Outra maneira de dizer a mesma coisa é considerar que:
Em uma fusão :
, não alteramos o branch atual 'B', então o que temos ainda é o que estávamos trabalhando (e nos unimos de outro branch)
Mas em um rebase , mudamos de lado porque a primeira coisa que um rebase faz é verificar o branch upstream! (para repetir os commits atuais em cima dele)
A
git rebase upstream
primeiro mudaráHEAD
de B para o ramal upstreamHEAD
(daí a troca de 'nosso' e 'deles' em comparação com o branch de trabalho "atual" anterior.), e então o rebase irá repetir 'seus' commits no novo 'nosso' branch B:
O único passo extra
git svn rebase
é que um svn "fetch" é executado primeiro no branch remoto Git representando os commits SVN.Você tem inicialmente:
, você primeiro atualiza o branch de rastreamento SVN com novos commits vindos do SVN
, então você muda o branch atual para o lado SVN (que se torna "nosso")
, antes de repetir os commits nos quais você estava trabalhando (mas que agora são "deles" durante o rebase)
fonte
git rebase
página de manual ...