从 git 历史中抹去整个提交链?
Obliterate entire chain of commits from git history?
我有一个很奇怪的问题。在尝试迁移到 Github 的大型文件存储并尝试从它迁移出去时遇到一些不幸之后,我现在有一个非常混乱的 git 拓扑,如下所示:
A - B - C - D - E - F
/
A' - B' - C'
现在,C 与 C' 完全相同,B 与 B' 完全相同,依此类推一直回到初始提交。如果我这样做 "git log",我基本上会看到 D 之前所有内容的重复提交。D 本身是一个空合并。
有没有办法完全删除A'、B'、C',让我的历史变成这样?
A - B - C - E - F
是的。您可以将 E - F
变基到 C
.
git rebase --onto <new-base> <exclusive-start> <inclusive-end>
因为起点是独占的(它不会变基)我们从 D 开始到 F 结束。(这使得变基在上面的分支变得容易分支机构)。
git rebase --onto C D F
你会得到这个。
E' - F'
/
A - B - C - D - E - F
/
A' - B' - C'
只要没有任何内容指向 F,A' - F 最终将被垃圾回收。
鉴于 D
未引入任何更改,您可以通过多种方式进行更改。
rebase 会起作用(正如 Schwern 所建议的)。 "Reparenting" 也可以。
因为变基是 "more familiar",我认为有些人可能更喜欢这种方法。另一方面,在某些情况下,变基变得复杂可能会引入错误;出于这个原因,我更喜欢在两者预期相同的情况下重新设置。
假设您显示的历史记录是 master
分支的历史记录(并且从 D
开始的任何内容都无法从任何其他分支访问),那么 rebase 将是
git rebase --onto C D master
用解析相应提交的表达式替换 C
和 D
(即提交 ID,或者您显示的历史图中 C
的 master~3
).
请注意,我使用分支名称而不是提交 ID 或其他表达式来标识 F
。这样rebase操作会自动移动分支。
如果在 D
之后有合并(即使它们全部折叠回一个仍然当前的分支),或者如果有多个分支指向您正在移动的历史记录,那么这些是在最明显的情况下,您可能会考虑重新设置父级。
在这种情况下,您将使用 git filter-branch
。有几种方法可以做到;请参阅 parent-filter
下的 git filter-branch
文档 (https://git-scm.com/docs/git-filter-branch);有一些示例具体说明了如何重新提交提交。
我有一个很奇怪的问题。在尝试迁移到 Github 的大型文件存储并尝试从它迁移出去时遇到一些不幸之后,我现在有一个非常混乱的 git 拓扑,如下所示:
A - B - C - D - E - F
/
A' - B' - C'
现在,C 与 C' 完全相同,B 与 B' 完全相同,依此类推一直回到初始提交。如果我这样做 "git log",我基本上会看到 D 之前所有内容的重复提交。D 本身是一个空合并。
有没有办法完全删除A'、B'、C',让我的历史变成这样?
A - B - C - E - F
是的。您可以将 E - F
变基到 C
.
git rebase --onto <new-base> <exclusive-start> <inclusive-end>
因为起点是独占的(它不会变基)我们从 D 开始到 F 结束。(这使得变基在上面的分支变得容易分支机构)。
git rebase --onto C D F
你会得到这个。
E' - F'
/
A - B - C - D - E - F
/
A' - B' - C'
只要没有任何内容指向 F,A' - F 最终将被垃圾回收。
鉴于 D
未引入任何更改,您可以通过多种方式进行更改。
rebase 会起作用(正如 Schwern 所建议的)。 "Reparenting" 也可以。
因为变基是 "more familiar",我认为有些人可能更喜欢这种方法。另一方面,在某些情况下,变基变得复杂可能会引入错误;出于这个原因,我更喜欢在两者预期相同的情况下重新设置。
假设您显示的历史记录是 master
分支的历史记录(并且从 D
开始的任何内容都无法从任何其他分支访问),那么 rebase 将是
git rebase --onto C D master
用解析相应提交的表达式替换 C
和 D
(即提交 ID,或者您显示的历史图中 C
的 master~3
).
请注意,我使用分支名称而不是提交 ID 或其他表达式来标识 F
。这样rebase操作会自动移动分支。
如果在 D
之后有合并(即使它们全部折叠回一个仍然当前的分支),或者如果有多个分支指向您正在移动的历史记录,那么这些是在最明显的情况下,您可能会考虑重新设置父级。
在这种情况下,您将使用 git filter-branch
。有几种方法可以做到;请参阅 parent-filter
下的 git filter-branch
文档 (https://git-scm.com/docs/git-filter-branch);有一些示例具体说明了如何重新提交提交。