Pregunta de filosofía de Git: ¿son la "ascendencia" y la "historia" (también conocida como cronología) cosas distintas? ...

He aquí, tengo el siguiente repositorio de git:

      A---B---C develop
     /
D---E---F---G master

Y quiero que la cabeza del maestro contenga exactamente lo que el desarrollo tiene en su cabeza:

      A---B---C develop
     /         \ 
D---E---F---G---C master

Excepto , no quiero una fusión. Quiero que sea algo como esto :

      A---B---C   develop
     /         \ 
D---E---F---G===C--- master

Donde el jefe de maestro NO tendría múltiples antepasados, simplemente se convertiría en lo que es el jefe de Desarrollo. El === en mi diagrama implica conexión cronológica, pero no ascendencia.

Para aclarar, no quiero usar git merge -X theirs o git merge -r ours porque todavía son fusiones verdaderas ... Simplemente no quiero una fusión: quiero una "pegar". Sin embargo, también necesito poder mirar el git log on master y ver commit C, luego commit G, luego commit F, etc., a pesar de que no hay vínculos paternos entre C y G. Además, mis restricciones me lo prohíben de borrar al maestro o desarrollar, o meterse con sus historias. ¿Hay una manera simple de hacer esto?

0
JCollier 3 mar. 2018 a las 00:55

2 respuestas

La mejor respuesta

puede lograr algo como esto, pero no es así como funciona Git, y no debe hacerlo.

Puede usar git reset para mover master y arrastrarlo al estado actual de develop. Debe mover la rama master de su confirmación actual, G, a la confirmación deseada C, y luego restablecer el software master nuevamente a su confirmación original, {{X7 }}, arrastrando el estado actual de C con él. Luego puede confirmar esos cambios, creando una nueva confirmación (NO C) con los cambios tal como existen en develop.

git checkout master
git reset --hard develop
git reset <commit id of C> # or git reset HEAD@{1}
# the working directory now contains the difference between C and G
git commit -m 'a message for C'

En este punto, master y develop contendrán contenido idéntico, pero con diferentes historiales de confirmaciones. El gráfico de compromiso se verá así:

      A---B---C   develop
     /          
D---E---F---G---C' master

Donde C' y C contienen contenido idéntico, pero historias divergentes.

En su lugar, puede fusionarse primero, y luego realizar los pasos exactamente como se indicó anteriormente, y crear una nueva confirmación que contenga tanto master como develop como antepasados pero con el contenido de C:

Git checkout master git merge desarrollar git reset --hard desarrollar git reset HEAD @ {1} git commit -m 'un mensaje de confirmación para C'.

Esto le dará algo como lo siguiente, donde M es una confirmación de fusión:

      A---B---C       develop
     /         \ 
D---E---F---G---M---C' master

Pero, de nuevo, no es así como debe funcionar Git, y hay muy pocas razones para hacerlo si tiene la intención de descartar todos los cambios de una rama u otra.

3
meagar 2 mar. 2018 a las 23:28

No quiero una fusión: quiero una "pegar". Sin embargo, también necesito poder mirar el git log on master y ver commit C, luego commit G, luego commit F, etc., a pesar de que no hay vínculos paternos entre C y G.

Esto es contradictorio. Has cortado los enlaces de ascendencia. Has abandonado por completo la historia.

Git checkout -B master develop

Es cómo abandonas un historial master existente, haciendo que master ahora se refiera al historial actual de develop.

Si desea ver el antiguo historial abandonado en el nuevo historial de master, puede

git merge -s ours master@{1}

Para grabar la ascendencia sin tomar nada del contenido, pero ya has grabado la ascendencia o no. No puede cortar sus enlaces de ascendencia y tenerlos también.

0
jthill 2 mar. 2018 a las 22:24