tag - git rebase, haciendo un seguimiento de ''local'' y ''remoto''
tipos de etiquetas en git (3)
Al hacer una rebase de git, a menudo tengo dificultades para resolver lo que está sucediendo con el ''local'' y ''remoto'' cuando resuelvo conflictos. A veces tengo la impresión de que intercambian lados de un compromiso al siguiente.
Esto es probablemente (definitivamente) porque todavía no he entendido correctamente.
Al volver a basar, ¿quién es "local" y quién es "remoto"?
(Uso P4Merge para resolver conflictos)
TL; DR;
Para resumir (como comments Benubird ), cuando:
git checkout A
git rebase B # rebase A on top of B
-
local
esB
(rebase en ), -
remote
esA
Y:
git checkout A
git merge B # merge B into A
-
local
esA
(se funde en ), -
remote
esB
Una rebase cambia la ours
(rama actual antes de que comience la base de datos) y la theirs
(la rama sobre la cual desea volver a establecer la base).
kutschkem señala que, en un contexto de combinación de herramientas GUI :
- referencias locales las confirmaciones parcialmente reestadificadas : "
ours
" (la rama ascendente) - remote se refiere a los cambios entrantes : "
theirs
" - la rama actual antes de la rebase.
Ver ilustraciones en la última parte de esta respuesta.
Inversión cuando se rebase
La confusión podría estar relacionada con la inversión de la ours
y la theirs
durante una rebase .
(extractos relevantes)
Tenga en cuenta que una fusión de rebase funciona al repetir cada confirmación desde la rama de trabajo en la parte superior de la rama
<upstream>
.
Debido a esto, cuando ocurre un conflicto de fusión:
- el lado reportado como ''
ours
'' es la serie hasta ahora rebasada, comenzando con<upstream>
, - y ''
theirs
'' es la rama de trabajo. En otras palabras, los lados se intercambian.
Inversión ilustrada
En una fusión
x--x--x--x--x(*) <- current branch B (''*''=HEAD)
/
/
/--y--y--y <- other branch to merge
, no cambiamos la rama actual ''B'', entonces lo que tenemos es aún en lo que estábamos trabajando (y nos fusionamos de otra rama)
x--x--x--x--x---------o(*) MERGE, still on branch B
/ ^ /
/ ours /
/ /
--y--y--y--/
^
their
En una rebase:
¡Pero en una rebase , cambiamos de lado porque lo primero que hace una rebase es verificar la rama ascendente! (para reproducir los commits actuales en la parte superior)
x--x--x--x--x(*) <- current branch B
/
/
/--y--y--y <- upstream branch
Un git rebase upstream
cambiará primero HEAD
of B a HEAD
de la rama upstream (de ahí el cambio de ''ours'' y ''theirs'' en comparación con la rama de trabajo "actual" anterior).
x--x--x--x--x <- former "current" branch, new "theirs"
/
/
/--y--y--y(*) <- upstream branch with B reset on it,
new "ours", to replay x''s on it
, y luego la rebase reproducirá ''sus'' confirmaciones en la nueva ''nuestra'' rama B:
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
/
/
/--y--y--y--x''--x''--x''(*) <- branch B with HEAD updated ("ours")
^
|
upstream branch
Nota: la noción "ascendente" es el conjunto referencial de datos (un repositorio o, como aquí, una sucursal, que puede ser una sucursal local ) desde el que se leen los datos o a los que se agregan / crean nuevos datos.
'' local
'' y '' remote
'' contra '' mine
'' y '' theirs
''
Pandawood agrega en los comentarios :
Para mí, la pregunta sigue siendo, que es "local" y que es "remota" (ya que los términos "nuestro" y "suyo" no se usan cuando se vuelve a basar en git, referirse a ellos simplemente parece hacer una respuesta más confusa) .
GUI git mergetool
kutschkem agrega, y con razón:
Al resolver conflictos, git dirá algo como:
local: modified file and remote: modified file.
Estoy bastante seguro de que la pregunta apunta a la definición de local y remota en este punto. En ese punto, me parece desde mi experiencia que:
- referencias locales las confirmaciones parcialmente reestadificadas : "
ours
" (la rama ascendente) - remote se refiere a los cambios entrantes : "
theirs
" - la rama actual antes de la rebase.
git mergetool
menciona ''local'' y ''remoto'' :
Merging:
f.txt
Normal merge conflict for ''f.txt'':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (kdiff3):
Por ejemplo, KDiff3 mostraría la resolución de fusión así :
Y meld lo mostraría también :
Lo mismo para VimDiff , que muestra :
Invoca a Vimdiff como una herramienta de combinación con git mergetool -t gvimdiff. Las versiones recientes de Git invocan a Vimdiff con el siguiente diseño de ventana:
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
LOCAL
:
Un archivo temporal que contiene el contenido del archivo en la rama actual.BASE
:
Un archivo temporal que contiene la base común para la fusión.REMOTE
:
Un archivo temporal que contiene el contenido del archivo que se fusionará.MERGED
:
El archivo que contiene los marcadores de conflicto.Git ha realizado la mayor cantidad posible de resolución automática de conflictos y el estado de este archivo es una combinación de
LOCAL
yREMOTE
con marcadores de conflicto que rodean cualquier cosa que Git no haya podido resolver por sí mismo.
Elmergetool
debe escribir el resultado de la resolución en este archivo.
No entendí exactamente tu problema, pero creo que el siguiente diagrama resuelve tu problema. (Rebase: Repositorio remoto ---> Espacio de trabajo)
Fuente: flujo de trabajo de My Git
La línea de fondo
git rebase
- LOCAL = la base sobre la que está volviendo a basar
- REMOTO = los commits te estás moviendo hacia arriba
git merge
- LOCAL = la rama original en la que se está fusionando
- REMOTO = la otra rama cuyas confirmaciones te estás fusionando
En otras palabras, LOCAL siempre es el original, y REMOTO es siempre el tipo cuyas confirmaciones no estaban allí antes, porque están siendo fusionadas o reordenadas en la parte superior.
¡Pruébalo!
Ciertamente. No tomes mi palabra! Aquí hay un experimento fácil que puedes hacer para verte por ti mismo.
Primero, asegúrate de que tienes git mergetool configurado correctamente. (Si no lo hiciste, probablemente no estarías leyendo esta pregunta de todos modos). Luego encuentra un directorio para trabajar.
Configura tu repositorio:
md LocalRemoteTest
cd LocalRemoteTest
Crear una confirmación inicial (con un archivo vacío):
git init
notepad file.txt (use the text editor of your choice)
(save the file as an empty file)
git add -A
git commit -m "Initial commit."
Crea una confirmación en una rama que no es maestra:
git checkout -b notmaster
notepad file.txt
(add the text: notmaster)
(save and exit)
git commit -a -m "Add notmaster text."
Crear una confirmación en la rama maestra:
git checkout master
notepad file.txt
(add the text: master)
(save and exit)
git commit -a -m "Add master text."
gitk --all
En este punto, su repositorio debería verse así:
Ahora para la prueba de rebase:
git checkout notmaster
git rebase master
(you''ll get a conflict message)
git mergetool
LOCAL: master
REMOTE: notmaster
Ahora la prueba de fusión. Cierre su herramienta de combinación sin guardar ningún cambio y luego cancele la rebase:
git rebase --abort
Entonces:
git checkout master
git merge notmaster
git mergetool
LOCAL: master
REMOTE: notmaster
git reset --hard (cancels the merge)
Tus resultados deberían ser los mismos que los que se muestran arriba.