DebugEN
科技森
专注于Java开发~每天都会更新文章~
  1. 首页
  2. Java
  3. 正文

[原创] 如何从 Git 的提交历史记录中删除大文件

2021年12月01日 1005点热度 0人点赞 0条评论 作者: kejisen

1. 概述

在本教程中,我们将学习如何使用各种工具从 git 存储库的提交历史记录中删除大文件。

2. 使用*git filter-branch*

这是最常用的方法,它可以帮助我们重写提交分支的历史记录。

例如,假设我们错误地将一个 blob 文件放入项目文件夹中,删除它后,我们仍然会在 git 历史记录中注意到该文件:

$ git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"
* 9e87646        (HEAD -> master) blob file removed
* 2583677        blob file
* 34ea256        my first commit

我们可以通过使用以下命令重写树及其内容来从 git 历史记录中删除 blob 文件:

$ git filter-branch --tree-filter 'rm -f blob.txt' HEAD

在这里,rm选项从树中删除文件。此外,如果我们项目中的其他提交目录中不存在该文件,则-f 选项可防止命令失败。如果没有-f 选项,当我们的项目中有多个目录时,该命令可能会失败。

这是我们运行命令后的 git 日志:

* 8f39d86        (HEAD -> master) blob file removed
* e99a81d        blob file
| * 9e87646      (refs/original/refs/heads/master) blob file removed
| * 2583677      blob file
|/  
* 34ea256        my first commit

我们可以用提交历史的 SHA1 密钥替换 HEAD,以尽量减少重写。

我们的 git log 仍然包含对已删除文件的引用。我们可以通过更新我们的 repo 来删除引用:

$ git update-ref -d refs/original/refs/heads/master

该-d选项验证它仍包含旧值后,删除指定的裁判。

我们需要在存储库中记录我们的引用更改:

$ git reflog expire --expire=now --all

在到期子李子年长参考日志条目。

最后,我们需要清理和优化我们的 repo:

$ git gc --prune=now

该-prune =现在选择梅干不论其年龄的散装物品。

运行命令后,这是我们的 git 日志:

* 6f49d86        (HEAD -> master) my first commit

我们可以看到 refs 已被删除。

或者,我们可以运行:

$ git filter-branch --index filter 'git rm --cached --ignore-unmatched blob.txt' HEAD

这与tree-filter完全一样 ,但它更快,因为它只重写索引,即工作目录。如果文件从我们项目中的其他提交目录中丢失,子命令–ignore-unmatched可防止命令失败。

我们应该注意,在删除大文件时,这种使用两个不同命令的方法可能会很慢。

3. 使用*git-filter-repo*

另一种方法是使用git-filter-repo命令。它是第三方附加组件,使用起来更简单,而且比其他方法更快。而且是git官方文档中推荐的方案。

3.1. 安装

它至少需要 python3 >= 3.5 和 git >= 2.22.0;某些功能需要 git 2.24.0 或更高版本。

我们将在我们的 Linux 机器上安装git-filter-repo。对于 Windows 安装指南,我们可以参考文档。

首先,我们将使用以下命令安装python-pip和git-filter-repo:

$ sudo apt install python3-pip
$ pip install --user git-filter-repo

或者,我们可以使用以下命令安装git-filter-repo:

# Add to bashrc.
export PATH="${HOME}/bin:${PATH}"

mkdir -p ~/bin
wget -O ~/bin/git-filter-repo https://raw.githubusercontent.com/newren/git-filter-repo/7b3e714b94a6e5b9f478cb981c7f560ef3f36506/git-filter-repo
chmod +x ~/bin/git-filter-repo

3.2. 删除文件

让我们运行命令来检查我们的 git 日志:

$ git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"
* ee36517        (HEAD -> master) blob.txt removed
* a480073        project folder

接下来我们要分析我们的 repo:

$ git filter-repo --analyze
Processed 5 blob sizes
Processed 2 commits
Writing reports to .git/filter-repo/analysis...done.

这将生成我们的回购状态报告目录。该报告可以在 .git/filter-repo/analysis 找到。这些信息可能有助于确定在后续运行中要过滤的内容。它还可以帮助我们确定我们之前的过滤命令是否真的做了我们想要它做的事情。

然后,让我们使用选项–path-match运行此命令,这有助于指定要包含在过滤历史记录中的文件:

$ git filter-repo --force --invert-paths --path-match blob.txt

这是我们的新 git 日志:

* 8940776        (HEAD -> master) project folder

执行后,它将更改修改后的提交的提交哈希。

4. 使用 BRG Repo-Cleaner

另一个不错的选择是BRG Repo-Cleaner,它是用 Java 编写的第三方插件。

它比*git filter-branch*方法更快。此外,它适用于删除大文件、密码、凭据和其他私人数据。

假设我们要删除大于 200MB 的 blob 文件。这个插件可以很容易地做到这一点:

$ java -jar bfg.jar --strip-blob-bigger-than 200M my-repo.git

然后,让我们运行这个命令来清理死数据:

$ git gc --prune=now --aggressive

5. 使用*git-rebase*

我们需要 git 日志中的 SHA1 密钥才能使用这种方法:

$ git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"
* 535f7ea        (HEAD -> master) blob file removed
* 8bffdfa        blob file
* 5bac30b        index.html

我们的目标是从我们的提交历史中删除 blob 文件。因此,我们将使用要删除的条目之前条目历史记录中的 SHA1 密钥。

使用此命令,我们进入交互式变基:

$ git rebase -i 5bac30b

这将打开我们的nano编辑器,显示:

pick 535f7ea blob file removed
pick 8bffdfa blob file 

# Rebase 5bac30b..535f7ea onto 535f7ea (2 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .  create a merge commit using the original merge commit's
# .  message (or the oneline, if no original merge commit was
# .  specified). Use -c <commit> to reword the commit message.

现在,我们将通过删除文本“ pick 535f7ea blob file removed ”来修改它。这有助于我们更改提交历史并删除我们之前删除的历史。

然后我们保存文件并退出编辑器,它会将我们带到终端并显示以下消息:

interactive rebase in progress; onto 535f7ea
Last command done (1 command done):
pick 535f7ea blob file removed
No commands remaining.
You are currently rebasing branch 'master' on '535f7ea'.
(all conflicts fixed: run "git rebase --continue")

最后,让我们继续 rebase 操作:

$ git rebase --continue
Successfully rebased and updated refs/heads/master.

然后我们可以验证我们的提交历史:

$ git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"
* 5bac30b        (HEAD -> master) index.html

我们应该注意到这种方法不如*git-filter-repo***快**。

六,结论

在本文中,我们学习了从 git 存储库的提交历史记录中删除大文件的不同方法。我们还看到,根据 git 文档,推荐使用git filter-repo,因为与其他方法相比,它速度快且缺点更少。

标签: git
最后更新:2021年12月29日

kejisen

保持饥渴的专注,追求最佳的品质

点赞
< 上一篇
下一篇 >

文章评论

取消回复
最新 热点 随机
最新 热点 随机
【原创】记录一次失败的折腾——使用jkeymaster实现的按键监听 【原创】这些年我用过的IDEA插件 【原创】在windows上使用VNC远程连接linux桌面 我在RxJava使用线程池时遇到的问题 [原创文章] Swagger生成pdf格式的接口文档 [个人翻译]Java HTTP工具类的客户端证书认证 [原创] 如何从 Git 的提交历史记录中删除大文件 [翻译] 创建一个只读的Repository接口(Spring Data) [翻译] 反射的用法——用Java调用私有方法 Java 虚拟机最多可以支持多少个线程? 排查Hibernate的慢查询日志–这是查找慢查询的最简单方法 [翻译] 使用apache poi在excel文件中插入一行数据 [翻译] 在Spring 中@EntityScan与@ComponentScan注解有什么区别 [原创] 从QQ音乐网页版扒歌词的补充说明 [原创] 介绍java maven项目的多种打包方式 原创——在Java中生成随机数 将G1垃圾回收的内存使用量减少20%(翻译) [原创] java8 lambda表达式的toMap造成的空指针异常 [原创] 在Spring Boot中使用CommandLineRunner来在启动时执行代码 [转载] Kafka 节点重启失败导致数据丢失的分析排查与解决之道
从QQ音乐获取并解析音乐的歌词 [翻译] 使用apache poi在excel文件中插入一行数据 java maven项目的几种打包方式 [原创]javaslang(vavr.io)中Try的使用 [原创] 在ubuntu18.04上安装chromedriver [原创] 如何从 Git 的提交历史记录中删除大文件 Spring Boot的@RequestMapping注解中加斜杠与不加斜杠的区别 [转载] Kafka 节点重启失败导致数据丢失的分析排查与解决之道 [原创] java8 lambda表达式的toMap造成的空指针异常 [原创文章] Swagger生成pdf格式的接口文档 使用Spring RestTemplate压缩请求 【原创】这些年我用过的IDEA插件 【原创】在windows上使用VNC远程连接linux桌面 [原创] 如何使用okhttp发起application/json类型的请求 Linux截图软件推荐-flameshot [原创] 从QQ音乐网页版扒歌词的补充说明 [原创] 介绍java maven项目的多种打包方式 在Java中生成随机的日期 如何设置Servlet的session超时时间 排查Hibernate的慢查询日志–这是查找慢查询的最简单方法
标签聚合
java qq音乐 歌词 linux maven json elasticsearch base64 springboot spring

COPYRIGHT © 2020 Kejisen. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS