Réponses:
Assurez-vous que votre arbre de travail est propre, puis
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'
fonctionnera, mais je l'ai également modifié afin d' git musquash 3
omettre complètement l'indicateur -m afin que vous obteniez l' git commit
interface utilisateur interactive dans ce cas.
J'aime personnellement la solution de Wilhelmtell :
git reset --soft HEAD~3
git commit -m 'new commit message'
Cependant, j'ai créé un alias avec une vérification d'erreur pour que vous puissiez le faire:
git squash 3 'my commit message'
Je recommande de configurer des alias qui exécutent réellement des scripts afin qu'il soit plus facile (a) de coder vos scripts et (b) d'effectuer un travail plus complexe avec la vérification des erreurs. Vous trouverez ci-dessous un script qui fait le travail de squash, puis ci-dessous un script pour configurer vos alias git.
Script pour écraser (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
Ensuite, pour connecter ce script squash.sh à un alias git, créez un autre script pour configurer vos alias git comme ceci ( create_aliases.command ou 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
et il sera automatiquement aliasé en tant que git squash
. Je n'ai pas changé votre réponse, juste au cas où il y aurait une raison d'utiliser le create-aiases.sh
script dont je ne suis pas au courant.
Pour ajouter à la réponse de wilhelmtell, je trouve pratique de réinitialiser HEAD~2
puis de modifier le commit de HEAD~3
:
git reset --soft HEAD~2
git commit --all --amend --no-edit
Cela fusionnera tous les commits dans le HEAD~3
validations de validation et utilisera son message de validation. Assurez-vous de partir d'un arbre de travail propre.
J'ai utilisé:
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
A bien fonctionné. N'essayez pas d'avoir un journal de validation avec une ligne commençant par "pick" :)
Utilisez la commande suivante pour écraser les 4 derniers commits du dernier commit:
git squash 4
Avec l'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
Depuis https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Voici une ligne pour écraser les 2 derniers commits. Dans cet exemple, le message de l'avant-dernier commit sera conservé. Vous pouvez modifier le message à votre guise.
git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"
Cette commande sera très utile si vous créez un alias pour cette commande et utilisez l'alias à la place.
Pour tout écraser depuis que la branche a été dérivée de master:
git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author
--reedit-message=HEAD
utilisera le message du dernier commit qui ne fait pas partie de l'écrasement . Ce n'est probablement pas celui que vous souhaitez. Pour obtenir le message du premier commit à inclure , soit (1) remplacez HEAD
par le hachage du commit dont vous voulez que le message soit inclus , ou (2) sautez au premier commit à inclure et git commit --amend --reedit-message=HEAD
. C'est ce que fait la réponse harmonieuse.
Vous pouvez être assez proche avec
git rebase --onto HEAD ~ 4 HEAD ~ master
Cela suppose que vous êtes maître avec une histoire linéaire. Ce n'est pas tout à fait un squash car il rejette les commits intermédiaires. Vous devrez modifier le nouveau HEAD pour modifier le message de validation.
HEAD~4
comme parent.