git - 自动修复相同消息和作者(完整存储库)的连续提交

标签 git git-svn rebase git-filter-branch git-rewrite-history

我已将一个大型 SVN 存储库迁移到 GIT,并且同一作者有大量具有相同消息的连续提交。

现在我想自动将提交修复为一个提交。

想法?

最佳答案

我终于能够解决这个问题,像往常一样,这是一个人为错误。

我在这里提供的脚本是为 bash 编写的,但正如我从您的实验中看到的那样,这应该不是问题。

这是脚本,我将在下面详细解释它:

#!/bin/bash

author="$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>"
msg="$(cat)"
tree="$1"
parents=()
shift
while getopts ":p:" opt; do
    case $opt in
        p)
            parents=(${parents[*]} $OPTARG)
            ;;
        ?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
    esac
done


create_parents_option() {
    parentsstring=""
    for parent in $@; do
        parentsstring+="-p $parent "
    done
    echo "$parentsstring"
}

get_msg() {
    git log -1 --format="%B" $1
}

get_author() {
    git log -1 --format="%aN <%aE>" $1
}

squash_commit() {
    if [ "x$author" == "x$(get_author $1)" ] && [ "x$msg" == "x$(get_msg $1)" ]; then
        git read-tree -m --aggressive ${1}^{tree} $tree >/dev/null
        tree=$(git write-tree)
        parents=($(git log --format=%P -1 $1))
    fi
}

if [[ ${#parents[@]} == 1 ]]; then
    squash_commit ${parents[0]}
fi

git commit-tree $tree $(create_parents_option ${parents[@]}) -m "$msg"

您可以通过以下方式执行脚本:

git filter-branch --commit-filter "$(cat /path/to/the/script)"

该脚本将检查当前提交是否由同一作者提交并具有与之前相同的消息。

如果是这种情况,它将在使用 git read-tree -m merge 给定的树并将结果写入索引之前将当前提交的树与提交的更改 merge 。
然后使用 git write-tree 根据索引上的 merge 结果生成一棵新树。

然后,脚本继续将当前提交的父级设置为 merge 提交的父级的父级,从而有效地从历史记录中“删除”此提交。

如果您还有任何疑问,我很乐意为您提供帮助。从事这项工作很有趣!

编辑:我已在 Windows 7 上使用 msysgit 版本 1.9.2 测试了此脚本。

关于git - 自动修复相同消息和作者(完整存储库)的连续提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26271635/

相关文章:

git - git merge --squash 是否会导致跨分支 merge 令人头疼

git - 在 git 中“ float ”提交

git - 我可以在我的存储库的一部分上使用 git bisect 吗?

linux - 如何方便地在两个git存储库之间同步文件

git - 无法克隆现有的 Gitlab 存储库

Git pre-svn-dcommit 钩子(Hook)

git-svn rebase 出了可怕的错误

git: checkout 时自动 stash + pop

git - "No newline at end of file"日志有什么意义?

git:我如何轻松判断我是否处于 rebase 过程中