Después de la confirmación de git, el file eliminado reapareció en el repository remoto

Tengo un repository remoto en GitHub y un repository y espacio de trabajo local correspondiente.

El problema es así

  1. Extraigo desde el control remoto y comienzo a trabajar en los files
  2. Al mismo time, mi colega borra un file (Bar.java) y modifica un file Foo.java en la línea 10 y envía sus cambios al repository remoto.
  3. También hago cambios en la misma línea de Foo.java
  4. Cometí mi Foo.java y hago un Pull para ver si hay algún conflicto
  5. Recibí y resolví el conflicto
  6. Cuando traté de agregar los cambios al índice, obtuve dos files en etapas, uno es Foo.java que se espera y otro es Bar.java que está marcado como eliminar.
    1. Si elimino el file eliminado Bar.java de la puesta en escena y solo comprometo Foo.java (solo mis cambios) y realizo un push upstream, ¡entonces el file eliminado aparecerá nuevamente en Remote Repo!

    2. Si agrego dos files en el índice, lo comprometo y hago un push upstream solo entonces, el file borrado queda eliminado en el repository remoto Supongo que esto sucede cuando hago un Pull y hay un conflicto y como resultado mi Repo local no se actualizó pero mi espacio de trabajo se actualizó. ¿Es correcto?

Basado en eso, tengo las siguientes preguntas:

  • ¿Cómo puedo hacer que mi repository local esté sincronizado con Remote Repo cuando hay un conflicto cuando hago un pull?

  • ¿Qué sucede cuando envío mi repository local a la stream ascendente? ¿Se sobrescribirá todo el repository remoto o combinará de forma selectiva mis cambios comprometidos?

Para comprender completamente lo que está sucediendo (o lo que significa estar sincronizado con el control remoto), debemos recordar tres types de área de almacenamiento en git: tree de trabajo, índice, database. Usted tiene estos tres localmente, y también se preocupa por la database en el control remoto.

Así que pasemos por un pull que tiene conflictos. Pero para que la image sea más clara, supongamos que hacemos una fetch (lo cual está bien, porque ese es el primer paso que realiza Git cuando pides un pull ).

Entonces, para empezar, tiene un repository local con commits como

 I --- A <--(master)(origin/master) 

Realizas algunos cambios localmente y los comprometes.

 I --- A <--(origin/master) \ B <--(master) 

Pero mientras tanto, su compañero de trabajo presionó cambios en el control remoto, por lo que tiene

 I --- A --- C <--(master) 

Cuando fetch , obtienes

 I --- A --- C <--(origin/master) \ B <--(master) 

En este punto, su database tiene todos los objects del control remoto, por lo que podría decir que está completamente sincronizado con el control remoto. Sin embargo, el control remoto está un poco retrasado con respecto a lo que tienes; todavía no sabe acerca de B

El siguiente paso de la pull es fusionar origin/master en master . Si hay conflictos, la fusión se detiene con el tree de trabajo y el índice en un estado de "fusión". El índice contiene cambios en los files que no tuvieron ningún conflicto, y su tree de trabajo contiene marcadores de conflicto (junto con cualquier cambio no conflictivo) para los files que tuvieron conflictos.

Estos cambios se expresan en relación con su maestro local (es decir, en relación con B ) ya que eso es en lo que se está fusionando. Entonces, "eliminar Bar.java" es un cambio que se fusiona en su sucursal local sin conflicto, pero aún puede anularlo. Aunque git solo requiere que enfrentes los conflictos en este momento, puedes realizar los cambios que quieras en la confirmación. Permitir eso es bueno y necesario, porque a veces resolver el conflicto requiere cambios fuera de la región de las líneas conflictivas reales; pero en este caso probablemente no quieras hacerlo. Así que, aparte de add files mientras los modifica para resolver conflictos, probablemente deba dejar el índice solo.

Finalmente, resolvió conflictos y se compromete, por lo que tiene

 I --- A --- C <--(origin/master) \ \ B --- M<--(master) 

Noe, que has creado otro commit nuevo (una combinación) en tu master , y el control remoto está, por lo tanto, atrás hasta que push . Puede evitar este compromiso tirando de la opción --rebase ; el process sería similar, pero terminarías con

 I --- A --- C <--(origin/master) \ B' <--(master) 

(donde B' es el reemploop rebasado para B ). Aún así, el origin/master está atrás hasta que presionas.

Con ese conocimiento básico, respondamos específicamente a sus preguntas:

¿Cómo puedo hacer que mi repository local esté sincronizado con Remote Repo cuando hay un conflicto cuando hago un pull?

El primer paso de la pull es una fetch que te pone completamente sincronizado en el sentido de que tienes toda la información del control remoto. Todavía tiene información que todavía no está en el control remoto (sus confirmaciones locales), y hasta que haya resuelto los conflictos, no hay mucho que deba hacer al respecto.

Cualquier percepción de que no está completamente sincronizado es porque su tree de trabajo e índice reflejan la fusión en progreso que pull inicia después de la fetch . (Si hubiera hecho una fetch , podría realizar el checkout inmediato a checkout origin/master y vería todo tal como está en el control remoto).

¿Qué sucede cuando envío mi repository local a la stream ascendente? ¿Se sobrescribirá todo el repository remoto o combinará de forma selectiva mis cambios comprometidos?

Una push envía refs actualizados (y otros objects según sea necesario para soportarlos) al control remoto. Entonces, en este caso, estás presionando la reference para la twig master :

1) git actualiza la reference de origin/master en su repository local

2) git se asegura de que el origin/master todavía es "alcanzable" desde el master (a través de pointers de confirmación padres); esto significa, de forma intuitiva, que todos los cambios en el origin/master se han incorporado en el master , por lo que la actualización de los controles remotos master según lo solicitado solo aplicará los nuevos cambios que haya agregado localmente al master

3) si (2) se ve bien, entonces:

3a) los objects requeridos se envían al control remoto y se agregan a su database. En este caso, eso comprometería B y M (o confirmará B' si hiciste una rebase ) y los objects contenidos en él.

3b) la reference master del control remoto se actualiza para coincidir con su reference master local

Mientras se sobrescribe la reference master , no es correcto decir que el repository se sobrescribe. En su mayoría, le ha agregado datos. Si esto puede parecer un poco confuso, los datos que ha agregado pueden include instrucciones para deshacer un cambio que otra persona haya realizado anteriormente . El manejo adecuado del paso de fusión durante la extracción es lo que determina si eso sucede.

Si decide mantener el file en la revisión (descartando la eliminación), seguramente aparecerá en la revisión resultante. Si decide hacer lo mismo y mantener la eliminación en el índice, el file desaparecerá.