git - 从合并分支中删除提交

时间:2016-09-16 11:59:57

标签: git git-rebase git-revert

我不小心用一些巨大的文件推送了一个提交,然后还原了它。但它导致任何人拉这个分支在历史记录中获取这些文件,所以我决定删除或压缩这两个提交。但是,有些分支已合并。我不知道如何让“git rebase -i”保持分支结构。

历史现在看起来像:

H - new commits
|
G - merge
| \
|  F - commits on another branch
|  |
E  | - some other commits
|  |
D  | - corrected B
|  |
C  | - revert B
|  |
B  | - huge files
| /
A - early commit

我可以将其更改为以下内容吗?

h - new commits
|
g - merge
| \
|  F - commits on another branch
|  |
e  | - some other commits
|  |
d  | - corrected B
| /
A - early commit

2 个答案:

答案 0 :(得分:2)

你可以 ,但你不应该

它将要求您重写历史记录并替换服务器上已经推送的历史记录(这需要强制推送,并且最常导致每个人都对你大吼大叫)

但如果您真的想要git filter-branch就是您想要使用的内容,就像在this SO answer中一样。所以你会做这样的事情:

git filter-branch --commit-filter '
    if [ "$GIT_COMMIT" = "<your commit to remove here>" ]
    then
        skip_commit "$@";
    else
        git commit-tree "$@";
    fi'  HEAD

还有一些例子here

答案 1 :(得分:0)

不,你不能。

每个提交的哈希不仅包括索引中所有文件的哈希内容,还包括提交父项的哈希值。

“更正的B”将拥有与现在不同的父级。这会改变哈希值。

可以解决这个问题,但是一旦完成,就不可能避免用力推动修复,并让所有人强行拉动它。

解决此问题的唯一真正方法是以下过程:

 git checkout A

在分支分支之前检查父提交。然后,创建两个工作分支:

 git checkout -b corrected-mainline
 git checkout -b corrected-fork

你现在正在修正叉分支上。现在,在这个分支上,您应该能够git cherry-pick所有提交到F提交,跳过提交大文件及其恢复。如果这些提交中的任何一个是合并,请执行相同的合并。

现在,在corrected-mainline分支

上执行相同的操作
 git checkout corrected-mainline

现在,git cherry-pick主线分支上的所有提交,直到G合并之前的最后一次提交。然后,与corrected-fork分支合并。现在,这是您更正的G合并提交。

完成樱桃选择最初在图表中G之上的任何提交,完成原始分支上的最后一次提交。

此时,工作分支的内容应与原始分支的内容相同。确认是这样。

然后,删除原始分支,将工作分支重命名为其名称。或者,使用git reset --hard将原始分支重置为已更正的工作分支。

然后执行git push --force,推动修正后的分支。当然,任何拉动分支的人最终都会获得强制拉力。