GIT 高手9问

2020-04-27 10:57:25 浏览数 (1)

GIT 高手9问

  • 1、git 比其它版控工具快的原因?
  • 2、git 将版本库和工作区放在同一个目录,究竟是好是坏?
  • 3、git 默认只在根目录有.git版本库,其子目录是如何发现版本库呢?
  • 4、git config --global --system 究竟有什么区别?
  • 5、git commit生成的`HASH`为什么不用顺序数字代替?
  • 6、git 工作区如何归档压缩?
  • 7、如何使用`GIT`找出`BUG`缔造者?
  • 8、TAGS(里程碑)有什么用?
  • 9、非技术问

开始阅读前,我估且认为您已经是GIT老手了。

1、git 比其它版控工具快的原因?

  • 分布式,每个client都是server,没有跨网络等待时延
  • git的判别文件是否有变化是根据文件的时间缀、大小、指纹HASH变化的文件以快照的方式存储,没有变化则更改链接指向。而CVS,SVN等传统工具,则是每次记录文件变化的内容,随时间长短和项目大小变化,计算量直接影响速度快慢。

综上:快

2、git 将版本库和工作区放在同一个目录,究竟是好是坏?

  • 首先:传统版控工具特意将数据和版本库分开存放,是为了数据安全,主要是磁盘损坏等物理行为造成的数据不可逆损坏
  • 其次:这是一个鸡生蛋,还是蛋生鸡的问题。到底哪种方式安全各有说法
  • 最后,也是最重要:git本身分布式的架构方式已经解决了鸡生蛋,还是蛋生鸡的问题。不同于集中管理的方式,git每个用户都是版控机 。即使server挂了也丝毫不会影响版本库和数据。

综上:好

3、git 默认只在根目录有.git版本库,其子目录是如何发现版本库呢?

如前个问题所描述:git及分布式版本控制系统的显著特点是:版本库位置工作区根目录。以git为例,是根目录下的.git目录。

传统的集中式版本控制系统的版本库和工作区是分开,甚至在不同主机上。因此,必须有额外的对应关系。

CVS每个工作区的根目录下及子目录下都有一个CVS目录,包括了配置文件。不安全,搜索结果混乱

有些软件工作区看起来非常“干净”,但其实是通过服务器建立文件跟踪,在DB存储,哪个client哪个目录检出什么版本库。如果客户端将工作区移动或改名,则文件状态会丢失。

GIT只在工作区根目录下设置.git版本库,保证了目录的干净性,大大提高了安全性,但也意味着只有.git版本库的目录才存储有版本库信信息。

  • 但同步带来的问题是,子目录没有版本库信息,怎么记录工作状态呢?

其实,子目录下的执行命令其实会依次向上递归查找.git目录,找到工作区对应的版本库。 并且提供命令追踪向上递归的过程。

代码语言:javascript复制

strace -e 'trace=file' git status

  • 结果如下:
代码语言:javascript复制
execve("/usr/bin/git", ["git", "status"], [/* 44 vars */]) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/12.1/client64/lib/tls/x86_64/libz.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/oracle/12.1/client64/lib/tls/x86_64", 0x7fff445d6c40) = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/12.1/client64/lib/tls/libz.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)


...

题外话: git的检索甚至是从根目录开始的,这个是不是有点过分了。。

  • 检索git根目录
代码语言:javascript复制

git rev-parse --git-dir # 显示.git目录所在位置

git rev-parse --show-toplevel # 显示工作区根目录

git rev-parse --show-prefix # 相对工作区根目录的当前目录

综上:向上逐层递归

4、git config --global --system 究竟有什么区别?

  • 对应关系如表所示

配置文件

命令

/etc/gitconfig

# git config —system user.name …

~/.gitconfig

# git config —global user.name …

.git/config

# git config user.name …

5、git commit生成的HASH为什么不用顺序数字代替?

  • 首先: git是分布式,每次是先提交本地,最后有需求才会推送SERVER。即不仅仅要保证本地版本库ID唯一,也要保证“全球”ID唯一。
  • 其次: HASH是通过 SHASUM加密算出来,即是版本唯一性的标识,更是文件是否的变化的标识。还记得问题1中git比传统工具快的原因吗?
  • 最后: 版本是非线性增长,GIT提倡充分使用好分支特性

6、git 工作区如何归档压缩?

  • tar,zip? NO!

.git目录不想打包,且.gitgnore中记录的忽略文件也不想打包!写个shell脚本读取.gitgnore后,find过滤?NO。。。。

其实git提供了内置工具

  • 基于最新的提交建立归档文件 latest.zip
代码语言:javascript复制
git archive -o latest.zip HRAD
  • 只将目录src和doc归档到partial.tar中
代码语言:javascript复制
git archive -o partial.tar HEAD src doc
  • 建议里程碑v1.0建立归档,并为归档的文件添加目录前缀1.0
代码语言:javascript复制
git archive --format=tar --prefix=1.0/ v1.0| gzip > foo-1.0.tar.gz

7、如何使用GIT找出BUG缔造者?

  • git blame值得拥有
代码语言:javascript复制

git blame prod/alarm.php
git blame -L 6, 5 prod/alarm.php # 只想查看某几行

  • 输出如下
代码语言:javascript复制
e5a152be (gw       2018-04-26 09:48:39  0800  13)             'wx:?49d79ce274ca65ae04965864e1',
8041ad3e (stanley    2016-06-13 14:55:05  0800  14)         ],
8041ad3e (stanley    2016-06-13 14:55:05  0800  15)
8041ad3e (stanley    2016-06-13 14:55:05  0800  16)         'jerror'=>[

可以清晰看到什么人,什么时间,在哪个版本、改了哪行代码。当然,我假设你已经定位到是哪个文件引发的BUG

8、TAGS(里程碑)有什么用?

代码语言:javascript复制
git tag v_2.0 -m 'my first tag'

tags里程碑的构建先简单,但究竟有什么用呢?

  • 通常情况下用不到,但是这非常好的使用习惯,推荐使用
  • git长时间使用,库越来越大,希望清理很久以前的提交信息以减少磁盘占用或者希望将版本中的某部分提交去除时,tags会提供非常大的帮助

9、非技术问

版本协同工具的鼻祖是CVS(Concurrent Version System),作者阿姆斯特丹Dick Grune教授因工作协同问题被逼实现的作品。一经问世便红遍全球,唯 Linux 教父 linus 极度排斥。宁愿diff,patch手工维护也不愿使用,遭受同样遭遇的还有众所周知的 SVN。随着CVS, SVN管理的项目越来越多,原子级提交对二进制文件的支持有限、版本追踪合并混乱、隐藏目录安全隐患、分支错乱等问题也逐一暴露出来。

随后的戏剧性的故事开始了,在 bitkeeper 的授权被回收后,linus 被逼花了**4天写出了git** 。对的,只有4天。2个月就已经开始维护Linux核心代码。而1996年硕士毕业的 linus 40岁。30岁的linus就已经看出教授的产品是"垃圾".

那么问题来了:究竟是人成就了事,还是事成就了人呢?您怎么看

GIT 简介:Linus坚定的CVS反对者,同样也反对SVN,这也是其1991-2002十余年间手动维护代码的原因。git是其第二个伟大作品。在git诞生之前,linux社区使用的bitmover公司的商业产品bitkeeper进行版本管理。2005SAMBA作者试图对bitKeeper进行反工程,希望能与bitkeeper交互的开源工具。bitmover收回到linux社区免费使用bitkeeper的授权。 不得已, 2005.04.03 开始开发git 4.6号git发布 4.29,性能达linus预期 6.16 维护linux核心源代码 07.26 linus功成身退,git交由Junio C Hamano维护 最开始,每个git功能都是一条命令,如git-commit git-clone等,使git命令集过于庞大,随后封装成一个git命令,贴近普通用户的使用习惯。 gitlinux平台下开发,但现在已经跨平台,也是迄今最为流行的版本管理工具。

0 人点赞