usar qué how hacer from como git github pull-request

qué - Aplaste solo a una confirmación "correcta" para la solicitud de extracción de github



pull request from master (5)

Tengo un repositorio en github que alguien más (Bob, por el bien de la discusión) ha emitido una solicitud 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 solicitud de extracción para cada conjunto de cambios marcados.

Entonces mi repositorio ahora se ve así:

master: ---o A (Chowlett | | pull-req: o---o---o---o B C D (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 solicitud de extracción; pero preferiría que las versiones de premarcado no estuvieran en mi repositorio. ¿Puedo lograr todo lo siguiente? ¿y cómo?

  • Fusionar B, C y D en mi repositorio 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 solicitud de extracción

Usando git rebase

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

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

$ 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 lista 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 lista de compromisos que se pasa al script es un archivo de texto simple. Luego, Git procede con la rebase y le permite editar el mensaje de confirmación final.

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

Usando git merge --squash

Aplastamiento también es posible a través de git merge --squash . Vea here la diferencia entre los dos métodos. El siguiente script aplastaría las confirmaciones de una rama en una única confirmación utilizando el comando de fusión. También crea una copia de seguridad de la rama (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 solicitud de extracción para issue35squashed a upstream / master solo tiene una confirmación.
  • Por desgracia, la fusión no se registra, pero el mensaje 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 intento anterior de usar git merge --no-ff ... está en issue35take2 y una solicitud de extracción contiene todas las confirmaciones individuales de devtools_import_export . No es bueno).


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 fecha, solo recopila todos los cambios de una serie de confirmaciones en la copia 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 comando para establecer el mensaje 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 construir 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á una fusión de compromiso. En cambio, producirá un conjunto normal de cambios en el árbol de trabajo como si aplicara manualmente todos sus cambios a su copia. Entonces te comprometería como siempre.

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


Tenga en cuenta 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 documentación

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