开发者学堂课程【Git 从入门到进阶:Git 的十年变化(一)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1194/detail/18115
Git 的十年变化(一)
前言:
程序员如果问它们最好的预言是什么?
Python ,javascript ,它们平时用什么工具管代码 Git
做代码托管做code review 做版本同步的时候这就需要 Git 特别容易上手你能说出几个Git的命令?
Git commit ,Git clone ,Git status ,Git diff ,Git arechive ,Git bundle,Git pack-objects,Git pack-refs,Git gc,Git repack 。
Git的十年变化(一)
Git 年龄16岁,2005年由 Linus 创建,16岁的年纪对于其它一些版本控制软件来说可能已经到了谢幕的年纪,但是对于Git 正值当打之年,Git 项目的贡献者有2的11次方也就是2000多人。如果 Git 的贡献者是线性增长的话那每年会增加2的7次方,也就是128个新的贡献者。
在过去的两年阿里巴巴已经涌现出了5位新的 Git 贡献者,Git 项目的提交数量有2的16次方,也就是6万多个 Git 项目的代码行数包括代码和文档有2的19次方行,也就是50万行以上,通过上面这些数字我们可以计算出来每个贡献者平均贡献32个提交,每个提交平均修改8行,可见 Git 项目崇尚小提交。
这张图画的是16年以来 Git 项目,每个月的提交数量可以看出 Git 的开发势头,16年不减印证了我前面说的Git正值当打之年。
我是在10年前开始 Git 社区贡献的。2011年我写了Git权威指南这本书在2012年我向 Git 贡献了中文本地话翻译Git可以说中文了。2013年为d的贡献的交互式清理这是一个针对于 Git 的客户端的改进在2020年 我还对 Git 的服务端做出了一个重要改进,现在距离 Git 权威指南出版已经整整10年了这10年来 Git 有哪些变化我挑选了我认为最重要的10个变化。
1、条件包含(Includelf)
(1).场景:为不同的仓库提供不一样的默认设置
例如:不同目录下仓库提交使用不一样的邮箱配置(useremail)
(2).示例:
$ git config --global "includelf.gitdir:~/work-alibaba/.path" alibaba.inc
$ git config --global "includelf.gitdir:~/work-oss/.path" oss.inc
第一个变化条件包含的功能非常完美的解决了我的一个需求,,针对不同项目使用不同的邮箱配置,对于公司的项目在提交中使用公司邮箱对于外部的开源项目为了保持和之前的延续性使用。
我的个人邮箱我们知道 Git 的全局配置为所有仓库提供了相同的默认设置。那么可不可以为一部分仓库提供这样的设置,而对另外一些仓库提供另外的默认设置视力中的 Git 命令,在 Git 的全局配置中引入两段条件包含针对于不同的工作区,比如 work-alibaba 和walk杠oss 包含不同的 Git 配置文件,从而为不同录下的仓库引入不同的 Git 默认配置。
2、大仓库克隆
(1).稀疏检出:按需检出。
$ git clone --sparse ..
$ git sparse-checkout <init |add | reapply> .
(2).协议2.0:针对引用(分支等)多的仓库进行优化。
$ git config protocol.version 2
(3).部分克隆:只克隆元数据,按需获取文件内容等。
$ git clone --filter=blob:none ...
第二个变化就是大仓库克隆这是为了解决大仓库遇到的性能瓶颈,如果用户只对仓库中部分文件和目录感兴趣可以使用稀疏检出功能。虽然10年前功能就已经有了,但是 Git 通过引入新的命令,比如 git spice checkout 或者是引入新的参数如 git clonespice--sparse 使得稀疏检出更加易于使用。
协议2.0 为客户端和服务端的交互提供了新的协议支持,尤其对于包含非常多分支和 tag的仓库,消除了不必要的引用广播提升了性能,而部分克隆就是不下载文件的内容。
指克隆原数据原数据指的是仓库中的提交对象,数对象等。但并不包含提交文件本身的内容也就是 blob对象,下面示例命令它通过--filter参数提供了部分克隆功能就是说克隆出来的仓库只包含元数据需要用到的数据则按需下载。
3、多工作区
(1).场景:同一个企库:[at)。不同分支检出到不同的工作区。
(2).创建新工作区
$ gt woritee add -e tope-l _Mopel
(3).如果切换至已检出到其他工作区的分支,报错
$ gt Martih topic-t
fnal topic·l'it aimasly cheoied out am"Aopol"
(4).清理工作区通雄后,残存的Gt管理文件
$ gt wocktmt pruom
第3个变化就是多工作区很多人都可能遇到这样一个场景,就工作时经常要在不同的分支上切换有的人选择将一个仓库克隆多份缺点。是占有空间还有克隆出来的不同的工作区各自独立缺乏联系,而 girl worktree 实现了多个工作区共享同一个本地仓库不同分支检出到不同的工作区目录中。比如在一个工作区根目录执行 girl worktree 这条命令它,就会在当前目录的上级目录下面创建 topic-1子目录将新创建好 topic-1分支检出到新的工作区里面去。
如果一个分支已经剪出到独立的工作区,那么在另外的工作区切换分支就会报错比如 topic-1已经被检出到另外的工作区。那么在这个工作区里就不能够切换分支,如果一个工作区被删除那么残存的 Git 管理文件可以通过下面这条命令进行清除。
4.使用watchman提升工作区扫描效率
(1).场景:当仓库中包含数以万计的文件时,git status速度变慢
(2).安领 watchman
(3).为仓库设置core.fsmonitor参数,指定一个可执行解本
$ gtit config core.fsmonitor.git/ hooks/fsmonitor-watchman
(4).安装脚本
$ mv .git/hooks/fsmonitor-watchman.sample .git/hooks/fsmonitor-watchman
第四个改变就是使用 what man来提高工作区扫描效率一个仓库的工作区,包含数以万计的文件的时候执行Git status命令就会变得非常缓慢,这是因为Git要逐一扫描工作区文件的状态。它的复杂度是o(n)解决方案是使用 watchman开源工具利用文件系统的变更。
通知而非逐一扫描文件来感知文件变化,从而提升性能它的使用方法就是。首先我们要安装 watchman要为仓库来配置core.fsmonitor 参数,为其指定一个可执行的脚本脚本是从哪里获取实际上在 Git 的,钩子目录中就有一个可用的脚本只需要做一下重命名就可以。
5、.beckout 命令拆分为两条新命令厂switch 和restoro,群低复杂的chedoout 命令的学习成本
(1).创建并切换到新分支
$ git switch -c new-branch
(2).将文件在暂存区中的版本检出到工作区
$ git restore --fle..
(3).将文件在指定提交中的版本检出到工作区
$ git restore -s v2.0.0 -- file..
第5个变化新用户会感觉到checkoutd的 命令学习成本比较高。这是因为命令承载了太多的功能Git社区提供的方案是将git checkout 的命令拆分成了两个独立的新命令 git switch 和 git restore。git switch 命令提供切换分支的操作git restore 提供文件检出操作。
6、git-clean --interactive:采用交互式操作,清理本地未跟踪文件
(1).故事:一个网友问我如何找回“git clean -f”误删除的文件。
(2).交互式清理本地未跟踪的文件和目录
$ git clean -i -d
(3).交互式清理本地未跟踪的件和目录,含忽略的文件
$ git clean -idx
(4).关于交互式操作,查看帮助中INTERACTIVE MODE小节内容
$ git help clean
第6个变化就是交互式 Git -clean。Git- clean 是用来清理工作区未添加到仓库中的文件,这些文件有的是临时文件有的是忘了添加到仓库中的文件。在2013年之前我们一般是这么样使用git-clean的,先执行git clean-n来查看有哪些文件需要删除执行 git-clean -f来执行删除命令。
2013年的一天有一个网友给我发求助信息它执行了git cling-f误删了重要的文件问我怎么办后来我就给 gay 的社区贡献了git clean-i交互式清理程序它提供了一个界面显示要清理的文件。通过交互式操作来决定是否要删除这些文件或者有选择性的删除某些文件具体操作可以看git-clean的帮助文档。
7、用 git commit --fixup/--squash
以及 git rebase -i--autosquash 修改历史提交
(1).修改历史提交通常使用git rebase -i,但并不方便。是否可以先提交,后改历史?
(2).git commit --fixup=[amend:lreword:]<commit>创建的新提交提供对指定提交的修正/修补/修改说明。
$ git commit --fixup <commit> #新提交的标题包含便于识别的前缀“fixup!"
$ git commit --fixup=amend:<commit>#新提交的标题包含便于识别的前缀"amend!"
$ git commit --fixup=reword:<commit>#新提交的标题包含便于识别的前缀"amend!",且无内容更改。
(3).git commit --squash=<commit> #新提交的标题包含便于识别的前缀“squash!”。
(4).it rebase -i --autosquash 的交互式变基能够识别特殊的提交前缀,自动压合提交。
(5).如果希望--autosquash成为默认值,设置 rebase.autosquash为true。
第7个变化就是修改历史,我认为这是记得最为强大的地方可以修改历史来完善提交如果人生也可以如此有多少遗憾都可以被修复。以前我们要修复 Git 的提交历史,需要执行交互式变基切换到对应提交上来执行修补操作,但是操作会让开发工作横生枝节能不能在开发中一直顺序的向前提交提交过程中标记上。
比如提交用于修复a提交提交用于修复b提交待工作完成后再批量整理提交历史,这就是我要介绍特性标记题交在git commit的时候使用--fixup参数或者 --spuash参数这些参数可以为创建的新提交来进行标记比如 Git commit--fixup后面跟一个提交的ID创建出来的新提交的标题,就包含一个特别的前缀就是 fixup 一个叹号。这样的提交在将来做提交整理的时候,将会融合到它所修复的提交当中去,我们还可以在fixup的时候加上amand或者reword这样产生的提交会有不同的前缀它们有的会将提交的内容,进行修改提交说明也进行修改有的仅修改提交说明。
当我们完成了一连串对于历史提交的修复之后怎么样来整理提交那就是我们在使用交互式奠基操作的时候,增加一个--autosquash参数它就会自动的来完成对历史提交的修复。
如果希望 autosquash 成为默认值可以进行一个特殊的 Git 设置来设置 rebase.autosquash 为true。
8.git range-diff 比较两个版本序列之间的差异
(1).在 Git 项目的开源贡献中,经常使用此技术比较前后两个版本(reroll)多个提交之前的差异。
(2).示例:
https://public-inbox.org/git/20200827I5455I.5966-I-worldhello.net@gmail.com/
第8个变化就是Git提供了一条新命令Git range-diff,它可以用来比较两个版本序列之间的差异普通的Git diff比较的是两个版本的差异。普通git-diff是比较两串版本之间的差异。这条命令在给Git数据贡献的时候非常有用在我给出的链接中,大家可以看到下面的输出前后的提交有的提交是没有改变。比如第一个提交和第2个提交并没有改变而第3个提交改变了提交说明这就是git range-diff。
9.使用proc-receive挂钩和report-status-v2设计免特性分支的评审工作流(主干开发模式)
(1).只读用户向仓库推送创建代码评审。
(在https://codeup.aliyun.com/提供支持)
$ git push origin HEAD:refs/for/master/<topic-name>
(2).客户端工具:支持 Android 式多仓库模式(比git-submodule 更好用的多仓模式)
$ git repo init -u <manifest.git>
(3).客户端工具:单仓库快捷操作。参考:https://git-repo.info/
$ git pr
$ git download ...
(4).更多的服务端创新已在路上...
第九个变化就是在2020年我向 git 社区贡献了 proc-receive 挂钩和 report- status V2功能。这两个功能可以在代码平台设计出非常酷的 git 操作流程,比如来设计免特性分支的评审工作流阿里云的代码 Codeup 就支持特性用户,可以执行 Git push origin 把它本地的提交推到远程一个特殊的引用特殊的引用。
有一个特殊的前缀就是 refs/for 跟着你要修改的分支名后面是一个可选的一个本地的一个标志符。这个操作它并不会在服务端创建特殊的引用也不会创建任何分支,而是直接创建一个代码评审对于仓库没有写权限,只拥有读权限的用户也可以执行这套命令。我们还开源了名为Git-repo的客户端工具,这个工具可以支持像安卓项目那样的多仓库管理模式。这是一种比 Git-submoduel 更好的多仓模式。
10.Git 本地话
(1).Git 有一天突然说中文了!这始于2012年,九年的中文本地话工作。
(2).不喜欢 Git 的中文翻译?参考“po/RADME.md”了解本地话流程,参与贡献。
(3).作为 Git 本地话协调者,我是怎么管理多语种本地话的:
(4).Git本地话的CI工具:
(5)https://github.com/git-IIOn/git-po-helper
和Git本地话流水线:github/workflows/llOn.yml
(6).中文本地话 Leader:周方易
第十个变化Git本地话很多人感受到了 Git 变化,也有很多人认为这很自然。就是Git有一天突然说中文了这始于2012年从那之后我负责了9年的中文本地话工作。
有人可能不喜欢 Git 一些中文翻译可以参考po目录下的README.md,来了解Git本地话的流程来参与Git的本地话贡献,我同时还是Git本地话的国际协调者。
通过一些CI工具和流程来保障不同国家的人在贡献Git本地话翻译时能够保持一定的质量。在 Git2.34开始Git中文本地话的 Leader 是周方意。