Estoy tratando de tener dos ramas con archivos binarios en git - un "desarrollo" y un "estable". La rama de desarrollo puede tener varios cambios de estos archivos antes de que quiera "liberarlos" a la rama estable (y la rama estable tiene esos archivos renombrados, en caso de que sea relevante).Git fusionar squash repetidamente
Podría hacer una fusión normal, esto funciona bien, pero conserva demasiada historia: cuando se tira de la rama "estable", se extraen todas las confirmaciones intermedias de la rama "desarrollo" (porque son confirmaciones principales) . Pero estamos hablando de archivos binarios que no tienen ninguna estrategia de fusión razonable (excepto la suya/la nuestra), por lo que el historial real de los archivos en la rama de desarrollo es inútil. Cuando me tire de la rama "estable", me sale esto:
X-------------------G stable / / a---b---c---d---e---f---g development
Debido a que G tiene un padre en la rama de desarrollo, consigo toda la historia de la rama de desarrollo (objetos de datos para c, d, e, f y g) en mi repositorio, que no me interesa (X es lo mismo que b, con algunos cambios de nombre de archivo aplicados).
Así que traté de git merge --squash
cambios de la rama de desarrollo a la rama estable. La primera de esas fusión y comprometerse ido bien, los resultados fueron los esperados (buen registro de cambios en el mensaje de confirmación, sin relación con la rama de desarrollo):
X-------------------G stable / a---b---c---d---e---f---g development
Después de apretar el rama estable aplastada, me sale esto en mi repositorio, que es lo que quiero:
a---b---X---G
Pero la segunda fusión fallida (porque Git no tenía manera de saber lo mucho que ya se fusionaron y se confundió).
- ¿Es posible grabar la fusión de alguna manera, sin producir un "commit de fusión" con dos padres?
- O, ¿es posible decirle a git que combine solo cierto "rango" de revisiones, como en SVN?
- O, ¿es posible hacer una fusión normal sin tener que descargar todas las referencias desde la otra rama cuando se tira?
- ¿O debería proporcionar un controlador de combinación personalizado para los archivos en cuestión, que simplemente cambia el nombre de "su" versión a "nuestra", resolviendo así los conflictos? Todavía tengo miedo de que
--squash
siempre intente fusionar toda la historia, hasta el padre común, resolviendo solo la mitad de mi problema.
Actualización: rebase
Si entiendo correctamente rebase, voy a terminar con esto:
X stable / a---b---c---d---e---f---g development
Lo cual me lleva todos los datos que no estoy interesado en (c , d, e, f) y como extra, perderé la información de que b era una versión estable en la sucursal.
Cada revisión de desarrollo agrega unos 5MB al tamaño del repositorio (y reempaquetar todo el repositorio lo reduce solo un 10%), la rama "estable" es casi gratuita (los datos ya están allí). Quiero sacar una nueva revisión de la rama estable para extraer solo los 5MB nuevos, pero en cambio actualizar de X a G descarga 25MB, porque de alguna manera no puedo decir que no me importan los contenidos de c, d , e y f.
Esto se ve genial, pero no entiendo exactamente por qué es necesario crear una rama temporal y luego cambiarle el nombre. ¿Es porque todavía estás desapegado después del compromiso? –
@ kim-sullivan: el "por qué exactamente": cuando haces la confirmación en el ejemplo anterior, mueve 'HEAD' pero no' stable' para apuntar a la nueva confirmación: la cabeza aún está "separada", y ' stable' sigue apuntando a la versión anterior (X, en su ejemplo original). Hacer la bifurcación y cambiar el nombre (la salida es técnicamente opcional, aunque sin ella tendrás que suministrar argumentos a 'git branch -M', y aún estarás desapegado, lo que probablemente no sea deseable) hace que las causas sean estables a punto a J (por la respuesta). – lindes
También: Puede ejecutar 'git log --graph --oneline --all --decorate' y' git status' en cada punto de esta serie de comandos para ser informativo. Y/o mirando los contenidos de varios archivos en .git /, quizás con 'grep. .git/HEAD .git/refs/heads/* ' – lindes