Aplaste solo a una confirmación "correcta" para la request de extracción de github

Tengo un repository en github que alguien más (Bob, por el bien de la discusión) ha emitido una request de extracción. Su código no es perfecto, así que pasamos por algunas rondas de marcas. Según lo entiendo, se compromete y presiona a su request de extracción para cada set de cambios marcados.

Entonces mi repository ahora se ve así:

master: ---o A (Chowlett | | pull-req: o---o---o---o BCD (all Bob) 

Commit SHAs y msgs son los siguientes:

UN:

 123456 Good commit <chowlett> 

SEGUNDO:

 777ccc Fix the widget bug <bob> 

DO:

 888ddd Review markups <bob> 

RE:

 999eee Further markups <bob> 

Ahora estoy feliz de aceptar esta request de extracción; pero preferiría que las versiones de premarcado no estuvieran en mi repository. ¿Puedo lograr todo lo siguiente? ¿y cómo?

  • Fusionar B, C y D en mi repository como un compromiso único
  • Genere también la confirmación de "Solicitud de extracción de fusión # 99 en …"
  • Haz que github cierre automáticamente la request de extracción

Tenga en count que Bob no tiene que aplastar sus compromisos cuando está haciendo un PR de GitHub.
Desde marzo de 2016, puede dejar esa operación al mantenedor (usted) aceptando su RP.

Consulte " Aplastar sus compromisos " y su nueva documentation

Esta es una nueva opción que te permite forzar el aplastamiento de commit en todas las requestes de extracción combinadas mediante el button de fusión.

https://help.github.com/assets/images/help/pull_requests/squash-and-merge.png

Hay dos funciones de 'squash' incorporadas en git . Hay git merge --squash y está la acción de squash en git rebase --interactive . El primero no retiene ningún autor o información de date, solo recostack todos los cambios de una serie de confirmaciones en la copy de trabajo local. Esto último es molesto porque requiere interacción.

La extensión de git squash hace lo que quieres. Reasigna la CABEZA actual en una base específica mientras aplasta automáticamente las confirmaciones intermedias. También proporciona una opción de línea de command para establecer el post en la confirmación final aplastada en los casos en que la rebase no crea conflictos.

Al lanzar esto junto con hub y ghi , es posible que puedas build un script en esta línea:

 git pull upstream master hub checkout https://github.com/$user/$repo/pull/$issue git squash master rev=$(git rev-parse --short HEAD) git checkout master git merge $rev git commit --amend "Merged pull request #$issue" git push upstream master ghi close $issue $user/$repo ghi comment $issue "Merged as $rev" $user/$repo 

Puede usar la opción –squash para fusionarse

 git merge <remote url> <remote branch> --squash 

Sin embargo, esto no producirá un compromiso de fusión. En cambio, producirá un set normal de cambios en el tree de trabajo como si aplicara manualmente todos sus cambios a su copy. Entonces te comprometería como siempre.

La desventaja será que su historial en master no mostrará este commit como una fusión de su twig. Simplemente parecerá que usted mismo hizo el trabajo y no le dará crédito a Bob.

Usando git rebase

Una idea sería verificar la twig y aplastar todas las confirmaciones en una utilizando la rebase iteractiva, luego forzar push para actualizar la request de extracción y fusionar (aunque parte de este trabajo podría delegarse en Bob).

Para aplastar automáticamente todas las confirmaciones de una twig en la primera y aplicar esto a la request de extracción, puede usar los siguientes commands:

 $ git checkout pull-req $ GIT_SEQUENCE_EDITOR='sed -i "2,\$s/^pick/s/g" $1' git rebase -i origin/master $ git push --force 

GIT_SEQUENCE_EDITOR es una variable de entorno Git para establecer un editor temporal para la list de confirmación de rebase. Lo configuramos en un script en línea que reemplaza la palabra pick by s (que significa squash ) en el comienzo de todas las líneas excepto la primera (que es el 2,\$ en el patrón sed ). La list de compromisos que se pasa al script es un file de text simple. Luego, Git procede con la rebase y le permite editar el post de confirmación final.

Además, con un git hook puedes editar más o less fácilmente este post final para adaptarlo a tus necesidades (por ejemplo, agrega un separador visual entre los posts de commit aplastados).

Usando git merge –squash

Aplastamiento también es posible a través de git merge --squash . Vea aquí la diferencia entre los dos methods. El siguiente script aplastaría las confirmaciones de una twig en una única confirmación mediante el command de fusión. También crea una copy de security de la twig (por si acaso).

 MAINBRANCH="master" CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # update current feature branch with master git pull origin $MAINBRANCH # delete existing backup git branch -D "$CURRENT_BRANCH-backup" # backup current feature branch and go back git checkout -b "$CURRENT_BRANCH-backup" && git checkout - # checkout and update master branch git checkout $MAINBRANCH && git pull # create new branch from master git checkout -b "$CURRENT_BRANCH-squashed" # set it to track the corresponding feature branch git branch "$CURRENT_BRANCH-squashed" --set-upstream-to "$CURRENT_BRANCH" # merge and squash the feature branch into the one created git merge --squash $CURRENT_BRANCH # commit the squashed changes git commit # force push to the corresponding feature branch git push -f . HEAD:$CURRENT_BRANCH # checkout the feature branch git checkout $CURRENT_BRANCH # delete the squashed copy git branch -D "$CURRENT_BRANCH-squashed" 

Esto funcionó para mí.

  • Mi trabajo en devtools_import_export permanece intacto.
  • Mi request de extracción para issue35squashed a upstream / master solo tiene una confirmación.
  • Por desgracia, la fusión no se registra, pero el post de confirmación tiene todos los detalles.

Esto es lo que realmente hice (ver https://github.com/anaran/devtools-snippets/network )

 git checkout master git status # all clean git checkout -B issue35squashed master git merge --squash devtools_import_export git status # looks good git commit # review and commit via emacs git log --graph --abbrev-commit --stat --pretty --decorate=full --branches git push --all -v 

(Mi bash anterior de usar git merge --no-ff ... está en issue35take2 y una request de extracción contiene todas las confirmaciones individuales de devtools_import_export . No es bueno).