如何删除旧的 git 历史记录?
How to delete the old git history?
我有 git 个包含很多很多(2000+)次提交的存储库,例如:
l-- m -- n
/
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
\
x -- y -- z
并且我想截断旧的日志历史记录 - 从日志历史记录中删除所有提交(例如)提交 "f" 但作为存储库的开头。
怎么做?
为了不丢失一些历史;最好先复制您的存储库 :)。我们开始:(<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
如果您有一个遥控器,您希望在其中拥有相同的 t运行 分类历史记录;你可以使用 git push -f
。 警告这是一个危险的命令;不要轻易使用它!如果您想确保您的代码的上一个版本仍然相同;你可以 运行 git diff origin/master
。这应该不会显示任何变化(因为只有历史发生了变化;而不是文件的内容)。
git push -f
以下 2 个命令是可选的 - 它们使您的 git 存储库保持良好状态。
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
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
选项为您的问题提供了可能的解决方案。
第二个选项(--depth
)只克隆指定的分支。如果您需要额外的分支,您可以将原始仓库添加为远程并使用 git fetch
并检索它们。
当您对结果感到满意时,删除旧存储库并重命名新存储库以替换它。如果旧存储库是远程的,那么 re-create 删除后将其从新存储库推送到其中。
这种方法具有大小和速度的优势。新的 repo 只包含你想要的提交,不需要 运行 git prune
或 git gc
来删除旧对象(因为它们不存在)。
对于那些与 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
来源:https://github.com/adrienthebo/git-tools/blob/master/git-truncate
说明:
- 将上面的脚本保存到本地存储库根目录(可能是
git-truncate.sh
)。
- 检查您要截断的分支(可能
master
)。
- 查看历史并找到您要切断的第一个(最新)提交 SHA(假设它是
2c75a32
)并确保该提交没有并行分支!
- 运行 像这样:
$ ./git-truncate.sh 2c75a32 master
.
- (推力,如果存在任何遥控器。)
重要提示:SHA 必须是分支的 "part",并且它必须是您要删除的第一个提交。不要通过您要保留的第一个提交(新的 "beginning of repository" 提交)!
我有 git 个包含很多很多(2000+)次提交的存储库,例如:
l-- m -- n
/
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
\
x -- y -- z
并且我想截断旧的日志历史记录 - 从日志历史记录中删除所有提交(例如)提交 "f" 但作为存储库的开头。
怎么做?
为了不丢失一些历史;最好先复制您的存储库 :)。我们开始:(<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
如果您有一个遥控器,您希望在其中拥有相同的 t运行 分类历史记录;你可以使用 git push -f
。 警告这是一个危险的命令;不要轻易使用它!如果您想确保您的代码的上一个版本仍然相同;你可以 运行 git diff origin/master
。这应该不会显示任何变化(因为只有历史发生了变化;而不是文件的内容)。
git push -f
以下 2 个命令是可选的 - 它们使您的 git 存储库保持良好状态。
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
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
选项为您的问题提供了可能的解决方案。
第二个选项(--depth
)只克隆指定的分支。如果您需要额外的分支,您可以将原始仓库添加为远程并使用 git fetch
并检索它们。
当您对结果感到满意时,删除旧存储库并重命名新存储库以替换它。如果旧存储库是远程的,那么 re-create 删除后将其从新存储库推送到其中。
这种方法具有大小和速度的优势。新的 repo 只包含你想要的提交,不需要 运行 git prune
或 git gc
来删除旧对象(因为它们不存在)。
对于那些与 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
来源:https://github.com/adrienthebo/git-tools/blob/master/git-truncate
说明:
- 将上面的脚本保存到本地存储库根目录(可能是
git-truncate.sh
)。 - 检查您要截断的分支(可能
master
)。 - 查看历史并找到您要切断的第一个(最新)提交 SHA(假设它是
2c75a32
)并确保该提交没有并行分支! - 运行 像这样:
$ ./git-truncate.sh 2c75a32 master
. - (推力,如果存在任何遥控器。)
重要提示:SHA 必须是分支的 "part",并且它必须是您要删除的第一个提交。不要通过您要保留的第一个提交(新的 "beginning of repository" 提交)!