Tengo un repository remoto en GitHub y un repository y espacio de trabajo local correspondiente.
El problema es así
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!
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á.