如何在git中用一行压缩两个不连续的提交



我知道我可以使用rebase -i来完成这项工作,但我确实在寻找一种在一行中完成的方法,例如使用脚本。我看了一下如何运行git-rebase——以非交互式方式进行交互?例如,但我的bashfu太弱,无法正确使用。

需要明确的是,这就是我现在所拥有的:

A1B2C3有些承诺AAAAAA其他一些承诺A3B2C1更多承诺BBBBBB另一个承诺

我想把AAAAAA和BBBBBB压缩成一行(或几行),不进行交互。

感谢

您可以通过一系列樱桃选择和修改的提交来模拟rebase交互:

git checkout AAAAAA
git cherry-pick BBBBBB -n && git commit --amend -m "AAAAA squashed with BBBBB"
git cherry-pick A3B2C1

在链接问题的帮助下,我最终使用了bash脚本。为了完整起见,我附上了它。注意:我的bash是丑陋的。但有一点很重要:由于脚本不能接受参数,我选择了一个自我修改的代码。如果有更好的解决方案(不使用全局/环境变量),我很想知道。此外,我也不完全确定如何在bash中交换两行(谷歌并不是一个很好的帮助),所以我最终使用了for循环。

#!/bin/bash
commit1=???
commit2=???
if [ "$#" -eq 2 ]; then #2 arguments, first phase of script
    #modify lines 2 and 3 with arguments
    currentFile=${BASH_SOURCE[0]}
    cat $currentFile | sed "2s/.*/commit1=$1/" | sed "3s/.*/commit2=$2/" >| $currentFile
    echo "$currentFile"
    exit
fi
# second phase of script
line1=$(grep -nr "pick $commit1" $1 | cut -f1 -d:)
if [ -z $line1 ]; then
    echo "Could not find a match for $commit1"
    exit
fi
line2=$(grep -nr "pick $commit2" $1 | cut -f1 -d:)
if [ -z $line2 ]; then
    echo "Could not find a match for $commit2"
    exit
fi
oldLine=$(($line1<$line2?$line1:$line2))
newLine=$(($line1>$line2?$line1:$line2))
cat $1
#move newLine to be below oldLine, by iterating over all lines in reverse and swapping one by one
for currentLineIndex in `seq $newLine -1 $(expr $oldLine + 2)`; do
    currentLine=$(sed -n "${currentLineIndex}p" "$1")
    nextLineIndex=$(expr $currentLineIndex - 1)
    nextLine=$(sed -n "${nextLineIndex}p" "$1")
    cat $1 | sed $currentLineIndex"s/.*/$nextLine/" | sed $nextLineIndex"s/.*/$currentLine/" >| $1
done
#change the pick to squash
cat $1 | sed $(expr $oldLine + 1)"s/pick/squash/" >| $1

示例用法:$ GIT_SEQUENCE_EDITOR=$(./rebase.sh d199 a548) git rebase -i 95e2a7c

如果您只想修复来自暂存区的现有提交,则有一个更简单的替代方案:(感谢@Andrew C为我指出--fixup

function git_fix {
    git commit --fixup=$1
    GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash "$1^" #empty script
}

作为git别名:

fix="!f() {
    git commit --fixup=$1;
    GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash "$1^";
}; f"

最新更新