git管理大项目或者大文件
git 是追踪代码库演进的最佳选择,并且它能让你与你的同事间高效协作。当你想要追踪的库非常巨大时会发生什么?
在这篇文章里,我会尝试着给你一些想法和技巧来恰当地处理不同种类的大仓库。
两种大代码库
如果仔细想想,大概会有两种导致仓库大规模增长的原因:
项目累积了非常长的历史(项目成长了很长一段时间并且积累了包袱)。
项目包括了巨大的二进制资产,需要与代码一起跟踪配对。
两者皆有。
因此,仓库的增长有两个维度的方向:工作目录的尺寸——例如:最近一次提交,和整个累积历史的尺寸。
有时第二种问题会与老的过时的二进制生成的东西(artifact)混合,它们都被放在仓库中,不过这类问题是比较容易处理的——如果它们很讨厌,就覆盖它们,见下文。
上述两种场景需要的技巧和解决方案是不同的——尽管有时候需要互补——让我们分别来处理它们吧。

处理拥有大量历史记录的库
将一个库视为大规模库的界线非常高 - 比如 Linux 内核的最后一个版本记录了超过 1500 万行代码,但人们仍然愿意完整阅读 - 由于监管/规定方面的原因,某些很老的项目仍然需要保持完整,克隆它们是件痛苦的事情(现在通过拆分 Linux 库的方式使其结构清晰,它被拆分为历史库和最近时期的库,需要通过嫁接设置来访问完整的历史记录)。
浅克隆是简单的的解决办法
为了更快、更节省开发者和系统时间也更节约磁盘空间,第一个解决办法是使用 git 进行浅克隆。通过浅克隆可以只克隆某个库最后的历史记录。
怎么做到?只需要使用 --depth 选项,比如:
git clone --depth depth remote-url
想像一下,如果你的项目库中积累了 10 年甚至更长时间的历史记录 - 比如 JIRA 是我们往 git 迁移的一个 11 年的老库 - 累积节约的时间非常显著。
完整的克隆 JIRA 有 677 MB,如果包含工作目录还有另外的 320+ MB,总共超过 47,000 多次提交。通过浅克隆的方式检出 JIRE 需要 29.5 秒,而检出完整的历史记录则需要 4 分 24 秒。随着时间地推移及项目二进制资产的增长,这个差距也会成比例的增长。任何情况下,构建系统都会大大受益于这种技术(指浅克隆)。

最近 git 改善了对浅克隆的支持
过去浅克隆就像 git 世界里的残障人士一样,某些操作并未得到支持。不过最近的版本 (1.9+) 对此有着显著的改善,现在甚至可以适当的对浅克隆库使用 pull 和 push 操作。
另一个解决办法是 filter-branch (过滤分支)
巨大的库往往存在着大量错误的提交或无用的资源,对此,使用 filter-branch 是个很好的解决办法。这个命令可以根据预先定义的模式对项目历史进行过滤、整理、修改,甚至跳过一些文件。它是 git 工具集中的一个非常强大的工具。目前已经有脚本可以用于识别 git 库中的大型对象,所以它使用起来非常容易。
使用 filter-branch 的示例:
git filter-branch --tree-filter 'rm -rf /path/to/spurious/asset/folder' HEAD
filter-branch 有一个小小的缺点:一旦使用了 filter-branch,实际上已经重写了整个项目历史,因此每次提交的 ID 都会发生变化。这要求每个开发者都要重新克隆更新后的库。
所以,如果你打算使用 filter-branch 来进行一次清理行动,应该警告你的团队,计划一个短期的冻结来进行操作,然后通知大家重新克隆库。

浅克隆的替代者:只克隆一个分支
从 2012 年 4 月发布的 git 1.7.10 开始,你可以通过只克隆某一个分支来限制历史记录的数量,就像这样:
git clone URL --branch branch_name --single-branch [folder]
对于长期运行分发的分支,或者你在有很多分支的情况下,这个特殊的技巧都非常有用。如果你只有极少数分支,那这个办法不会带来显著的效果。
Stack Overflow 参考。
处理拥有巨大二进制资产的库
第二类大型仓库中的代码含有巨大的二进制资产。游戏团队要处理巨大的 3D 模型,Web 开发团队需要跟踪图像资产,CAD 团队可能需要操作和跟踪二进制交付物的状态。所以有各种不同的软件团队在使用 git 的过程中会遇到这样的问题。
git 在处理二进制资产的时候并不是特别差劲,但它也不会干得特别好。默认情况下,git 会完整压缩存储二进制资产的所有后续版本,如果你有很多二进制资产的情况下,这显然不是最佳方案。
可以通过一些基本的调整来改善情况,比如运行垃圾回收 git gc,或者在 .gitattributes 中对部分二进制类型进行调整,以使用 delta 方式的提交。

不过有一点很重要,对项目中不同性质的二进制资产可能需要不同的方法。例如,这里需要检查三个方面(感谢 Stefan Saasen 的评论):
对于变化显著的二进制文件 - 这是指不仅只有元数据头变化 - 这时增量压缩可能没什么作用,建议对这些文件关闭 delta 选项,以避免不必要的增量压缩并重新打包
对于上述情形,就像某些文件通过 zlib 压缩并不会有多好的效果,你使用 core.compression 0 或 core.loosecompression 0 来关闭压缩功能一样;这是一个全局设置,它会对其它压缩效果不错的非二进制文件带来负面影响。因此建议你把二进制资产放在单独的库中。
一定要记住 git gc 将“重复的”松散的对象变成一个单独的包文件,除非以任何方式压缩文件都不会使生成的包文件有显著差异。
探索调整 core.bigFileThreshold 带来的效果。任何大于 512 MiB 都不会采用 delta 压缩 - 如果没有设置 .gitattributes 的话 - 所以这样的调整值得一试。

技巧1: 稀疏检出
一个温和的管理二进制资产问题的方法是稀疏检出(从 Git 1.7.0 之后可用)。我们可以通过显式地详细说明要填充的文件夹来保持工作目录的清洁。 不幸的是,它并不能影响整个本地存储库的大小,但如果你有一个巨大的树形文件夹,这可能是有用的。
涉及到哪些命令呢? 示例如下(credit):
仅克隆全部存储库一次::git clone <repository-address>
激活以下功能:git config core.sparsecheckout true
添加那些需要显式依赖的文件夹,忽略 assets 文件夹:
echo src/ ? .git/info/sparse-checkout
读取指定的树目录:git read-tree -m -u HEAD
之后,你可以使用正常的 git 命令了,但你的工作目录将只包含你指定的文件夹。

技巧2:使用子模块
还有另一种处理二进制资产目录的的方法,就是把它们拆分到一个单独的库,然后在主项目是通过把它拉取为子模块。使用这种方法你可以控制资产的更新。需要了解子模块,可以看看:核心概念与技巧和另一个选择。
如果你想继续使用子模块的方法,你可能需要检查项目依赖的复杂性。我提到的方法对解决大型二进制文件问题会有所帮助。
技巧3:使用 git-annex 或 git-bigfiles
git 中处理二进制资产的第3个选择依靠第三方扩展。
我要说的第一个扩展是 git-annex,它可以使用 git 管理二进制文件,但不需要把文件内容检入库中。git-annex 使用一个特殊的键值库来保存文件,然后将符号链接像普通文件一样检入 git 库中进行版本管理。这种用法非常直接,还有一看就能明白的例子。
第二个扩展是 git-bigfiles,一个 git 分支,适合于使用 git 分享项目大文件的人。
相关文章:

window下java开发环境安装
首先请去Java的官网上下载,最好下载最新版本地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 如图,点击下载java platform(JDK),然后选择接受接受协议(Accept …
【ACM】蛇形填数
先判断,再移动,而不是发现越界了再退回来。 #include "stdio.h" #include "string.h" #define maxn 20 int a[maxn][maxn]; int main() {int n, x, y, tot 0;scanf_s("%d", &n);memset(a, 0, sizeof(a));tot a[x …

Mybatis中Oracle和Mysql的Count字段问题
Mybatis中Oracle和Mysql的Count字段问题 我们在进行项目开发时经常会碰到查询总数的问题,所以我们直接是用select count(1) from table来进行查询。那么在Mybatis通常情况下我们是这么写的 <select id"testCount" resultType"int">select…

为什么free()时不需要传指针大小
malloc()和free()是c中两个非常基本的函数,但这种最基本的东西往往都是特别复杂的。malloc和free的原形如下:void *malloc(unsigned int num_bytes); void free(void *ptr);在c的标准中并没有定义这两个函数的具体实现,在我们最常用的gcc中&a…

redis cluster 安装配置
一、redis集群安装配置1、下载redis源码包并下载wget http://download.redis.io/releases/redis-3.0.7.tar.gz $ tar xzf redis-3.0.7.tar.gz $ cd redis-3.0.7 yum -y install gcc gcc-c libstdc-devel #解决相关依赖关系$ make && make install 因我们安装redis 集…

【ACM】汉诺塔
https://blog.csdn.net/xueerfei008/article/details/9904681

什么是机器人底盘 答案在这里!
机器人底盘承载了机器人本身的定位、导航及避障等基本功能,可帮助机器人实现智能行走,以思岚科技的ZEUS为例,内置SLAMWARE高性能自主定位导航模块,用户可根据实际需要搭载不同的应用,可广泛适用于餐厅、商场、银行、办…

嵌入式linux内存使用和性能优化
这本书有两个关切点:系统内存(用户层)和性能优化。 这本书和Brendan Gregg的《Systems Performance》相比,无论是技术层次还是更高的理论都有较大差距。但是这不影响,快速花点时间简单过一遍。 然后在对《Systems Performance》进行详细的学…

【算法导论】插入排序
循环不变式 在数学上阐述了通过循环(迭代,递归)去计算一个累计的目标值的正确性。 关于循环不变式,我们必须要证明三条性质: 初始化:循环第一次迭代之前,它为真。保持:如果循环的…

gdb+gdbserver
内容摘要 远程调试环境由宿主机GDB和目标机调试stub共同构成,两者通过串口或TCP连接。使用 GDB标准程串行协议协同工作,实现对目标机上的系统内核和上层应用的监控和调试功能。调试stub是嵌入式系统中的一段代码,作为宿主机GDB和目标机调试程…

Android开发技巧——去掉TextView中autolink的下划线
我们知道,在布局文件中设置textview的autolink及其类型,这时textivew上会显示link的颜色,并且文字下面会有一条下划线,表示可以点击。而在我们在点击textview时,应用将根据我们所设置的类型跳转到对应的界面。但是有时…

【算法导论】冒泡排序 选择排序
冒泡排序: //从大到小 void bubble_sort(int array[],int len) {int i,j,t;for(i0;i<len-1;i){for(j0;j<len-1-i;j){if(array[j]<array[j1]){tarray[j];array[j]array[j1];array[j1]t;} }} } 选择排序: //从大到小 void select_sort(int a…

监控平台zabbix高级配置
2019独角兽企业重金招聘Python工程师标准>>> 12月26日任务 19.12 添加自定义监控项目 19.13/19.14 配置邮件告警 19.15 测试告警 19.16 不发邮件的问题处理 添加自定义监控项目 zabbix可以自定义监控项目,满足个性化的需求。例如网站注册量、访问量等具体…

linux内存实际占用分析
作者: 黄永兵/译 出处:51CTO.com 阅读提示:本文是为那些经常疑惑的人准备的,“为什么一个简单的KDE文本编辑器要占用25M内存?”导致大多数人认为许多Linux应用程序,特别是KDE或GNOME程序都象ps报告一样臃肿...【51CTO.com独家译文…

CentOS 6.5 下Vim 配置图解
分享个CentOS 6.5 下Vim 配置图文详解,希望对大家有所帮助。 1. 登录并进入你常用的用户名下,查看其主目录 命令: # su xxx $ cd xxx $ ls -a 2.查看并建立目录和文件 首先看你的主目录~/ 下是否有.vimrc文件,没有就输入指令 $ to…
【ACM】杭电OJ 1106 函数atoi
函数atoi是把字符串转化成整数的函数,头文件为 #include "stdlib.h" e.g. 运行环境:Dev-C 5.11 杭电1106 调用了sort函数,运行的时间相对长一些。 #include "stdio.h" #include "string.h" #include "…

docker-dockerfile
docker文件存储驱动dockerfile镜像构建指令示例dockekr镜像是只读的,对容器修改的内容,一旦容器退出,所有的内容将会丢失。镜像是分层的,最上的一层为读写层(写时复制和用时分配) 文件系统存储驱动…

proc/[pid]/maps 文件解释
proc/[pid]/maps 文件解释 查看进程的虚拟地址空间是如何使用的。 该文件有6列,分别为: 地址:库在进程里地址范围 权限:虚拟内存的权限,r读,w写,x,s共享,p私有; 偏移量:库在进程里…

【ACM】UVa 1339
【题目】:给定两个长度相同且不超过100的字符串,判断是否能把其中一个字符串的各个字母重排,然后对26个字母做一一映射,使得两个字符串相同。输入两个字符串,输出“YES”或者“NO”。 【分析】:既然字母可…

springBoot PUT请求接收不了参数的解决办法
2019独角兽企业重金招聘Python工程师标准>>> 做项目的时候,想把接口写标准点,于是在更新内容的时候采用put提交内容,但是提交内容时总是获取不到参数,总是选择参数为null。 首先贴出我的put的方法控制器的代码 和之前的…

七牛云内容审核服务被选为「上海首批人工智能创新产品」
近日,上海人工智能应用场景建设实施计划正式发布,这是全国首次面向人工智能应用场景需求的征集计划。上海 10 大人工智能应用场景、19 个具体点位需求和 60 个人工智能创新产品集中首发,其中,上海七牛信息技术有限公司(…

linux动态库命名规则
说道“动态库版本兼容”,很多人头脑中首先蹦出的就是“Dll Hell”。啊,这曾经让人头疼的难题。时至今日,这个难题已经很好地解决了。 在进一步讨论之前来思考一个问题:Linux下为什么没有让人头痛的“DllHell”? 回答…

如何在同一系统里同时启动多个Tomcat
需要在同一系统里启动多个tomcat,应该怎么处理? tomcat是个服务程序,需要占用几个通讯端口,所以默认情况是不能启动多个tomcat,如果要启动多个tomcat,需要修改配置文件,通过在配置文件设置不同的通讯端口就可以做到.文件 %TOMCAT_HOME%/conf…

【ACM】Uva 455
【题目】:如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串以k为周期。输入一个长度不超过80的字符串,输出其最小正周期。 注意以下几点: 1、它的最小正周期一定可以被它的长度整除。 2第一个大循环下 i 可以等于…

前端自动化构建工具webpack (二)之css和插件加载总结
1. webpack只识别js文件,其他文件都需要转换成js文件。所有文件都是模块; 2. css解析 css需要css-loader ---》style-loader -----》less-loader less文件还需要less-loader (注意书写顺序) 3. plugins:他是一个数组&#…

使用command对象操作数据库
1.Command对象查询数据库 protected void Button1_Click(object sender, EventArgs e){//读取web.config节点配置string strcon ConfigurationManager.ConnectionStrings["testjm"].ConnectionString;//实例化sqlConnection对象SqlConnection con new SqlConnectio…

浅析C语言之uint8_t / uint16_t / uint32_t /uint64_t
一、C语言基本数据类型回顾 在C语言中有6种基本数据类型:short、int、long、float、double、char 1、数值类型 1)整型:short、int、long 2)浮点型:float、double 2、字符类型:char 二、typedef回顾 …

【ACM】UVa 489 刽子手游戏(自顶向下)
【题目】 Hangman Judge是一个猜英文单字的小游戏(在电子字典中常会看到),游戏规则如下: 1、答案单字写在纸上(每个字元一张纸),并且被盖起来,玩家每次猜一个英文字元(le…

ssh远程执行多个命令
shell远程执行: 经常需要远程到其他节点上执行一些shell命令,如果分别ssh到每台主机上再去执行很麻烦,因此能有个集中管理的方式就好了。一下介绍两种shell命令远程执行的方法。 前提条件: 配置ssh免密码登陆 对于简单的命令&am…