Git工作原理
1.版本控制系统
采用版本控制系统(VCS)是个明智的选择。 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。
1.1版本控制系统的演变
本地版本控制系统
大多都是采用某种简单的数据库来记录文件的历次更新差异。
集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)
为了让不同系统上的开发者协同工作, 于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 这类系统,诸如 CVS、Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。
- 管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
- 但容易见的缺点是中央服务器的单点故障
分布式版本控制系统(Distributed Version Control System,简称 DVCS)
客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份
1.2.保存数据的差异
集中式版本控制
每个version 保存的是变更的记录,与更老的版本一起得到完整的记录
分布式版本控制
分布式,每个version 都是一个快照,有变化的是新的记录,没有变化的就通过指针定位到上个version的对应的文件。
2.git的三种状态与四个区域
按照git官方的书籍来说,区域只有三个,但为了方便理解我把stash操作存储的地方 暂存栈也算一个区域。
2.1 git 中文件的三种状态
- 已提交(committed)
- 已修改(modified)
- 已暂存(staged)
2.2 git的其他三个区域
- 工作树:对应中项目的某个版本独立提取出来的内容,这些从 Git 仓库的压缩数据库中提取出来的文件,放在磁盘上供你使用或修改
-
暂存区(索引区) : 就是给下个快照的文件做标记的地方<==>下次要提交的文件集。
a.为了避免每次改动都需要commit的繁琐,把很多改动的文件做一次commit
b.可以避免工作树中不必要的文件提交 -
仓库: 永久性存储数据的地方
a.本地仓库(通常是远程仓库的一个mirror)
b.远程仓库
2.3 git 记录数据
git 记录数据的大概流程,用下面一张图来诠释
这里有几点需要注意
- git commit 操作只会把暂存区的数据保存到本地仓库,所以要特别注意是修改了已跟踪的某个文件(上个version的文件),一定要要执行一次 git add 才能保存这次对该文件的修改,不然新生成快照里的该文件还是上个version的内容
- 在执行下次commit 操作前,工作树新建的文件或者上个版文件有变动文件但还未加到暂存区,暂存区的文件 对所有的分支是可见的,这也是为什么有时候切换分支时报错,提示让先进行commit或者stash(就是当前分支和目标分支有相同的文件存在改动,引起冲突)。
2.4 git 检查当前文件状态
git status
$ git status
On branch master
nothing to commit, working directory clean
这说明你现在的工作目录相当干净。换句话说,所有已跟踪文件在上次提交后都未被更改过。
主要分下面两种情况
2.4.2 跟踪新文件(之前未跟踪)
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
2.4.3 查看已暂存和未暂存的修改(上个version里文件发生改动)
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md