资讯详情

简单梳理下git的使用感受,思考git中最重要的是什么

文章目录

  • 前言
  • git和svn
  • git最重要的是什么
  • 总结

前言

工作中使用git从两年前开始,一直以前add -> commit ->push常规操作,真正在工作中使用后才逐渐理解git强大,这种理解是建立在不断解决问题的基础上,不断处理遇到的问题,就像升级怪物一样,是的git理解也越来越全面。因为在使用git之前一直用svn作为版本控制工具,对git和svn差异也有自己的理解。网上搜索了很多关于两者区别的文章,我就不重复了。我只是从自己的理解来描述两者的区别。

git和svn

关于git和svn网上有很多不同的文章,大部分都会提到分布式、存储方式、版本号、完整性等。,而我今天要写的区别是两者提交记录的结构。

由于是版本控制工具,那么每一次历史提交都必须能够追溯和回归svn提交记录时线性的,以时间轴为参考基准,所有提交按时间顺序排列,因为svn必须将记录提交给服务器才能生效,所有服务器相当于每个服务器svn每个客户端的总控制svn提交到服务器时线性排列,在修改和提交之前,必须将本地文件状态更新为与服务器相同的状态。

正因为在svn服务器负责总控操作,所以最新的提交记录可以保证时间是整个svn在最新状态下,提交记录不依赖端时间,完全由服务器时间排序。

在git没有这样的总控服务器。虽然每个代码库通常都有统一的托管服务器,但它的作用是任何一个git可以替换客户端,因为git它可以离线提交。托管服务器只是我们存储代码的地方svn按时间排序服务器的做法大不相同。

git提交记录通常是树形结构,有时会变成起点和终点的网状结构git中间时间只有参考意义,不能决定提交记录的顺序。如果你仍然怀疑这一点,你可能是一个svn重度用户还没有理解git操作原理。

对于这个问题,可以举个例子,操作相同的文件svn中2月13日修改一次,2月14日修改一次,那么2月15日看这个文件一定是2月14日修改后的状态;而在git同样的文件在2月13日和2月14日修改一次,文件的状态取决于两次修改是否在同一分支,以及合并时如何处理,随着时间的延长和多分支的结合,这种错位往往对时间的依赖最小,此时提交的顺序无法用时间来衡量。

假如一开始就是git,上述问题并不明显,但已经习惯了svn再使用git,在处理历史可追溯性问题时,往往很容易找到错误的方向。经常通过时间过滤的内容不是你想要的,这在实践中需要注意。

git最重要的是什么

我相信每个人都有自己的答案。有些人认为它是分布式的,有些人认为切换分支非常方便,我的答案是 commit 的设计哲学,我觉得这是git中的精髓,git中的commit就像链表中的元素一样,用来自己和其他元素commit串联到一起,形成branchtagHEAD 等等。

我们可以通过 git log 看一个命令 commit:

$ git log -1 commit 7bf665f125a4771db095c83a7ad6ed46692cd314 (HEAD -> 6.0, tag: 6.0.6, origin/6.0) Author: Oran Agra <oran@redislabs.com> Date:   Sun Jul 19 14:00:20 2020  0300      Redis 6.0.6.  

这条commit id 为 7bf665f125a4771db095c83a7ad6ed46692cd314,这是整个库中唯一的,通过 git log 可以看到提交时间、作者、简要说明等信息,那么提交和库有什么关系呢?

通过括号中的内容,我们可以知道当前的提交是这个库6.0同时是标签的分支6.0.6,也与远端的6.0分支同步。

使用 git cat-file 命令可以进一步查询commit组织形式:

$ git cat-file -p HEAD tree c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3 parent a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d author Oran Agra <oran@redislabs.com> 1595156420  0300 committer Oran Agra <oran@redislabs.com> 1595268506  0300  Redis 6.0.6. 

可以发现这次提交包含了 tree c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3,同时,它的父亲提交 parent a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d,有了这两个id可以推出当前版本的内容和历史记录。

通过 tree c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3 当前版本中的所有文件都可以递归找到:

$ git cat-file -p c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3 040000 tree 6608d88fe6a7a25b137b869040103ab261310da4    .github 100644 blob e445fd2017bb0c13af2f40cd7f24afefdb603ade    .gitignore 100644 blob 484aeb62186033d32e9a4bdf12434cb6b8c56fb5    00-RELEASENOTES 100644 blob 7af2593407805c308cc25739ac9c6520031de60f    BUGS 100644 blob 000edbeaf0270bf3b9e457274ab092b02b176b84    CONTRIBUTING 100644 blob a381681a1c2524ed586c6a87dfeb9ccdf1e86ded    COPYING 100644 blob 3083f1afd50c34e1139ab1577510a17e968b0ed4    INSTALL 100644 blob 3727894624fdabf72995e6f94998a2cad359f760    MANIFESTO 100644 blob e614ede891f2dd183a3ae41ea1ac3b63fe2e7634    Makefile 100644 blob 55537e01fe862dd200ebe1078033122facfc854e    README.md 100644/span> blob 2d020d0ceb0ddc7fd0bb2a6185e57a9afd5aef79 TLS.md 040000 tree 43ccdd93a80b35e03160d9db34f1e844a62a74b4 deps 100644 blob 8c53f015a20934bdb41c77152fd32a557d719fae redis.conf 100755 blob ade1bd09a539ecd8dcdd09e59a658539dab9bce6 runtest 100755 blob 27829a5fe8afacf893fe9bafc4245971ce375d6c runtest-cluster 100755 blob f6cc0a2589dea0f95b77b226e54200a29b8237ae runtest-moduleapi 100755 blob 3fb1ef61561289b2bf8622e49645f66dab83eeea runtest-sentinel 100644 blob 4ca5e5f8fc5abe2938c66a6851bba0c90058620f sentinel.conf 040000 tree e3b3338a7c60eafb3d9c19d3784e2482beea1d4b src 040000 tree af5de133fa0a0da30fe487be40783ef9644fba6d tests 040000 tree 5a82556097d23f0c16a8e5432d464f2ab434fd2a utils 

通过 parent a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d 可以找出上一次提交,进而递归找出所有的提交,要注意有些commit的parent不止一个:

$ git cat-file -p a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
tree 1adcf548620c6134f7d5fd072c05b981d0f36118
parent e15528bf1da1f1232fd08801ad382c915be94662
author Oran Agra <oran@redislabs.com> 1595162001 +0300
committer Oran Agra <oran@redislabs.com> 1595268506 +0300

Run daily CI on PRs to release a branch

这个commit的设计真的很神奇,一个个commit串起来就是一个branch,本质来讲branch只是commit的一个别名,包括HEAD也是,而 tag 也是对commit的一个描述,在不加描述信息时和commit也是一样的。

$ git cat-file -p 6.0.6
tree c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3
parent a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
author Oran Agra <oran@redislabs.com> 1595156420 +0300
committer Oran Agra <oran@redislabs.com> 1595268506 +0300

Redis 6.0.6.

$ git cat-file -p HEAD
tree c3d4b2bcd934be7e4ed98edac5aa7e9c054503c3
parent a5696bdf4f2687ab45f633ccb7cdc4ee9c2f957d
author Oran Agra <oran@redislabs.com> 1595156420 +0300
committer Oran Agra <oran@redislabs.com> 1595268506 +0300

Redis 6.0.6.

所以理解了commit的定位以后,所有切换分支、切换tag、操作HEAD,本质上都是在对commit进行操作,这些操作的参数完全可以用commit id来替换HEAD、branch name、tag name等等。

总结

  • svn的提交记录是一个按时间排序的线性结构,git的提交记录是一个参考时间的树状结构
  • git记录中时间先后不能代表commit修改的先后,回溯查找时要注意这一点才能解释很多疑惑
  • git中的commit我认为是它的精髓,通过commit的串联和别名,形成分支、标签、HEAD等多种元素,隐藏了细节,方便了操作

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

什么才是精彩的人生?扬在脸上的自信、长在心底的善良、融进血里的骨气、刻进生命里的坚强~

标签: bf3v系列圆柱形光电传感器ceb螺栓式铝电解电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台