如何批量删除一些很久之前的提交记录,但保留那些修改的内容。
这个问题有一点 A/B,因为你没有说明删除很久之前的提交记录的场景是什么,这很重要因为会影响到接下来 Git 的使用选择。举例来说:
git rebase -i <ref>
git rebase --onto <ONTO_BASE_ref> <START_ref> <END_ref>
START
END
ONTO_BASE
git checkout --orphan new_start
new_start
HEAD
git replace
其实还有很多种场景可以说道,Git 的用法非常灵活,即使暂时用不到也值得细细过一遍知道它能做什么样的事情,然后遇到各种复杂的场景就可以自己推导出解决方案了。
作为 Repo 的维护者,最常见的事情就是从某一 ref 开始到 HEAD保留下来,然后之前的历史删除。因为这个任务比较常见,所以这里也有一个 shell script 分享给你:
sh#!/bin/bash git checkout --orphan temp git commit -m "截取的历史记录起点" git rebase --onto temp master git branch -D temp
sh
#!/bin/bash git checkout --orphan temp git commit -m "截取的历史记录起点" git rebase --onto temp master git branch -D temp
使用的时候这样(比如该脚本保存叫 git-detach): git-detach <ref>,其中 <ref> 就是你要保留的历史记录的起点。
git-detach
git-detach <ref>
<ref>
需要注意的是,这个脚本只是把历史记录“分离”开来,然后其中的一部分没有了可见的引用因此在历史记录里看不见,然而它们的 git object 仍然存在(换言之你还能恢复过来,自行查阅 git-reflog),如果你真要彻底丢掉这些历史(为了给 repo 减肥),可以用 git gc --prune,那就再也找不回来了。
git-reflog
git gc --prune
P.S. 这个脚本依赖 Orphan Branch,低版本的 Git 不支持(大概是 < v1.7.x),有替代方案自己 Google 吧。
这个问题有一点 A/B,因为你没有说明删除很久之前的提交记录的场景是什么,这很重要因为会影响到接下来 Git 的使用选择。举例来说:
1.2 如果要删除的历史记录是分散的,则可以考虑 Interactive Rebase,自行挑拣/合并等。如
git rebase -i <ref>
1.1 如果要删除的历史记录是连续的,比如说从最开始到某一刻全部都删除或者是中间一截可以删除,则可以考虑 Onto Rebase,如
git rebase --onto <ONTO_BASE_ref> <START_ref> <END_ref>
,其中START
到END
之间的是需要保留的部分,而ONTO_BASE
则是最新的基点;换言之,从ONTO_BASE
到START
之间的历史记录会被干掉。git checkout --orphan new_start
,这条命令会创建一个叫做new_start
的分支,该分支没有任何历史记录,但是所有的文件都会原封不动的存在,你可以据此开始重新提交。完成之后甚至可以把旧的分支直接废弃。另外,也可以指定新分支的起点,默认当然是从HEAD
开始了。git replace
的文档:http://git-scm.com/2010/03/17/replace.html其实还有很多种场景可以说道,Git 的用法非常灵活,即使暂时用不到也值得细细过一遍知道它能做什么样的事情,然后遇到各种复杂的场景就可以自己推导出解决方案了。
作为 Repo 的维护者,最常见的事情就是从某一 ref 开始到 HEAD保留下来,然后之前的历史删除。因为这个任务比较常见,所以这里也有一个 shell script 分享给你:
使用的时候这样(比如该脚本保存叫
git-detach
):git-detach <ref>
,其中<ref>
就是你要保留的历史记录的起点。需要注意的是,这个脚本只是把历史记录“分离”开来,然后其中的一部分没有了可见的引用因此在历史记录里看不见,然而它们的 git object 仍然存在(换言之你还能恢复过来,自行查阅
git-reflog
),如果你真要彻底丢掉这些历史(为了给 repo 减肥),可以用git gc --prune
,那就再也找不回来了。P.S. 这个脚本依赖 Orphan Branch,低版本的 Git 不支持(大概是 < v1.7.x),有替代方案自己 Google 吧。