有没有一种方法可以非交互式地压制大量的提交?

我试图压缩一个提交范围-HEAD 到 HEAD ~ 3。有没有一种快速的方法来做到这一点,或者我需要使用 rebase ——交互式?

51947 次浏览

那么,请确保您的工作树是干净的

git reset --soft HEAD~3
git commit -m 'new commit message'

你可以很接近

git rebase --onto HEAD~4 HEAD~ master

This assumes you're on master with a linear history. It's not quite a squash because it discards the intermediate commits. You'd need to amend the new HEAD to modify the commit message.

我用:

EDITOR="sed -i '2,/^$/s/^pick\b/s/'" git rebase -i <ref>

工作得非常好。只是不要尝试在提交日志中使用以“ pick”开头的行:)

我个人喜欢 Wilhelmtell 的解决方案:

git reset --soft HEAD~3
git commit -m 'new commit message'

但是,我做了一个别名,并进行了一些错误检查,以便您可以这样做:

g.squash 3 'my commit message'

我建议设置实际运行脚本的别名,以便更容易(a)编写脚本代码,(b)使用错误检查执行更复杂的工作。下面是一个脚本,它执行压缩工作。我将其放在 HOME 路径中的脚本文件夹中。

用于压缩的脚本(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

然后,为了将这个 压扁,嘘脚本连接到一个别名,我将以下内容添加到我的. zprofile:

export PATH="$PATH:$HOME/scripts" # Add scripts folder to PATH
...
alias g.squash='function _gSquash(){ sh squash.sh $1 $2; };_gSquash'
...

注意: 你可以使你的别名任何你想要的。我有我的很多我的 git 快捷方式作为 g.<myCommand>

使用以下命令压缩最后一次提交中的最后4次提交:

git squash 4

化名是:

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

来自 https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

下面是压缩最后2次提交的一行代码。在本例中,将保留倒数第二次提交的消息。你可以随意更改信息。

git commit -am "$(git log -1 --skip=1 --pretty=%B | xargs && git reset --soft HEAD~2)"

如果为此命令创建别名并使用别名,则此命令将非常有用。

为了补充 Wilhelmtell的答案,我发现软复位到 HEAD~2然后修改 HEAD~3的提交是很方便的:

git reset --soft HEAD~2
git commit --all --amend --no-edit

这将合并对 HEAD~3提交的所有提交,并使用其提交消息。一定要从一棵干净的工作树开始。

自从树枝从主人那里分出来以后,把一切都压扁了:

git reset --soft $(git merge-base --fork-point master) \
&& git commit --verbose --reedit-message=HEAD --reset-author