我不小心用一些巨大的文件推送了一个提交,然后还原了它。但它导致任何人拉这个分支在历史记录中获取这些文件,所以我决定删除或压缩这两个提交。但是,有些分支已合并。我不知道如何让“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
答案 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
,推动修正后的分支。当然,任何拉动分支的人最终都会获得强制拉力。