我如何将最后的N承诺集成到一个承诺中?


当前回答

最方便的方式是使用 GitHub 桌面. 只需在历史中选择所有命令,右键单击并选择“Squash x 命令”:

此分類上一篇

其他回答

基于克里斯·约翰森的回答,

从 bash 添加一个全球性的“squash”标志:(或在 Windows 上使用 Git Bash)

git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'

...或使用Windows的命令促销:

git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"

您的 ~/.gitconfig 现在应该包含此标题:

[alias]
    squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"

使用:

git squash N

它自动将最后的 N 承诺集成在一起,包括。

注意: 结果的承诺消息是所有失败的承诺的组合,顺序. 如果你不满意,你总是可以 git 承诺 - 修改,以手动修改。

基于这篇文章,我发现这个方法对我的使用更容易。

我的“dev”分支在“起源/dev”前面有96个承诺(因此这些承诺尚未推到远程)。

我宁愿将分支重新设置为“起源/dev”状态(这将使96个分支的所有变更无效),然后立即进行变更:

git reset origin/dev
git add --all
git commit -m 'my commit message'

程序1

(一)定义承诺短暂的哈希

# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....

在这里,即使是 git log --oneline 也可以用来获得短暂的 hash。

# git rebase -i deab3412 

....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....

....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....

# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....

# git push origin +master

程序2

首先,添加所需的文件

git add <files>

git commit --fixup=OLDCOMMIT

现在这个创建了一个新的承诺在头顶与 fixup1 <OLDCOMMIT_MSG>。

其次,下令下令下令下令下令下令下令下令下令下令下令下令。

git rebase --interactive --autosquash OLDCOMMIT^

在这里 ^ 意味着以前的承诺到 OLDCOMMIT. 这个 rebase 命令在一个编辑器(vim 或 nano)上打开了互动窗口,我们不需要做任何事情,只是保存和输出是足够的. 因为转移到此的选项将自动移动最新的承诺到旧的承诺旁边,并将操作转换为 fixup(相当于 squash)。 然后 rebase 继续完成。

程序3

如果需要将新的更改添加到最后的承诺方式 - 更改可以使用 git-commit。

    # git log --pretty=oneline --abbrev-commit
    cdababcd Fix issue B
    deab3412 Fix issue A
    ....
    # git add <files> # New changes
    # git commit --amend
    # git log --pretty=oneline --abbrev-commit
    1d4ab2e1 Fix issue B
    deab3412 Fix issue A
    ....  

结论

只需将此 bash 函数添加到.zshrc 文件的 bash。

# Squash last X commits with a Commit message.
# Usage: squash X 'COMMIT_MSG'
# where X= Number of last commits.
# where COMMIT_MSG= New commit msg.
function squash() {
    if [ -z "${1}" -o -z "${2}" ]; then
        echo "Usage: \`squash X COMMIT_MSG\`"
        echo "X= Number of last commits."
        echo "COMMIT_MSG= New commit msg."
        return 1
    fi

    git reset --soft HEAD~"$1"
    git add . && git ci -m "$2" # With 100 emoji
    git push --force
}

然后跑

squash X 'New Commit Message'

你已经完成了。

要避免在重定向同一分支中的承诺时不得不解决任何合并冲突,您可以使用下列命令:

git rebase -i <last commit id before your changes start> -s recursive -X 我們

要将所有承诺分成一个,当您被要求编辑将合并的承诺时(在旗帜上),更新所有但第一个行动,从选择到分解,如其他答案中所建议。

在这里,我们使用合并策略(旗帜)回归和战略选项(X)我们的,以确保历史上后来的承诺赢得任何合并冲突。

注意:不要把这与我们做别的事情的 git rebase 混淆。

引用: git rebase recursive merge 策略