¿Esta fusión de Git ya está completa, o cómo completarla con kdiff3?

Fondo

Soy nuevo en Git y estoy resolviendo mi primer conflicto de fusión. Estoy trabajando en C # usando Visual Studio en el tutorial Scott Lilly C # SuperAdventure . Mientras construyo el tutorial, estoy usando Github para aprender SCM y Git también. Como parte de este process, aprendí a tener un maestro limpio que sigue directamente el tutorial sin desviación, creo una twig para cada capítulo, y lo fusiono de nuevo a maestro al final, y luego mantengo cualquier experimento en twigs separadas – de esa manera mi los experimentos nunca entran en conflicto con el tutorial cuando crea nuevas características o refactoriza el código existente.

Hasta aquí todo bien. Uno de mis experimentos es agregar algunas testings unitarias. unittesting sucursal de unittesting separado y decidí realizar cambios de maestro a esta twig para mantenerla actualizada. En la primera fusión, tuve un conflicto, en el file de proyecto de Visual Studio para el proyecto al que estaba agregando testings de unidad, debido a la installation de diferentes packages. Esto no es gran cosa, pero los mecanismos me están haciendo tropezar. Hay 5 conflictos por adiciones, que pueden combinarse todos directamente, y un caso de un conflicto verdadero. He pasado la mayor parte del path, pero solo necesito ayuda.

Paso a paso hasta ahora

Estoy usando un repository público en Github , y Visual Studio 2017 Community en Windows 10 con la extensión VS Github y el repository local de Git, pero seamos sinceros, los commands del complemento de Visual Studio están bastante limitados a los elementos de flujo de trabajo muy normales. Por lo tanto, comencé a usar Git bash según lo necesario para la command-line y a Git Extensions para una GUI de Git, que funciona bastante bien.

Recientemente Chap_23 Capítulo 23 del tutorial y Chap_23 twig Chap_23 en master . Luego traté de fusionar el maestro hasta la testing de unidad, pero tuve un conflicto en el file SuperAdventureConsole / SuperAdventureConsole.csproj. Un estado de git en este punto muestra:

 $ git status On branch unittesting Your branch is ahead of 'origin/unittesting' by 1 commit. (use "git push" to publish your local commits) You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Changes to be committed: modified: SuperAdventure.sln modified: SuperAdventureConsole/App.config modified: SuperAdventureConsole/Properties/AssemblyInfo.cs Unmerged paths: (use "git add <file>..." to mark resolution) both modified: SuperAdventureConsole/SuperAdventureConsole.csproj Untracked files: (use "git add <file>..." to include in what will be committed) SuperAdventureConsole/SuperAdventureConsole.csproj.BASE SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE SuperAdventureConsole/SuperAdventureConsole.csproj.orig 

En este punto ejecuté git mergetool basado en Q: ¿cómo resolver conflictos de fusión en Git? , que ejecuta kdiff3 como una herramienta de fusión (en mi configuration, de todos modos), con el file original como A file, y LOCAL y REMOTO como B y C (no estoy seguro de cuál era cuál). Pude equivocarme con eso, y elegir entre B y C para cada conflicto (6 en total). Aquí es donde me quedé atrapado.

Al principio, el file de salida (en la parte inferior debajo de A , B y C en kdiff3) no estaba tomando, pero en el 3er bash, guardé y salí de kdiff3, y ya no hubo un conflicto de fusión:

 $ git mergetool No files need merging 

Pero, todavía tengo files sin seguimiento, por "estado de git":

 $ git status On branch unittesting Your branch is ahead of 'origin/unittesting' by 1 commit. (use "git push" to publish your local commits) All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: SuperAdventure.sln modified: SuperAdventureConsole/App.config modified: SuperAdventureConsole/Properties/AssemblyInfo.cs modified: SuperAdventureConsole/SuperAdventureConsole.csproj Untracked files: (use "git add <file>..." to include in what will be committed) SuperAdventureConsole/SuperAdventureConsole.csproj.BASE SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE SuperAdventureConsole/SuperAdventureConsole.csproj.orig 

Pregunta (s)

Parece que el file modificado es el resultado guardado de kdiff3 y, por lo tanto, ya está agregado al índice y, por lo tanto, puedo confirmarlo. ¿Es eso correcto? Supongo que en este caso solo me comprometo a completar la fusión.

En general, no estoy seguro de lo que sucedió aquí: ¿por qué el "estado de git" muestra 4 files sin .BASE con una extensión (es decir .BASE , .LOCAL , .REMOTE y .orig ), pero muestra una SuperAdventureConsole/SuperAdventureConsole.csproj sin un extensión en la list de files "modificados"?

Comprendo .LOCAL y .REMOTE , pero ¿cuál es la diferencia entre .BASE y .orig ? Uno de ellos debería ser el padre de ambas twigs, pero ¿cuál es, y cuál es el otro?

Además, ¿hay algo que pueda hacer desde Git Bash o usar extensiones de Git u otra GUI de Git para verificar si la fusión está list para comprometerse de la manera que espero?

¡¡Gracias!!

Parece que el file modificado es el resultado guardado de kdiff3 y, por lo tanto, ya está agregado al índice y, por lo tanto, puedo confirmarlo. ¿Es eso correcto? Supongo que en este caso solo me comprometo a completar la fusión.

Esto parece ser el caso. Utilice git diff --cached (o git diff --staged , si lo prefiere: ambos hacen exactamente lo mismo) para comparar lo que está en el índice en este momento, es decir, lo que iría en un nuevo commit, a lo que está en el commit actual ahora mismo. Ver también la respuesta a la segunda pregunta.

(El git status tiene este mismo git diff --cached pero con --name-status , para que solo vea los files agregados, eliminados o modificados, y no el cambio real).

En general, no estoy seguro de lo que sucedió aquí, ¿por qué el "estado de git" muestra 4 files sin .BASE con una extensión (es decir .BASE , .LOCAL , .REMOTE y .orig ) …

Esto es un poco misterioso: sugiere que todavía tengas funcionando una git mergetool .

Lo que hace git mergetool es git mergetool en el lío dejado en el índice después de una fusión fallida . Recuerde, el índice, también conocido como el área de preparación o caching -tres nombres para una cosa- normalmente es solo un lugar donde usted construye su próxima confirmación. Tiene una copy de cada file que irá a la nueva confirmación. Sin embargo, durante una fusión fallida, puede tener tres copys de cada file de fusión fallida en lugar de solo una.

(Parece probable que solo una fusión automática de un file haya fallado, es decir, SuperAdventureConsole/SuperAdventureConsole.csproj ).

Las tres copys en el índice son:

  • La versión de base de combinación del file.
  • La versión actual ( HEAD , --ours , or-aha! – local ) del file.
  • La otra --theirs (del mismo nombre, muy mala o remota ) del file.

Los files que están en el índice están en una forma especial, solo Git, entonces lo que hace git mergetool es extraer cada uno de estos a un file ordinario en su tree de trabajo. También copy el file fall-merge-result, que quedó en SuperAdventureConsole/SuperAdventureConsole.csproj , en .orig .

Luego, git mergetool ejecuta su progtwig de fusión de files elegido. Puedes manipular el file en este progtwig. Cuando termine, guarde el file y salga. La mergetool commands mergetool compara el file .orig con la versión final para ver si realmente arregló algo y / o mira el código de salida del progtwig.

Si parece que hiciste algo acerca de la fusión fallida, la git mergetool commands de git mergetool debería eliminar al less tres, y a menudo los cuatro, de estos files. El hecho de que no sugiera que git mergetool aún se está ejecutando. Puede verificar y asegurarse de que realmente no lo es. Tal vez algo lo mató y nunca tuvo la oportunidad de limpiar.

Comprendo .LOCAL y .REMOTE , pero ¿cuál es la diferencia entre .BASE y .orig ? Uno de ellos debería ser el padre de ambas twigs, pero ¿cuál es, y cuál es el otro?

El file .LOCAL es solo la versión --ours del índice ( git show :2:<path> , durante el conflicto). El file .REMOTE es la --theirs versión ( git show :3:<path> ). El file .BASE es la versión de combinación (padre común, como dijiste; git show :1:<path> ). .orig es una copy de security de lo que sea que haya dejado la fusión de files. La mergetool commands mergetool principalmente lo usa para comparar con lo que queda en el file original cuando sale el progtwig de combinación elegido.