当前位置: > Linux服务器 > Git >

2016 Git 新视界(3)

时间:2017-04-19 12:46来源:linux.it.net.cn 作者:IT




Submodule差强人意

子模块允许你从 Git 仓库内部引用和包含其他 Git 仓库。这通常被用在当一些项目管理的源依赖也在被 Git 跟踪时,或者被某些公司用来作为包含一系列相关项目的 monorepo 的替代品。

由于某些用法的复杂性以及使用错误的命令相当容易破坏它们的事实,Submodule 得到了一些坏名声。

但是,它们还是有着它们的用处,而且,我想这仍然是用于需要厂商依赖项的最好选择。 幸运的是,2016 对子模块的用户来说是伟大的一年,在几次发布中落地了许多意义重大的性能和特性提升。

并行抓取

当克隆或则抓取一个仓库时,加上 --recurse-submodules 选项意味着任何引用的子模块也将被克隆或更新。传统上,这会被串行执行,每次只抓取一个子模块。直到 Git v2.8,你可以附加 --jobs=n 选项来使用 n 个并行线程来抓取子模块。

我推荐永久的配置这个选项:


	
  1. $ git config --global submodule.fetchJobs 4

……或者你可以选择使用任意程度的平行化。

浅层化子模块

Git v2.9 介绍了 git clone —shallow-submodules 标志。它允许你抓取你仓库的完整克隆,然后递归地以一个提交的深度浅层化克隆所有引用的子模块。如果你不需要项目的依赖的完整记录时会很有用。

例如,一个仓库有着一些混合了的子模块,其中包含有其他厂商提供的依赖和你自己其它的项目。你可能希望初始化时执行浅层化子模块克隆,然后深度选择几个你想工作与其上的项目。

另一种情况可能是配置持续集成或部署工作。Git 需要一个包含了子模块的超级仓库以及每个子模块最新的提交以便能够真正执行构建。但是,你可能并不需要每个子模块全部的历史记录,所以仅仅检索最新的提交可以为你省下时间和带宽。

子模块的替代品

--reference 选项可以和 git clone 配合使用来指定另一个本地仓库作为一个替代的对象存储,来避免跨网络重新复制你本地已经存在的对象。语法为:


	
  1. $ git clone --reference <local repo> <url>

到 Git v2.11,你可以使用 —reference 选项与 —recurse-submodules 结合来设置子模块指向一个来自另一个本地仓库的子模块。其语法为:


	
  1. $ git clone --recurse-submodules --reference <local repo> <url>

这潜在的可以省下大量的带宽和本地磁盘空间,但是如果引用的本地仓库不包含你克隆的远程仓库所必需的所有子模块时,它可能会失败。

幸运的是,方便的 —-reference-if-able 选项将会让它优雅地失败,然后为丢失了的被引用的本地仓库的所有子模块回退为一次普通的克隆。


	
  1. $ git clone --recurse-submodules --reference-if-able \
  2. <local repo> <url>

子模块的 diff

在 Git v2.11 之前,Git 有两种模式来显示对更新你的仓库子模块的提交之间的差异。

git diff —-submodule=short 显示你的项目引用的子模块中的旧提交和新提交(这也是如果你整体忽略 --submodule 选项的默认结果):

git diff —submodule=log 有一点啰嗦,显示更新了的子模块中任意新建或移除的提交的信息中统计行。

Git v2.11 引入了第三个更有用的选项:—-submodule=diff。这会显示更新后的子模块所有改动的完整的 diff。

git stash 的 90 个增强

不像子模块,几乎没有 Git 用户不钟爱 git stash。 git stash 临时搁置(或者 藏匿)你对工作区所做的改动使你能够先处理其他事情,结束后重新将搁置的改动恢复到先前状态。

自动搁置

如果你是 git rebase 的粉丝,你可能很熟悉 --autostash 选项。它会在变基之前自动搁置工作区所有本地修改然后等变基结束再将其复用。


	
  1. $ git rebase master --autostash
  2. Created autostash: 54f212a
  3. HEAD is now at 8303dca It's a kludge, but put the tuple from the database in the cache.
  4. First, rewinding head to replay your work on top of it...
  5. Applied autostash.

这很方便,因为它使得你可以在一个不洁的工作区执行变基。有一个方便的配置标志叫做 rebase.autostash可以将这个特性设为默认,你可以这样来全局启用它:


	
  1. $ git config --global rebase.autostash true

rebase.autostash 实际上自从 Git v1.8.4 就可用了,但是 v2.7 引入了通过 --no-autostash 选项来取消这个标志的功能。如果你对未暂存的改动使用这个选项,变基会被一条工作树被污染的警告禁止:


	
  1. $ git rebase master --no-autostash
  2. Cannot rebase: You have unstaged changes.
  3. Please commit or stash them.

补丁式搁置

说到配置标签,Git v2.7 也引入了 stash.showPatch。git stash show 的默认行为是显示你搁置文件的汇总。


	
  1. $ git stash show
  2. package.json | 2 +-
  3. 1 file changed, 1 insertion(+), 1 deletion(-)

将 -p 标志传入会将 git stash show 变为 “补丁模式”,这将会显示完整的 diff:

stash.showPatch 将这个行为定为默认。你可以将其全局启用:


	
  1. $ git config --global stash.showPatch true

如果你使能 stash.showPatch 但却之后决定你仅仅想要查看文件总结,你可以通过传入 --stat 选项来重新获得之前的行为。


	
  1. $ git stash show --stat
  2. package.json | 2 +-
  3. 1 file changed, 1 insertion(+), 1 deletion(-)

顺便一提:--no-patch 是一个有效选项但它不会如你所希望的取消 stash.showPatch。不仅如此,它会传递给用来生成补丁时潜在调用的 git diff 命令,然后你会发现完全没有任何输出。

简单的搁置标识

如果你惯用 git stash ,你可能知道你可以搁置多次改动然后通过 git stash list 来查看它们:


	
  1. $ git stash list
  2. stash@{0}: On master: crazy idea that might work one day
  3. stash@{1}: On master: desperate samurai refactor; don't apply
  4. stash@{2}: On master: perf improvement that I forgot I stashed
  5. stash@{3}: On master: pop this when we use Docker in production

但是,你可能不知道为什么 Git 的搁置有着这么难以理解的标识(stash@{1}、stash@{2} 等),或许你可能将它们勾勒成 “仅仅是 Git 的癖好吧”。实际上就像很多 Git 特性一样,这些奇怪的标志实际上是 Git 数据模型的一个非常巧妙使用(或者说是滥用了的)的结果。

在后台,git stash 命令实际创建了一系列特定的提交目标,这些目标对你搁置的改动做了编码并且维护一个 reglog 来保存对这些特殊提交的引用。 这也是为什么 git stash list 的输出看起来很像 git reflog 的输出。当你运行 git stash apply stash@{1} 时,你实际上在说,“从 stash reflog 的位置 1 上应用这条提交。”

到了 Git v2.11,你不再需要使用完整的 stash@{n} 语句。相反,你可以通过一个简单的整数指出该搁置在 stash reflog 中的位置来引用它们。


	
  1. $ git stash show 1
  2. $ git stash apply 1
  3. $ git stash pop 1

讲了很多了。如果你还想要多学一些搁置是怎么保存的,我在 这篇教程 中写了一点这方面的内容。 


好了,结束了。感谢您的阅读!我希望您喜欢阅读这份长篇大论,正如我乐于在 Git 的源码、发布文档和 man手册中探险一番来撰写它。如果你认为我忘记了一些重要的事,请留下一条评论或者在 Twitter 上让我知道,我会努力写一份后续篇章。

至于 Git 接下来会发生什么,这要靠广大维护者和贡献者了(其中有可能就是你!)。随着 Git 的采用日益增长,我猜测简化、改进的用户体验,和更好的默认结果将会是 2017 年 Git 主要的主题。随着 Git 仓库变得越来越大、越来越旧,我猜我们也可以看到继续持续关注性能和对大文件、深度树和长历史的改进处理。

如果你关注 Git 并且很期待能够和一些项目背后的开发者会面,请考虑来 Brussels 花几周时间来参加 Git Merge 。我会在那里发言!但是更重要的是,很多维护 Git 的开发者将会出席这次会议而且一年一度的 Git 贡献者峰会很可能会指定来年发展的方向。

或者如果你实在等不及,想要获得更多的技巧和指南来改进你的工作流,请参看这份 Atlassian 的优秀作品: Git 教程 。

封面图片是由 instaco.de 生成的。


via: https://medium.com/hacker-daily/git-in-2016-fad96ae22a15



 




(责任编辑:IT)
------分隔线----------------------------