¿Error de fusión inesperado en un sistema git svn?

Tengo una configuration algo intrincada (como en git svn dcommit committing wrong file? ) Que se ve algo como esto (producido en Dia, testrepo.dia , publicado en este artículo ) – y se simula con el siguiente script, testrepo.sh :

/tmp/testrepo.png

Básicamente, he tenido un repository SVN en un server web ( myrepo_svn_WS ), que al principio trabajé a través de una copy de trabajo SVN en mi PC local ( myrepo_svnco ). Después de un time, dejé de hacerlo y me mudé a git-svn ; pero en lugar de usarlo directamente desde mi PC local, configuré un myrepo_gitsvn en mi server local; a partir de ella se realiza un repository de git myrepo_git_LS.git en el server local, myrepo_git_LS.git , que se agrega como origen remoto de myrepo_gitsvn . La idea es que puedo trabajar desde PC locales con respecto a myrepo_git_LS.git y mantener la networking local sincronizada, incluso si el server web svn se desconecta temporalmente.

El script siguiente, testrepo.sh , simula este process localmente, incluido el myrepo_svn_WS desconectado. Si usa la secuencia de commands como está, notará que el sistema puede "recuperar" desde el server "WS" de SVN sin connection, y el logging en ese caso es testrepo_nofail.log . Sin embargo, si descomenta las #~ líneas comentadas, que hacen una git fetch origingit , notará que el process falla, para lo cual el logging es testrepo_fail.log :

 remote: Using index info to reconstruct a base tree... remote: Falling back to patching base and 3-way merge... remote: Auto-merging folder/file.txt remote: CONFLICT (content): Merge conflict in folder/file.txt remote: Failed to merge in the changes. remote: Patch failed at 0001 5th git commit remote: remote: When you have resolved this problem run "git rebase --continue". remote: If you would prefer to skip this patch, instead run "git rebase --skip". remote: To check out the original branch and stop rebasing run "git rebase --abort". 

Lo que me confunde aquí (y por qué lo encuentro inesperado) – es que soy el único usuario aquí, ¡y por lo tanto ni siquiera uso twigs! En ese caso, ¿cómo podría get un "conflicto de fusión"?

El asunto es que ahora el sistema ha terminado en este estado fallido; entonces mi pregunta es: ¿cómo puedo recuperar el sistema al estado de trabajo correcto, de modo que cuando realizo un commit y push desde myrepo_git_wc local, el server web SVN myrepo_svn_WS se actualice correctamente?

Algunas notas de comparar los loggings con meld :

Tenga en count que justo después de la parte "Simular conflicto de fusión vía fetch fetch", el process parece continuar correctamente, excepto que ahora hay una twig origingit/master (haga clic para tamaño completo):

testrepo_meld_01.png

No pensé mucho en esto, porque no pensé en git-svn como una twig; pero aquí hay una pregunta: de git-svn y origingit/master , ¿cuál es una twig?

Esa parte termina aquí:

/testrepo_meld_02.png

Observe que al final, el process no fallado muestra el tree del gráfico de logging como "compactado" o "aplanado" (es decir, no hay twigs sobresaliendo), mientras que el process fallido en ese punto no se queja de errores, pero muestra el tree de gráfico de logging como ramificado.

El problema ocurre solo después del '6to. Commit de git':

testrepo_meld_03.png

El process fallido en realidad se inicia, por alguna razón, "Aplicar el 5º compromiso de git", que en ese momento ya debería haber sido manejado; y en ese punto, se produce el conflicto de fusión.

Entonces, si mi sistema (o más bien, myrepo_gitsvn ) está en este estado fallido, ¿qué puedo hacer para recuperarlo?

Aquí está el código testrepo.sh :

 set -x rm -rf /tmp/myrepo* cd /tmp echo "simulating svn web server repo" svnadmin create myrepo_svn_WS # svn co file:///tmp/myrepo_svn_WS myrepo_svnco read -s -p "Enter ssh pass [note, you will be prompted again via GUI for the same]: " SSHPASS export SSHPASS # note: the next command will again prompt for sshpass in GUI once, regardless of the SSHPASS variable sshpass -e svn co svn+ssh://localhost/tmp/myrepo_svn_WS myrepo_svnco cd /tmp/myrepo_svnco echo "Adding first commits via svn" echo aaa > AA.txt svn add AA.txt sshpass -e svn ci -m 'first svn commit' echo bbb > BB.txt svn add BB.txt sshpass -e svn ci -m '2nd svn commit' echo ccc > CC.txt svn add CC.txt sshpass -e svn ci -m '3rd svn commit' echo ddd > DD.txt svn add DD.txt sshpass -e svn ci -m '4th svn commit' echo eee > EE.txt svn add EE.txt sshpass -e svn ci -m '5th svn commit' cd /tmp echo "Cloning svn as git" sshpass -e git svn clone svn+ssh://localhost/tmp/myrepo_svn_WS myrepo_gitsvn echo "Cloning a bare git local server" git clone --bare myrepo_gitsvn myrepo_git_LS.git echo "Adding a git local server remote to the gitsvn" cd /tmp/myrepo_gitsvn git remote add origingit file:///tmp/myrepo_git_LS.git cd /tmp cat > /tmp/myrepo_git_LS.git/hooks/post-update <<EOF #!/usr/bin/env bash export SSHPASS=${SSHPASS} #export GIT_DIR="." git update-server-info export GIT_DIR=".git" echo "post-update kicking in" cd /tmp/myrepo_gitsvn git pull --rebase origingit master git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order sshpass -e git svn rebase sshpass -e git svn dcommit sshpass -e git svn rebase git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order EOF chmod +x /tmp/myrepo_git_LS.git/hooks/post-update cd /tmp echo "Cloning a git local server to git local working copy" sshpass -e git clone ssh://localhost/tmp/myrepo_git_LS.git myrepo_git_wc cd /tmp/myrepo_git_wc echo "Working from git local working copy now" git config user.name me git config user.email me@myself.com mkdir folder echo hhh > folder/file.txt git add folder/file.txt git commit -m "1st git commit" sshpass -e git push origin master echo iiii >> folder/file.txt git add folder/file.txt git commit -m "2nd git commit" sshpass -e git push origin master echo "Simulating svn server offline; git wc commits get added" mv /tmp/myrepo_svn_WS /tmp/.myrepo_svn_WS echo jjj >> folder/file.txt echo jjj > folder/file2.txt git add folder/file*.txt git commit -m "3rd git commit" sshpass -e git push origin master echo kkkk >> folder/file.txt echo kkkk >> folder/file2.txt git add folder/file*.txt git commit -m "4th git commit" sshpass -e git push origin master echo "Simulating svn server back online; git wc commits get added" mv /tmp/.myrepo_svn_WS /tmp/myrepo_svn_WS #~ echo "Simulating merge conflict via git fetch" #~ (cd /tmp/myrepo_gitsvn; git fetch origingit) echo lll >> folder/file.txt git add folder/file.txt git commit -m "5th git commit" sshpass -e git push origin master echo mmm >> folder/file.txt git add folder/file.txt git commit -m "6th git commit" sshpass -e git push origin master 

Por lo tanto, creo que llegué a algún lado, pero realmente no estoy seguro de si esto funcionará para todos los casos extremos, por lo que una respuesta eventual más erudita será apreciada.

Primero, una nota: puedes get los loggings con bash testrepo.sh 2>&1 | tee testrepo_MARK.log bash testrepo.sh 2>&1 | tee testrepo_MARK.log ; y puede eliminar los caracteres de control insertados por git remoto de los loggings con: sed -i 's/\x1b\[\x4b//g' testrepo*.log .

De todos modos, al parecer, cuando se hace git fetch , se agrega una twig llamada de seguimiento remoto local, que se puede eliminar de acuerdo con ¿Cómo elimino una twig de Git tanto local como remotamente? (para no agregar esa "twig local de seguimiento remoto", uno debería aparentemente llamar a git fetch <remote> --prune en git fetch <remote> --prune lugar). Pero eso no es suficiente si se recupera de un estado roto; el estado roto aparentemente significa que hay un logging de una fusión fallida, que debe eliminarse (para lo cual se puede usar git rebase --abort , como recomienda el propio progtwig). En resumen, la solución sería:

 cd /tmp/myrepo_gitsvn git branch --delete --remotes origingit/master git rebase --abort 

Aquí hay una modificación del script anterior, que permitirá simular el corte y la recuperación (simplemente reemplace las partes respectivas en el script OP):

 # ... cd /tmp cat > /tmp/myrepo_git_LS.git/hooks/post-update <<EOF #!/usr/bin/env bash export SSHPASS=${SSHPASS} #export GIT_DIR="." git update-server-info export GIT_DIR=".git" echo "post-update kicking in" cd /tmp/myrepo_gitsvn git svn info | grep Rev git pull --rebase origingit master git svn info | grep Rev git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order sshpass -e git svn rebase sshpass -e git svn dcommit sshpass -e git svn rebase git log --graph --decorate --pretty=oneline --abbrev-commit --all --date-order git svn info | grep Rev EOF chmod +x /tmp/myrepo_git_LS.git/hooks/post-update # ... echo "Simulating svn server back online; git wc commits get added" mv /tmp/.myrepo_svn_WS /tmp/myrepo_svn_WS DOCONFLICT=true if [ "${DOCONFLICT}" = "true" ] ; then echo "Simulating merge conflict via git fetch" (cd /tmp/myrepo_gitsvn; git fetch origingit) fi echo lll >> folder/file.txt git add folder/file.txt git commit -m "5th git commit" sshpass -e git push origin master echo mmm >> folder/file.txt git add folder/file.txt git commit -m "6th git commit" sshpass -e git push origin master DOFIX=true if [ "${DOCONFLICT}" = "true" ] ; then if [ "${DOFIX}" = "true" ] ; then # http://sofes.miximages.com/questions/2003505/delete-a-git-branch-both-locally-and-remotely/23961231#23961231 (cd /tmp/myrepo_gitsvn; git branch --delete --remotes origingit/master; git rebase --abort; ) fi fi echo nnn >> folder/file.txt git add folder/file.txt git commit -m "7th git commit" sshpass -e git push origin master echo ooo >> folder/file.txt git add folder/file.txt git commit -m "8th git commit" sshpass -e git push origin master 

Hay algunos commits más, para probar si la recuperación se mantiene; aparentemente lo hace, porque para la última confirmación, ahora esto se puede ver en la comparación de loggings:

/tmp/testrepo_meld_04.png

… por lo tanto, aparte de una ligera reorganización, el gráfico de logging se ve casi igual. Además, tenga en count que, como dice la git svn info añadida, cada vez que hay un "cabezal de rebobinado para reproducir su trabajo encima de él", git-svn realmente trae el repository a cometer 5 (que es el último que se hizo) únicamente en Subversion, antes de migrar a git-svn); No estoy seguro porque es así. Y al final, cuando se muestra el gráfico de log compactado después de la confirmación final, todo parece quedar bien:

testrepo_meld_05.png

Bueno, espero que esto me ayude a arreglar mi repository real …