Respuestas:
Asegúrese de que su árbol de trabajo esté limpio, luego
git reset --soft HEAD~3
git commit -m 'new commit message'
git reset --soft HEAD~3 && git commit -m "my message"
git config alias.mysquash '!f(){ git reset --soft HEAD~$1 && git commit ${2:+-m "$2"}; };f'
. git mysquash 3 'some message'
funcionará, pero también lo modifiqué, por git musquash 3
lo que omitiré la marca -m por completo para que obtenga la git commit
interfaz de usuario interactiva en ese caso.
Personalmente, me gusta la solución de Wilhelmtell :
git reset --soft HEAD~3
git commit -m 'new commit message'
Sin embargo, hice un alias con alguna comprobación de errores para que puedas hacer esto:
git squash 3 'my commit message'
Recomiendo configurar alias que realmente ejecuten scripts para que sea más fácil (a) codificar sus scripts y (b) hacer un trabajo más complejo con la verificación de errores. A continuación se muestra un script que hace el trabajo de squash y, a continuación, hay un script para configurar sus alias de git.
Script para aplastar (squash.sh)
#!/bin/bash
#
#get number of commits to squash
squashCount=$1
#get the commit message
shift
commitMsg=$@
#regular expression to verify that squash number is an integer
regex='^[0-9]+$'
echo "---------------------------------"
echo "Will squash $squashCount commits"
echo "Commit message will be '$commitMsg'"
echo "...validating input"
if ! [[ $squashCount =~ $regex ]]
then
echo "Squash count must be an integer."
elif [ -z "$commitMsg" ]
then
echo "Invalid commit message. Make sure string is not empty"
else
echo "...input looks good"
echo "...proceeding to squash"
git reset --soft HEAD~$squashCount
git commit -m "$commitMsg"
echo "...done"
fi
echo
exit 0
Luego, para conectar ese script squash.sh a un alias de git, cree otro script para configurar sus alias de git así ( create_aliases.command o create_aliases.sh ):
#!/bin/sh
echo '-----------------------'
echo 'adding git aliases....'
echo '-----------------------'
echo
git config --global alias.squash "!bash -c 'bash <path to scripts directory>/squash.sh \$1 \$2' -"
#add your other git aliases setup here
#and here
#etc.
echo '------------------------------------'
echo 'here is your global gitconfig file:'
echo '------------------------------------'
more ~/.gitconfig
echo
echo
echo '----------------'
echo 'end of script...'
echo '----------------'
$PATH
named git-squash.sh
y automáticamente se le asignará un alias git squash
. No cambié tu respuesta, por si acaso hay una razón para usar el create-aiases.sh
guión que no conozco.
Para agregar a la respuesta de wilhelmtell, me resulta conveniente realizar un restablecimiento parcialHEAD~2
y luego enmendar la confirmación de HEAD~3
:
git reset --soft HEAD~2
git commit --all --amend --no-edit
Esto fusionará todas las confirmaciones con la HEAD~3
confirmación y usará su mensaje de confirmación. Asegúrese de comenzar con un árbol de trabajo limpio.
Solía:
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
Funcionó bastante bien. Simplemente no intente tener un registro de confirmación con una línea que comience con "elegir" :)
Use el siguiente comando para aplastar las últimas 4 confirmaciones dentro de la última confirmación:
git squash 4
Con el alias:
squash = !"f() { NL=$1; GIT_EDITOR=\"sed -i '2,$NL s/pick/squash/;/# This is the 2nd commit message:/,$ {d}'\"; git rebase -i HEAD~$NL; }; f"
sq = !git squash $1
sqpsf = !git squash $1 && git psf
De https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Aquí hay una línea para aplastar las últimas 2 confirmaciones. En este ejemplo, se conservará el mensaje de la penúltima confirmación. Puede cambiar el mensaje como desee.
git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"
Este comando será muy útil si crea un alias para este comando y usa el alias en su lugar.
Para aplastar todo desde que la rama se bifurcó del maestro:
git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author
--reedit-message=HEAD
usará el mensaje de la última confirmación que no es parte del aplastamiento . Es probable que este no sea el que desea. Para que se incluya el mensaje de la primera confirmación , (1) reemplácelo HEAD
con el hash de la confirmación de la que desea que se incluya el mensaje, o (2) salte a la primera confirmación que se incluirá y git commit --amend --reedit-message=HEAD
. Esto es lo que hace la respuesta armoniosa.
Puedes acercarte bastante
git rebase --en HEAD ~ 4 HEAD ~ master
Esto supone que está en el maestro con un historial lineal. No es del todo un squash porque descarta las confirmaciones intermedias. Debería enmendar el nuevo HEAD para modificar el mensaje de confirmación.
HEAD~4
como padre.