J'utilise git-svn et j'ai remarqué que lorsque je dois corriger un conflit de fusion après avoir exécuté a git svn rebase
, la signification des options --ours
et --theirs
de par exemple git checkout
est inversée. Autrement dit, s'il y a un conflit et que je veux conserver la version qui provient du serveur SVN et rejeter les modifications que j'ai apportées localement, je dois utiliser ours
, quand je m'attendais à ce que ce soit le cas theirs
.
Pourquoi donc?
Exemple:
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"
Réponses:
Cela semble cohérent avec ce que fait un rebase.
git svn rebase
récupérera les révisions du parent SVN du HEAD actuel et rebase le travail actuel (non validé vers SVN).git rebase
mentionne:Notez qu'une fusion de rebase fonctionne en rejouant chaque commit depuis la branche de travail au-dessus de la
<upstream>
branche.Pour cette raison, lorsqu'un conflit de fusion se produit:
<upstream>
,En d'autres termes, les côtés sont échangés .
Si vous conciliez les deux définitions:
test.txt
fichier avec lebar
contenu)test.txt
fichier avec lebaz
contenu) est "leur", et chacun de ces commits Git locaux est en cours de relecture.En d'autres termes, SVN ou non:
<upstream>
branche " " (sur laquelle tout est rejoué, et qui fait partie des commits rebasés jusqu'à présent ") est" la nôtre ".Bon conseil mnémotechnique de CommaToast :
(et la première chose à faire pour extraire
git rebase upstream
laupstream
branche au-dessus de laquelle vous voulez rebaser: HEAD fait référenceupstream
-ours
maintenant.)La confusion vient probablement du rôle de la branche de travail dans un classique
git merge
.Lorsque vous fusionnez:
Comme l'indique la
git rebase
page de manuel, une fusion pendant un rebase signifie que le côté est permuté.Une autre façon de dire la même chose est de considérer que:
Lors d'une fusion :
, nous ne changeons pas la branche actuelle 'B', donc ce que nous avons est toujours ce sur quoi nous travaillions (et nous fusionnons depuis une autre branche)
Mais sur un rebase , on change de côté car la première chose qu'un rebase fait est de vérifier la branche amont! (pour rejouer les commits actuels par-dessus)
A
git rebase upstream
passera d'abordHEAD
de B à la branche amontHEAD
(d'où le changement de «le nôtre» et «le leur» par rapport à la branche de travail «actuelle» précédente)., puis le rebase rejouera `` leurs '' commits sur la nouvelle branche `` notre '' B:
La seule étape supplémentaire avec
git svn rebase
est qu'un svn "fetch" est d'abord effectué sur la branche distante Git représentant les commits SVN.Vous avez au départ:
, vous mettez d'abord à jour la branche de suivi SVN avec de nouveaux commits provenant de SVN
, puis vous basculez la branche actuelle du côté SVN (qui devient "la nôtre")
, avant de rejouer les commits sur lesquels vous étiez en train de travailler (mais qui sont désormais "les leurs" pendant ce rebase)
la source
git rebase
page de manuel ...