删除git历史记录中的第一个x提交,并从其余历史记录中删除所有合并分支

删除git历史记录中的第一个x提交,并从其余历史记录中删除所有合并分支,git,github,github-for-mac,git-history-graph,Git,Github,Github For Mac,Git History Graph,我有一个git项目的历史记录,我有近400次提交。我想删除前(最早)200个提交。然后在剩下的200次提交中,我只想删除所有合并提交,并保持其余的有序 完成后,我想检查所有剩余的提交,并更改一封特定的作者电子邮件 有没有办法优雅地做到这一点 首先,如果你真的想这样做,请三思。(更改历史记录,尤其是在公共存储库中,通常是个坏主意。) 您可以使用git-rebase-i来执行此操作。您可以使用fixup将两个提交合并为一个,也可以使用edit更改提交。(包括作者变更) 对于多个提交的自动更改,您可以

我有一个git项目的历史记录,我有近400次提交。我想删除前(最早)200个提交。然后在剩下的200次提交中,我只想删除所有合并提交,并保持其余的有序

完成后,我想检查所有剩余的提交,并更改一封特定的作者电子邮件


有没有办法优雅地做到这一点

首先,如果你真的想这样做,请三思。(更改历史记录,尤其是在公共存储库中,通常是个坏主意。)

您可以使用
git-rebase-i
来执行此操作。您可以使用
fixup
将两个提交合并为一个,也可以使用
edit
更改提交。(包括作者变更)


对于多个提交的自动更改,您可以使用
git过滤器分支
。但是,只有当你知道自己在做什么时,才可以使用它。

如果你真的想这样做,请先三思。(更改历史记录,尤其是在公共存储库中,通常是个坏主意。)

您可以使用
git-rebase-i
来执行此操作。您可以使用
fixup
将两个提交合并为一个,也可以使用
edit
更改提交。(包括作者变更)


对于多个提交的自动更改,您可以使用
git过滤器分支
。但是,只有当你知道自己在做什么时才使用它。

正如一些人已经说过的,这很少是一个好主意,有几个原因我将不再重复。不过,我想再添加一件事,然后展示如何使用
git filter branch
实现这一点

这不是一个删除,而是一个新的副本:本质上,是一个新的回购协议 要了解这一点,关键是不能从一系列提交的前面或中间删除提交。原因很简单:作为其标识的一部分,每个提交都记录其父提交的标识。这方面的技术术语是提交的图形形成一个

更具体地说,如果你愿意的话,一个提交的“真名”就是它的SHA-1。SHA-1是提交中数据的加密散列。其中一条数据是
父行
行。下面是git源代码本身中的一个实际提交(减去
@
符号以阻止垃圾邮件捕获):


1“cryptographic”形容词的含义是,您不能简单地对提交进行轻微更改,例如,向消息中添加文本,以生成与以前相同的旧SHA-1。在计算可行的时间内做到这一点的唯一方法是破坏加密

2在不太密集的变更案例中,如果您制作了原始提交的精确副本,您将得到与以前相同的SHA-1。例如,如果您有一个过滤器分支操作,该操作删除链中第二个tip most提交,则只有tip most提交获得一个新的SHA-1。不过,在这种特殊情况下,我们建议删除根提交,这必然会对每个后续提交重新编号


3要复制的提交从作为筛选器分支操作一部分提供的-style参数中获取。要重写的分支名称也取自此处,使用“积极引用”。

正如一些人已经说过的,这很少是一个好主意,有几个原因我将不再重复。不过,我想再添加一件事,然后展示如何使用
git filter branch
实现这一点

这不是一个删除,而是一个新的副本:本质上,是一个新的回购协议 要了解这一点,关键是不能从一系列提交的前面或中间删除提交。原因很简单:作为其标识的一部分,每个提交都记录其父提交的标识。这方面的技术术语是提交的图形形成一个

更具体地说,如果你愿意的话,一个提交的“真名”就是它的SHA-1。SHA-1是提交中数据的加密散列。其中一条数据是
父行
行。下面是git源代码本身中的一个实际提交(减去
@
符号以阻止垃圾邮件捕获):


1“cryptographic”形容词的含义是,您不能简单地对提交进行轻微更改,例如,向消息中添加文本,以生成与以前相同的旧SHA-1。在计算可行的时间内做到这一点的唯一方法是破坏加密

2在不太密集的变更案例中,如果您制作了原始提交的精确副本,您将得到与以前相同的SHA-1。例如,如果您有一个过滤器分支操作,该操作删除链中第二个tip most提交,则只有tip most提交获得一个新的SHA-1。不过,在这种特殊情况下,我们建议删除根提交,这必然会对每个后续提交重新编号


3要复制的提交从作为筛选器分支操作一部分提供的-style参数中获取。要重写的分支名称也取自此处,使用“肯定引用”。

首先,我真的很想这样做。第二,你能更精细一些,按顺序给我一些命令吗?这些命令非常危险,如果使用不当,可能会炸毁你的存储库。正确的命令取决于您的具体情况。请尝试
git-help-rebase
git-help-filter-branch
获取文档或使用您选择的搜索引擎查找示例。但要确保你知道自己在做什么你已经被警告了。我很高兴你强烈警告@Scooby不要这样做。我会更进一步:如果有人在这个存储库上工作,我强烈建议不要这样做。你会为他们做更多的工作。根据历史记录以及他们是否在积极编写代码,这可能是一项非常痛苦的手工工作。这样做很容易失去提交者
tree 55c0d854767f92185f0399ec0b72062374f9ff12
parent 8413a79e67177d026d2d8e1ac66451b80bb25d62
author Junio C Hamano <gitster pobox.com> 1436563740 -0700
committer Junio C Hamano <gitster pobox.com> 1436563740 -0700

The last minute bits of fixes

Signed-off-by: Junio C Hamano <gitster pobox.com>
export STARTCOMMIT=.....

git filter-branch --tag-name-filter cat \
   --commit-filter '
     git merge-base --is-ancestor ${STARTCOMMIT} ${GIT_COMMIT};
     if [ $? -eq 1 ]; 
     then
        skip_commit "$@";
     else
        git commit-tree "$@";
     fi' \
   -- --all

# remove original references
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
# reduce repo size
git reflog expire --expire=now --all && git gc --aggressive --prune=all