git rebase después de la fusión de git anterior

79

Tengo la siguiente situación:

  • Creé una clone(Y) a partir de un repositorio principal (X), porque había muchas personas trabajando en Y, no hicimos nada rebasemás que merges. Cuando queremos entregar ( push) Y a X, nos gustaría hacer una rebasepara tener las cosas agradables y limpias

El problema es que al hacerlo se rebasenos pide que hagamos todas las fusiones que ya hicimos en los mergepasos anteriores . ¿Hay una solución para esto, además de la que significa volver a hacer las fusiones?

Esperaba que fuera bastante sencillo, ya que resolvimos las fusiones conflictivas.

EN S
fuente
En: "Debido a que había mucha gente trabajando en Y, no hicimos ningún rebase, solo fusionamos", te refieres a fusionar con el upstream, ¿es eso?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

81

Rebasar para obtener un historial "limpio" está sobrevalorado. La mejor manera si desea conservar el historial es simplemente hacer la fusión en lugar de una rebase. De esa forma, si alguna vez necesita volver a una revisión, es exactamente la misma que probó durante el desarrollo. Eso también resuelve su problema sobre los conflictos de fusión previamente resueltos.

Si no le importa preservar el historial, puede crear una nueva rama fuera del maestro, verificarla y luego git read-tree -u -m devactualizar su árbol de trabajo para que coincida con la devrama. Luego, puede comprometer todo en un gran compromiso y fusionarlo con el maestro como de costumbre.

Karl Bielefeldt
fuente
1
Lo que efectivamente ha hecho aquí es una fusión. La nueva rama es innecesaria.
isak gilbert
1
@isakgilbert Es lo mismo si te fusionas con --squash. Una fusión regular agregará N o N + 1 confirmaciones al maestro si hubiera N confirmaciones en la rama. La sugerencia anterior, o merge --squash, siempre agregará solo una confirmación al maestro.
peterflynn
3
@ytpete, sí exactamente. Siento que lo anterior es solo una forma indirecta de hacer una fusión: aplastar de desarrollador a maestro. "Crear una nueva rama" es simplemente apuntar al mismo lugar que el maestro. "Comprometer todo en un gran compromiso" es simplemente hacer squash.
isak gilbert
3
Las confirmaciones de fusión son ruidosas cuando se intenta ver el conjunto completo de cambios en una sola rama. Es una molestia extraer la diferencia y mirarla cuando un historial limpio lo hace simple.
Ajax
2
No podría estar más en desacuerdo con una historia "limpia" que está sobrevalorada. No está sobrevalorado, ahorra tiempo y hace que las cosas sean menos confusas.
basickarl
121

git merge --squashes ahora mi forma preferida de rebase después de una gran cantidad de trabajo y muchas fusiones ( consulte esta respuesta ). Si se llama a la rama en la que está trabajando my-branchy desea volver a establecer la base master, haga lo siguiente:

git checkout my-branch
git branch -m my-branch-old
git checkout master
git checkout -b my-branch
git merge --squash my-branch-old
git commit
Jon Lemmon
fuente
13

Dos observaciones:

  • puede reajustar su propio trabajo (aún no enviado) tantas veces como desee además de las confirmaciones recién obtenidas.
  • Podría evitar los conflictos de fusión (durante el rebase) si lo hubiera activadogit rerere , lo que se hace para este tipo de situación.
    http://git-scm.com/images/rerere2.png Ver más en git rerere.
VonC
fuente
@lulian: en ese caso, si tienes que reajustar tu trabajo, creo que tendrás que volver a hacer esas fusiones de resolución de conflictos.
VonC
@krlmlr Gracias. He restaurado el enlace, he añadido una ilustración y una referencia a la página de manual de ese comando.
VonC
8

Puede tomar todos los cambios en su rama y ponerlos en una nueva confirmación mastercon lo siguiente:

git diff master > my_branch.patch
git checkout master
patch -p1 < my_branch.patch

Luego organice sus archivos y confíe.

dbaston
fuente
1

Con respecto a la repetición de conflictos de fusión, puede usar git rerere para mantener una base de datos de cómo ya se han resuelto los conflictos de fusión, de modo que realizar una rebase que dé como resultado los mismos conflictos hará que las partes laboriosas se realicen automáticamente.

https://hackernoon.com/fix-conflicts-only-once-with-git-rerere-7d116b2cec67

git config --global rerere.enabled true

Lo único que debe tener en cuenta es que si resolvió algo incorrectamente , la próxima vez también se solucionará automáticamente y es posible que no se dé cuenta.

Documentación más formal aquí: https://git-scm.com/docs/git-rerere

Ajax
fuente