Git rebase en lugar de fusionar, ¿la forma correcta de hacerlo?

Me gustaría evitar las intersecciones recurrentes de las sucursales en mi repository remoto utilizando una rebase lugar de una merge .

Para darte una mejor comprensión de lo que me gustaría lograr, considera la siguiente situación:

 $ git lg * 2345678 hotfix (HEAD -> master) * 1234567 foo (origin/master, origin/HEAD) $ git push ! [rejected] master -> master (fetch first) $ git fetch $ git lg * 2345678 hotfix (HEAD -> master) | * 3456789 other change (origin/master, origin/HEAD) |/ * 1234567 foo 

Por lo general, la forma estándar de resolver este problema es una merge seguida de un push .

 $ git merge origin/master $ git lg * 4567890 Merge remote-tracking branch 'origin/master' |\ * | 2345678 hotfix (HEAD -> master) | * 3456789 other change (origin/master, origin/HEAD) |/ * 1234567 foo $ git push 

No me gusta esta solución porque podría evitar fácilmente la bifurcación en este caso particular. Entonces, revierte el cambio con git reset --hard head~1 y testing con otra solución:

 $ git rebase origin/master First, rewinding head to replay your work on top of it... Applying: hotfix $ git lg * 2345678 hotfix (master) | * 5678901 hotfix (HEAD) | * 3456789 other change (origin/master, origin/HEAD) |/ * 1234567 foo 

Ahora viene la parte desagradable donde tengo que mover a mi master nuevo a su HEAD :

 $ git branch -D master $ git checkout -b master $ git push $ git branch --set-upstram-to=origin/master master Branch master set up to track remote branch master from origin. $ git lg * 5678901 hotfix (HEAD -> master, origin/master, origin/HEAD) * 3456789 other change * 1234567 foo 

Mi pregunta es ¿cómo puedo simplificar mi rebase y evitar la parte desagradable?

Creo que la manera más fácil es cambiar tu flujo de trabajo de extracción. Hay un par de opciones aquí.

Primero, puedes usar la bandera --rebase para tirar

 git pull --rebase 

Según los documentos, git pull ejecuta una fetch seguida de una merge en su configuration pnetworkingeterminada. Usar la bandera --rebase remplazará la merge con una rebase 🙂

En segundo lugar, puede configurar un valor pnetworkingeterminado para siempre hacer esto con git pull

 git config --global pull.rebase true 

Recomendaría el primer enfoque, ya que establecer un valor pnetworkingeterminado de rebase me pone nervioso. git pull --rebase un alias git pr para git pull --rebase para hacerlo más fácil. De esa manera puedo tomar la decisión con cada extracción.

El problema es que trabajas directamente en la twig principal localmente. Cuando realice algunos cambios locales en la twig maestra y también haya cambios ascendentes desde después de que comenzó, obtendrá conflictos como los que describe en la pregunta. Entonces, la solución para evitar esto es simplemente no trabajar directamente en la twig principal, sino en una o más sucursales locales.

Así que pones los cambios de tu revisión en una twig separada, digamos hotfix_branch y luego hotfix_branch / hotfix_branch la twig principal normalmente (¡sin conflictos!). Cuando desee entregar los cambios de su revisión, restaure la bifurcación de botfix para permanecer en la parte superior de una nueva twig principal extraída, combine la twig de revisión con la maestra y presione.

Comandos de ejemplo:

 $ git pull master $ git checkout -b hotfix_branch master $ $EDITOR some.file # Time passes and changes are made on origin/master $ git add some.file $ git commit -m "hotfix" $ git pull master # No conflicts sine master is "clean" $ git rebase master hotfix_branch # This step might have merge conflicts but # if so those will come no matter what you # do with regards to branching $ git checkout master $ git merge hotfix_branch $ git push 

Hay una pequeña window donde pueden aparecer nuevos cambios en el origen / maestro entre ti y tirar e intentar empujar al maestro, pero si es así, solo tienes que hacer

 $ git checkout master # if not already on the master branch $ git reset origin/master 

y luego comenzar de nuevo en el segundo command pull master en la list anterior.