从历史中删除 git 次提交
Removing a git commit from history
假设我在 git
中有以下提交
A---B---C---D---E---F
还假设提交 B
和 D
是空的(不包含文件,即空快照)。
所以,我想去掉 B
和 D
;我正在做以下事情:
git filter-branch --prune-empty
最后我得到以下结果:
A---B---C---D---E---F
\
\--C'---E'---F'
但这不是我想要的,我想以
结束
A---C'---E'---F'
我该怎么做?
注:我也试过:
git rebase -i HEAD~6
但是还是不行。
重要更新
事实证明我做对了。来自 mu 无 的回答启发了我更多地研究为什么它对他有效但对我无效。我原来的分支从未被删除。经过进一步调查,似乎我在 C
广告 F
中有标签导致分支保留。因此,在 运行 filter-branch
命令之前,我删除了两个标签并且它起作用了。
您实际上已经以正确的提交结束,现在就git checkout F'
。
如果您将这些更改推送到远程存储库,则需要使用 git push -f origin branch_F':branch_F
.
强制更新那里的分支
示例:
创建一个新的存储库
$ git init
$ touch a && git add a && git commit -m "added a"
$ git commit --allow-empty -m "empty 1"
$ touch b && git add b && git commit -m "added b"
$ git commit --allow-empty -m "empty 2"
$ touch c && git add c && git commit -m "added c"
检查提交历史
$ git log --oneline
27196e9 (HEAD, master) added c
24e10de empty 2
a2d3931 added b
88be904 empty 1
564d4e4 added a
运行 过滤分支
$ git filter-branch --prune-empty
Rewrite 27196e9bc27e93ff54ebd10a5c8435e7fe496c78 (5/5)
Ref 'refs/heads/master' was rewritten
再次检查日志中的提交
$ git log --oneline
221f0d0 (HEAD, master) added c
ab6bf5f added b
564d4e4 added a
编辑
正如 OP 在他的 中提到的那样,这是由于中间提交中存在的标签而发生的。删除标签使这项工作。
在 git 中有几种方法可以做到这一点,但首先你必须确保没有人已经拉过分支。如果有人确实拉了它,你不能并且不应该改变树的历史。
如果有人已经提取了它,您只需重新添加 "old" 内容并覆盖当前数据。
万一还没有人拉,这里有一些你的选择:
键入 git reflog
并检查更改之前的最后一次良好提交,您将获得一个分离的头部,因此创建一个新分支,删除远程分支并再次推送它。
git format-patch** <number of commit to choose>
然后按照项目符号#1 中的描述检查分支并应用所需的提交(删除您希望跳过的提交)
还有更多选项,但这些是最简单的选项。
假设我在 git
中有以下提交A---B---C---D---E---F
还假设提交 B
和 D
是空的(不包含文件,即空快照)。
所以,我想去掉 B
和 D
;我正在做以下事情:
git filter-branch --prune-empty
最后我得到以下结果:
A---B---C---D---E---F
\
\--C'---E'---F'
但这不是我想要的,我想以
结束A---C'---E'---F'
我该怎么做?
注:我也试过:
git rebase -i HEAD~6
但是还是不行。
重要更新
事实证明我做对了。来自 mu 无 的回答启发了我更多地研究为什么它对他有效但对我无效。我原来的分支从未被删除。经过进一步调查,似乎我在 C
广告 F
中有标签导致分支保留。因此,在 运行 filter-branch
命令之前,我删除了两个标签并且它起作用了。
您实际上已经以正确的提交结束,现在就git checkout F'
。
如果您将这些更改推送到远程存储库,则需要使用 git push -f origin branch_F':branch_F
.
示例:
创建一个新的存储库
$ git init $ touch a && git add a && git commit -m "added a" $ git commit --allow-empty -m "empty 1" $ touch b && git add b && git commit -m "added b" $ git commit --allow-empty -m "empty 2" $ touch c && git add c && git commit -m "added c"
检查提交历史
$ git log --oneline 27196e9 (HEAD, master) added c 24e10de empty 2 a2d3931 added b 88be904 empty 1 564d4e4 added a
运行 过滤分支
$ git filter-branch --prune-empty Rewrite 27196e9bc27e93ff54ebd10a5c8435e7fe496c78 (5/5) Ref 'refs/heads/master' was rewritten
再次检查日志中的提交
$ git log --oneline 221f0d0 (HEAD, master) added c ab6bf5f added b 564d4e4 added a
编辑
正如 OP 在他的
在 git 中有几种方法可以做到这一点,但首先你必须确保没有人已经拉过分支。如果有人确实拉了它,你不能并且不应该改变树的历史。
如果有人已经提取了它,您只需重新添加 "old" 内容并覆盖当前数据。
万一还没有人拉,这里有一些你的选择:
键入
git reflog
并检查更改之前的最后一次良好提交,您将获得一个分离的头部,因此创建一个新分支,删除远程分支并再次推送它。git format-patch** <number of commit to choose>
然后按照项目符号#1 中的描述检查分支并应用所需的提交(删除您希望跳过的提交)
还有更多选项,但这些是最简单的选项。