我已将一个大型 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/