前言
今天是五一假期的第一天,突然想起来应该对最近工作中遇到的一个非常让我头痛的问题进行一下深入的学习和探索。这个问题是什么呢?就是git的使用。虽然以前自己做项目的时候也用过git,但是那时候对git的使用很浅,只要是push successfully就完事了,没有注意到git有那么多的使用细节。现在参与到团队开发中以后,我发现个人开发和团队开发是完全不一样的,相较于单人开发项目时的随意和松散,团队协作构建出来的复杂的代码工程是不容许任何一个开发者大意和马虎的,你的任何一个小错误都有可能对整个工程带来巨大的影响。所以学会如何使用团队协作工具是非常重要的。
在我看来,使用任何一个工具,首先去了解它的设计理念和基本结构肯定会在使用过程中产生事半功倍的效果,所以就先从Git的基础概念学起。
不积跬步无以至千里,不积小流无以成江海。
目录
1.1、什么是VCS(Version Controller System)?
1.4、什么是提交对象(git commit object)?
1、Git介绍
1.1、什么是VCS(Version Controller System)?
要弄明白什么是git,就要先弄明白什么是VCS,Version Controller System的字面意思很好理解,翻译过来就是指“版本控制系统”。难以理解的是我们为什么要使用这个VCS?它的作用是什么?
在阿里巴巴研发效能部的一篇文章中,我觉得他们很好的回答了这个问题:
当你在工作中面对的是一些经常变化的文档、代码等交付物的时候,考虑如何去追踪和记录这些changes就变得非常重要,原因可能如下:
- 对于频繁改动和改进的交付物,非常有必要去记录下每次变更的内容,每次记录的内容汇成了一段修改的历史,有了历史我们才能知道我们曾经做了什么
- 记录的历史中必须要包含一些重要的信息,这样追溯才变得有意义,比如:
- Who:是谁执行的变更?
- When:什么时候做出的变更?
- What:这次变更做了什么事情?
- 最好可以支持撤销变更,不让某一个提交的严重问题,去污染整个提交历史
VCS正是为我们在开发工作中提供了这种记录和追溯变更的能力。
1.2、什么是Git?
git是一个开源的分布式版本控制系统,是VCS的一种。它的发明者是Linux之父Linus Torvalds,git一开始是Linus为了管理Linux内核开发而开发的一个版本控制软件,后来因为其高度易用,速度快等特性才慢慢流行于软件开发项目中。
git既然是一个分布式版本控制系统,那么它的分布式体现在哪里呢?具体内容请参见Git Documentation ---分布式工作流程。
1.3、Git存储变更数据的理念
Git对待数据的方法与SVN不同。SVN是以文件变更列表的方式来存储信息,它是将保存的信息看做是一组基本文件和每个文件随时间逐步累积的差异delta,如下图所示:
File A即基本文件(最原始版本),SVN保存了不同版本与基础文件之间的差异(三角符号即差异变量delta)。
而Git保存信息的方式是把数据看做是对小型文件系统的一组快照(什么是快照?我理解的快照大概意思就是系统把某一个状态下的各种数据记录在一个文件中,就像是人类照相一样,照出来的相片其实就是对你当时某一个状态的记录),每次你提交更新,或者在Git中保存项目时,它对当时全部文件制作一个快照并保存一个对此快照的索引(为了实现高效率,如果某一个文件没有进行更改,那么Git不再重新存储此文件,而是保存一个链接指向之前存储的文件),如下图所示:
1.4、什么是提交对象(git commit object)?
- 提交对象(git commit object):即提交对象。每一个提交在git中都通过git commit object存储,这个对象具有一个全局唯一的名称,叫做revision hash,它的名字是由SHA-1算法(安全哈希算法)生成,形成如“998273647a8b67f89994ec2”这样的一串字符串(它由40个16进制字符组成),我们通常会取其缩写方便使用,如“9982736”。
- 对象构成:git commit object对象包含了author (提交者)+ commit message(提交信息)的基本信息。
- 对象存储:git commit object对象中保存了一次变更提交内的所有变更内容,而不是增量变化的数据delta,所以git对于每次改动存储的都是全部状态的数据。
- 提交树:多个commit对象会组成一个提交树,它让我们可以轻松的追溯commit历史,也能比对树上commit与commit之间的变更差异,例如下图:
1.5、Git的三个工作区域
一个文件从修改到提交要经历三个状态,分别是
- modified(已修改):表示修改了文件还没有保存到数据库中;
- staged(已暂存):表示对一个已修改的文件的当前版本做标记,使之包含在下次提交的快照中;
- committed(已提交):表示数据已经安全的保存到了本地数据库中。
这三种状态又对应着不同的工作区:
- 工作区(Working Directory):工作区是指我们本地工作的目录,比如我们在项目中创建一个test文件夹,并在test文件夹中新增一个readme文件,这时这个readme文件还只是本地文件系统上的修改,还没有存储到git。
- 暂存区(Staging Area):暂存实际上是将我们本地文件系统的改动转化为git的对象存储的过程,暂存区其实是一个文件,保存了下次将要提交的文件列表信息,一般在git仓库目录中。
- 仓库(Repository):是git用来保存项目元数据和对象数据库的地方,是git最重要的部分。git commit后将提交对象存储到git仓库。
另外!!!工作区中的任何文件都无外乎处于以下两种状态中的一种:
- 已跟踪(tracked):这是指那些已经被纳入版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们可能处于未修改、已修改或已放入暂存区(初次从远程仓库中clone下来的文件都属于已跟踪未修改状态)。
- 未跟踪(untracked):工作区中除了已跟踪外的所有文件都属于未跟踪文件,它们即不存在于上次快照记录中,也没有放入暂存区。
(要查看一个文件属于哪种状态,使用git status命令;将未跟踪状态变更为已跟踪状态,使用git add命令。git add命令是一个多功能命令,可参照Git Documentation。)
参考文章: