使用Git Filter-Branch后如何删除重复提交



我使用以下代码来编辑我的提交历史记录,将错误的电子邮件设置为我的git配置,我想用正确的内容来更新我的所有提交。

git filter-branch --env-filter '
WRONG_EMAIL="xxx"
NEW_NAME="xxx"
NEW_EMAIL="xxxx"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

现在的问题是,它重复了所有的提交,即使是我的人,我也会知道,它留下了我的旧奉献并创建了一个新的承诺,但是为什么它重复了不是我的命令呢?谁能告诉我为什么会发生这种情况以及如何解决?

我认为问题是您错过了以下

git push --force --tags origin 'refs/heads/*'

在本地更改提交后,您应将更新强制在遥控器上。

副本主要是因为遥控器上的旧投入没有改变。

好吧,需要一点半技术背景来充分理解这一点...

tl; dr - 如果提交被重写,则该提交的每个孩子也必须重写。因此,例如,听起来您必须重写初始提交。那将迫使重写每项提交。您无法修复它;这对于GIT的工作原理是不可或缺的。如果要更改root commit中的内容,则不可避免地会更改每个提交的哈希值。

详细信息

git回购中的结构相当严格;这与Git如何实现其性能,使用哈希进行快速内容比较等有关。每个对象都有一个哈希值,并且使用哈希值来存储对象。这用于文件(称为blob对象),目录(树对象),提交(您关注的对象)以及Git可以存储和地址的任何内容。

严格的算法计算哈希,因此始终给出相同的内容。同样,这是GIT如何更改检测(除其他事项)不可或缺的一部分。相反,非常不可能有两个不同的对象获得相同的哈希值(如果他们这样做会损坏您的回购)。

因此,在计算该对象的哈希时,必须考虑将对象"与"与"不同"或"不同"的所有内容。在提交的情况下,commita和commitb在各个方面都可能是相同的,除了commita是commitx的孩子,而commitb是一个合并的孩子。他们必须被视为不同的物体,否则您永远无法正确地穿越历史。

因此,当您重写commit d的父母时,您会更改识别commit d在历史上的位置的父母哈希,因此您必须重写commit d(也给它一个新的哈希...这是通过所有后代提交的递归继续进行的。)。

最新更新