Antworten:
Stellen Sie dann sicher, dass Ihr Arbeitsbaum sauber ist
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'
wird funktionieren, aber ich habe es auch so git musquash 3
angepasst, dass das Flag -m vollständig weggelassen wird, sodass Sie git commit
in diesem Fall die interaktive Benutzeroberfläche erhalten.
Ich persönlich mag die Lösung von wilhelmtell :
git reset --soft HEAD~3
git commit -m 'new commit message'
Ich habe jedoch einen Alias mit einer Fehlerprüfung erstellt, damit Sie dies tun können:
git squash 3 'my commit message'
Ich empfehle, Aliase einzurichten, in denen tatsächlich Skripte ausgeführt werden, damit es einfacher ist, (a) Ihre Skripte zu codieren und (b) komplexere Arbeiten mit der Fehlerprüfung durchzuführen. Unten finden Sie ein Skript, das die Arbeit des Squashs erledigt, und unten ein Skript zum Einrichten Ihrer Git-Aliase.
Skript zum Quetschen (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
Um dieses squash.sh- Skript mit einem Git-Alias zu verbinden, erstellen Sie ein anderes Skript zum Einrichten Ihrer Git-Aliase wie folgt ( create_aliases.command oder 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
einfügen und es wird automatisch als Alias bezeichnet git squash
. Ich habe Ihre Antwort nicht geändert, nur für den Fall, dass es einen Grund gibt, das create-aiases.sh
Skript zu verwenden, das mir nicht bekannt ist.
Um die Antwort von wilhelmtell zu ergänzen, finde ich es zweckmäßig, HEAD~2
das Commit von zurückzusetzen und dann zu ändern HEAD~3
:
git reset --soft HEAD~2
git commit --all --amend --no-edit
Dadurch werden alle Commits mit dem HEAD~3
Commit zusammengeführt und die Commit-Nachricht verwendet. Stellen Sie sicher, dass Sie von einem sauberen Arbeitsbaum ausgehen.
Ich benutzte:
EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>
Hat ganz gut funktioniert. Versuche nur nicht, ein Commit-Protokoll mit einer Zeile zu erstellen, die mit "pick" beginnt :)
Verwenden Sie den folgenden Befehl, um die letzten 4 Commits innerhalb des letzten Commits zu quetschen:
git squash 4
Mit dem 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
Von https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
Hier ist ein Einzeiler, um die letzten 2 Commits zu quetschen. In diesem Beispiel wird die Nachricht vom vorletzten Commit beibehalten. Sie können die Nachricht nach Ihren Wünschen ändern.
git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"
Dieser Befehl ist sehr nützlich, wenn Sie einen Alias für diesen Befehl erstellen und stattdessen den Alias verwenden.
Um alles zu zerquetschen, seit der Ast vom Meister gegabelt wurde:
git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author
--reedit-message=HEAD
verwendet die Nachricht des letzten Commits, die nicht Teil des Squashing ist . Dies ist wahrscheinlich nicht die, die Sie wollen. Um die Nachricht des ersten Commits zu erhalten, das aufgenommen werden soll , ersetzen Sie entweder (1) durch HEAD
den Hash des Commits, dessen Nachricht Sie aufnehmen möchten, oder (2) springen Sie zum ersten Commit, das aufgenommen werden soll, und git commit --amend --reedit-message=HEAD
. Dies ist, was harmonische Antwort tut.
Sie können ziemlich nah mit kommen
Git Rebase - auf HEAD ~ 4 HEAD ~ Master
Dies setzt voraus, dass Sie mit einer linearen Historie auf dem Master sind. Es ist kein Squash, weil es die Zwischen-Commits verwirft. Sie müssten den neuen HEAD ändern, um die Commit-Nachricht zu ändern.
HEAD~4
als übergeordnetes Element zu haben .