如何删除旧的 git 历史记录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41953300/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to delete the old git history?
提问by Nips
I have git repository with many, many (2000+) commits, for example:
我有很多很多(2000+)次提交的 git 存储库,例如:
l-- m -- n
/
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
\
x -- y -- z
and I want to truncate old log history - delete all commits from log history starting from (for example) commit "f" but as the beginning of repository.
并且我想截断旧的日志历史记录 - 从(例如)提交“f”开始的日志历史记录中删除所有提交,但作为存储库的开始。
How to do it?
怎么做?
回答by Chris Maes
In order not to lose some history; better first take a copy of your repository :). Here we go: (<f>
is the sha of the commit f that you want to be the new root commit)
为了不丢失一些历史;最好先复制您的存储库:)。我们开始:(<f>
是您希望成为新根提交的提交 f 的 sha)
git checkout --orphan temp <f> # checkout to the status of the git repo at commit f; creating a branch named "temp"
git commit -m "new root commit" # create a new commit that is to be the new root commit
git rebase --onto temp <f> master # now rebase the part of history from <f> to master onthe temp branch
git branch -D temp # we don't need the temp branch anymore
If you have a remote where you want to have the same truncated history; you can use git push -f
. Warningthis is a dangerous command; don't use this lightly! If you want to be sure that your last version of the code is still the same; you can run git diff origin/master
. That should show no changes (since only the history changed; not the content of your files).
如果你有一个遥控器,你想拥有相同的截断历史;你可以使用git push -f
. 警告这是一个危险的命令;不要轻易使用这个!如果您想确保您的上一个版本的代码仍然相同;你可以跑git diff origin/master
。这应该不会显示任何更改(因为只有历史更改;而不是文件的内容)。
git push -f
The following 2 commands are optional - they keep your git repo in good shape.
以下 2 个命令是可选的 - 它们使您的 git repo 保持良好状态。
git prune --progress # delete all the objects w/o references
git gc --aggressive # aggressively collect garbage; may take a lot of time on large repos
回答by axiac
A possible solution for your problem is provided by git clone
using the --shallow-since
option. If there is only a small number of commits since f
and there is no trouble counting them then you can use the --depth
option.
git clone
使用该--shallow-since
选项为您的问题提供了可能的解决方案。如果此后只有少量提交f
并且计算它们没有问题,那么您可以使用该--depth
选项。
The second option (--depth
) clones only the specified branch. If you need additional branches you can then add the original repo as a remote and use git fetch
and to retrieve them.
第二个选项 ( --depth
) 仅克隆指定的分支。如果您需要其他分支,则可以将原始存储库添加为远程并使用git fetch
和检索它们。
When you are pleased with the result, remove the old repository and rename the new one to replace it. If the old repository is remote then re-create it after removal and push from the new repo into it.
当您对结果感到满意时,删除旧存储库并重命名新存储库以替换它。如果旧存储库是远程的,则在删除后重新创建它并从新存储库推送到它。
This approach has the advantage of size and speed. The new repo contains only the commits you want and there is no need to run git prune
or git gc
to remove the old objects (because they are not there).
这种方法具有规模和速度的优势。新的 repo 只包含你想要的提交,不需要运行git prune
或git gc
删除旧对象(因为它们不存在)。
回答by Marcel
For those who get alot of merge conflicts (and broken results) with rebase --onto
I'd like recommend this script which uses git filter-branch
:
对于那些遇到很多合并冲突(和破坏结果)的人,rebase --onto
我想推荐这个脚本,它使用git filter-branch
:
#!/bin/sh
cut_sha=""
branch=""
git filter-branch \
--parent-filter "sed -e 's/-p $cut_sha[0-9a-f]*//'" \
--prune-empty \
-- $branch
git for-each-ref --format='%(refname)' refs/original | \
while read ref
do
git update-ref -d "$ref"
done
git reflog expire --expire=0 --all
git repack -ad
git prune
Source: https://github.com/adrienthebo/git-tools/blob/master/git-truncate
来源:https: //github.com/adrienthebo/git-tools/blob/master/git-truncate
Instructions:
指示:
- Save the script above to local repository root (maybe as
git-truncate.sh
). - Check out the branch you'd like to truncate (maybe
master
). - Go down history and find the first (newest) commit SHA you want to cut off (assume it's
2c75a32
) AND ensure the commit has no branches in parallel! - Run it like this:
$ ./git-truncate.sh 2c75a32 master
. - (Push force, if any remote is present.)
- 将上面的脚本保存到本地存储库根目录(可能是
git-truncate.sh
)。 - 查看您要截断的分支(也许
master
)。 - 查找历史记录并找到您想要切断的第一个(最新)提交 SHA(假设它是
2c75a32
)并确保提交没有并行分支! - 像这样运行它:
$ ./git-truncate.sh 2c75a32 master
。 - (推力,如果有任何遥控器。)
IMPORTANT: The SHA must be "part" of the branch and it must be the first commit you want to delete. Don't pass the first commit you want to keep (the new "beginning of repository" commit)!
重要提示:SHA 必须是分支的“一部分”,并且必须是您要删除的第一个提交。不要传递您要保留的第一个提交(新的“存储库开始”提交)!