git: fusionar twigs pero mantener el historial de confirmaciones

En mi flujo de trabajo de git tenemos un repository principal y una twig, maestro. Todos extraen del maestro remoto y todos los empujan al maestro remoto. Quiero trabajar en mi propia sucursal mientras preparo una característica. Hasta ahora mi historia es algo como esto:

git pull --rebase git checkout -b new_feature <make some commits> git checkout master git pull --rebase 

Ahora quiero fusionar la sucursal y esto es lo que necesito:

  1. No se cometen fusiones en mi twig principal local.
  2. Todas las confirmaciones realizadas en mi twig new_feature se fusionaron en master como si las hubiera hecho en master.
  3. Todos los commits fusionados se fusionarán en algún lugar sobre mi puntero principal remoto local.

Mi mayor preocupación es el elemento 3, cuando es necesario para poder impulsar los cambios de forma segura. Si los commit fusionados se entrelazan con commits before head entonces tendré problemas al presionar, ver el problema relacionado que tuve: git: presionar Comisiones simples, Reorderar con rebase, Duplicate Commits .

He leído lo siguiente:

  • http://mettadore.com/2011/05/06/a-simple-git-rebase-workflow-explained/
  • Mantener commits history después de una 'combinación git'
  • ¿Cómo relaciona los cambios de la sucursal actual con los cambios que se fusionaron?

Y creo que necesito hacer:

 git checkout master git pull --rebase git checkout new_feature git rebase master git checkout master git rebase new_feature git push 

Mi entendimiento es que

 git checkout new_feature git rebase master 

hará que new_feature aparezca como si estuviera bifurcada desde la nueva cabecera actual. ¿Es eso cierto? Y eso

 git checkout master git rebase new_feature 

colocará new_feature encima de master. ¿Es eso correcto? Si es así, este es el punto principal de mi confusión. Si "git rebase master" coloca los commits de master en la parte inferior de new_feature, ¿por qué "git rebase new_feature" coloca a new_feature commits en la parte superior de master, es decir, ¿por qué no hace lo contrario?

Responder

Aquí hay un flujo de trabajo que puede usar que hace exactamente lo que necesita hacer.

 git checkout master git pull --rebase (1) git checkout new_feature <do a bunch of commits> git rebase master (2) git checkout master git merge new_feature (3) git branch -D new_feature (4) 

Explicación

(1) git pull --rebase primero searchá origin/master y luego reproducirá tu master local encima de él. Tenga en count en el logging de ejemplo que sus confirmaciones locales se encuentran en la parte superior de su "puntero HEAD remoto local".

 > git log --oneline --all -10 --decorate d34d34c (HEAD, master) Local commit message. d3434r2 Local commit message. d234d4c Local commit message. er3ede3 (origin/master, origin/HEAD) Remote commit message. sfe3fd3 Remote commit message. 

Ahora puede checkout y trabajar en su new_feature twig de new_feature por un time. Cuando termines…

(2) git rebase master reproducirá new_feature en la parte superior del master . Una vez más, sus confirmaciones locales permanecen en la parte superior de su "puntero HEAD remoto local".

 > git log --oneline --all -10 --decorate fc5773d (new_feature) Local new_feature commit. 9282838 Local new_feature commit. d34d34c (HEAD, master) Local commit. d3434r2 Local commit. d234d4c Local commit. er3ede3 (origin/master, origin/HEAD) Remote commit. sfe3fd3 Remote commit. 

El command rebase acaba de poner new_feature antes del master, y para alinearlos debes ejecutar …

(3) git merge new_feature , que hará una fusión de avance rápido. Ahora HEAD , new_feature y master apuntan al mismo commit.

 > git log --oneline --all -10 --decorate fc5773d (HEAD, new_feature, master) Local new_feature commit. 9282838 Local new_feature commit. d34d34c Local commit. d3434r2 Local commit. d234d4c Local commit. er3ede3 (origin/master, origin/HEAD) Remote commit. sfe3fd3 Remote commit. 

(4) Después de eso, puede eliminar de forma segura la new_feature twig de características. Su logging final antes de pulsar se verá así:

 > git log --oneline --all -10 --decorate fc5773d (HEAD, master) Local new_feature commit 2 9282838 Local new_feature commit. d34d34c Local commit. d3434r2 Local commit. d234d4c Local commit. er3ede3 (origin/master, origin/HEAD) Remote commit. sfe3fd3 Remote commit. 

No es necesario ejecutar git rebase new_feature en la twig principal después de ejecutar git rebase master en la nueva twig de funciones. Después de ejecutar git rebase master en la twig new_feature, puede fusionar new_feature en master, será una fusión de avance rápido y no introducirá un commit de fusión.

La razón por la git rebase new-feature no está reproduciendo todas las confirmaciones de nuevas funciones además de la maestra es porque git reconoce que el maestro ya está en la base de la nueva característica – realizamos ese paso con git rebase master – y eso simplemente ser rebase en sí mismo. Por lo tanto, simplemente avanza rápidamente hacia la nueva function.

Además, no necesita preocuparse por enviar confirmaciones que residen debajo de su sugerencia remota / maestra: el control remoto rechazará su inserción en caso de que intente (a less que proporcione la opción -f, que no). Y, si su maestro local está rastreando su maestro remoto, el git status le dirá si su local se ha separado de su sucursal remota.