git 入门教程之版本控制
版本控制
我们知道 git 是分布式版本控制系统,所以称被控制对象是版本本身没错,但是从git 命令中发现,并没有版本这个名词,有的只是commit,所以前几节我一直称其为提交.
为了避免后续教程引发歧义,特意说明,无论是版本也好,提交也罢,都是中文翻译而已,不必太过较真,直接原汁原味称commit也可以啊!
假设你已掌握暂存区的相关概念,简单来说,暂存区就是更改文件的缓存集合,等待一次性全部提交到版本库,正因如此,方便我们批量操作相关性文件,打包提交到版本库,这正是暂存区的独特魅力.
我们反复在说 git 是分布式版本控制系统,分布式的概念已经粗略讲过多次了,下面我们讲一下版本控制,谈谈 git 的版本控制和其他系统的版本控制有什么不同,为什么 git 这么优秀,如此流行?
git 跟踪并管理的是更改,而非文件本身.正如linux 一切皆文件,java 一切皆对象一样,git 一切皆更改.新增文件是一个更改,新增文件内容是一个更改,修改文件内容是一个更改,删除文件内容也是一个更改,换言之,git 管理的正是这一个个的更改,并不是文件本身.
下面我们用事实说话,证明 git 管理的是更改而不是文件本身:
第一步,追加 git tracks changes 到 test.txt 文件
# 查看 test.txt 文件内容
$ cat test.txt
git test
git init
git diff
understand how git control version
how git work
# 追加 git tracks changes 文件内容到 test.txt 文件
$ echo "git tracks changes" >> test.txt
# 再次查看 test.txt 文件内容
$ cat test.txt
git test
git init
git diff
understand how git control version
how git work
git tracks changes
$
第二步,添加test.txt 文件到暂存区并查看文件状态
$ git add test.txt
sunpodeMacBook-Pro:demo sunpo$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: test.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
.DS_Store
$
对于上述内容应该不必再解释了吧,无外乎说test.txt 文件已修改(modified),即将被提交(to be committed).
但是,此时偏偏不提交,继续修改 test.txt 文件:(这种情况实际工作中也有可能出现,比如你正在研发某功能,本以为已经开发完毕,满心欢喜添加到暂存区,然后意外发现一个小bug,分分钟就修复了,时间间隔很短以至于你根本不记得还需要再次添加到暂存区.)
第三步,继续修改文件内容,忘记再次添加到暂存区
# 编辑 test.txt 文件,将 git tracks changes 更改为 git tracks changes of files
vim test.txt
# 查看 test.txt 文件内容
$ cat test.txt
git test
git init
git diff
understand how git control version
how git work
git tracks changes of files
$
第四步,正常提交暂存区的全部更改到版本库
$ git commit -m "git tracks changes"
[master 2daa74a] git tracks changes
1 file changed, 1 insertion(+)
此次提交后,我们再看一下文件状态:
$ git status
On branch master
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: test.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
.DS_Store
no changes added to commit (use "git add" and/or "git commit -a")
$
发现有什么不同吗?以往提交后再次查看文件状态,工作区都是干净的,这次居然提示我们 test.txt 文件已经修改但未添加到暂存区?!
等一下,我们先回忆一下我们的操作流程:
第一次修改(git tracks changes) -> git add -> 第二次修改(git tracks changes of files) -> git commit
这样就很好理解了,git 管理的是更改而不是文件本身,如果是文件本身的话,应该将文件的内容全部提交才对,所以管理的是更改.
第一次修改过后使用 git add 命令将工作区的第一次修改内容放到暂存区准备提交,但是此时工作区发生了第二次修改,注意,这次修改并没有放到暂存区,所以下一步的git commit 命令提交的暂存区内容中自然也就没有第二次修改的内容了!所以git commit 完毕后运行git status命令才会发现此时工作区和暂存区还存在版本差异,即此时工作区不是干净的!
这一次的实验很好理解,工作区的修改需要主动告诉暂存区,暂存区的全部更改再提交到版本库.所以版本库的提交取决于暂存区,而暂存区又取决工作区是否主动将更改添加进去了吗!
理论再多不如亲身体验,让我们直接比较一下工作区和版本库的差异吧!
# 比较 test.txt 文件在工作区和版本库的差异
$ git diff HEAD -- test.txt
diff --git a/test.txt b/test.txt
index d31bdd2..56c76b7 100644
--- a/test.txt
+++ b/test.txt
@@ -3,4 +3,4 @@ git init
git diff
understand how git control version
how git work
-git tracks changes
+git tracks changes of files
$
由此可见,工作区比版本库多了git tracks changes of files,少了git tracks changes,所以说第二次修改内容 git tracks changes of files 并没有被提交.
现在我们再解释一下-git tracks changes 和 +git tracks changes of files 的问题:
首先查看工作区 test.txt 文件内容
$ cat test.txt
git test
git init
git diff
understand how git control version
how git work
git tracks changes of files
$
根据上述分析,我们知道第一次的修改git tracks changes 已被提交到版本库,第二次的修改git tracks changes of files 没有被提交而是继续留在工作区.
因此,可以推断出目前版本库的文件应该是这样的:
git test
git init
git diff
understand how git control version
how git work
git tracks changes
既然如何,工作区和版本库相比岂不刚好是少了一个git tracks changes,多了git tracks changes of files,其余文件内容完全相同!
透过现象看本质,已经分析了现象也解释了产生现象的原因,是时候分析一下本质了.
抛出问题:因为git tracks changes of fiels 和 git tracks changes 被视为不同的更改,所以才会造成上述现象.如果git tracks changes of fiels 被认为是git tracks changes + of fiels 两者叠加产生的更改,还会产生上述现象吗?
答案是否定的,如果两个更改可以叠加的话,按照版本控制的思路,第二次的修改即便没有提交也只是 of fiels 没有加入到版本库而已,如此一来,工作区和版本库的差异将不再是少了一个git tracks changes,多了git tracks changes of files,而仅仅是多了of files!
由此可见,git 版本控制系统其实是全量更新的思维模式,并不是差量更新模式.
小结
- 工作区的更改需要
git add添加到暂存区,git commit将暂存区的全部更改提交到版本库. - 工作区,暂存区,版本库三者既相关独立又密切关联,三者是传递性依赖的关系.
git版本控制的是文件的更改,而不是文件本身,是全量更新模式,而不是差量更新模式.
原文请访问 https://snowdreams1006.github.io/git/usage/version-control.html
git 入门教程之版本控制的更多相关文章
- git 入门教程
git 入门教程之协同开发 前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协 ...
- 廖雪峰Git入门教程
廖雪峰Git入门教程 2018-05-24 23:05:11 0 0 0 https://www.liaoxuefeng.com/wiki/00137395163059296 ...
- git 入门教程之基本概念
基本概念 了解工作区,暂存区和版本库的区别和联系有助于我们更好理解 git 的工作流程,了解命令的操作意图. git 和其他版本控制系统如 svn 的不同之处就是有暂存区的概念. 基本概念 工作区 | ...
- 版本控制工具 GIT入门教程
GIT 在团队中的中作流程 1.每个程序员在自己的分支上进行开发 2.主程序猿/Leader合并程序员程序 3.程序员之间也可以对一下提交冲突进行合并 下载和安装 GIT官方网址:http:// gi ...
- git 入门教程之远程仓库
远程仓库 如果说本地仓库已经足够个人进行版本控制了,那么远程仓库则使多人合作开发成为可能. 如果你只是打算自己使用git,你的工作内容不需要发布给其他人看,那就用不到远程仓库的概念. git 是分布式 ...
- Git入门教程,详解Git文件的四大状态
大家好,欢迎来到周一git专题. git clone 在上一篇文章当中我们聊了怎么在github当中创建一个属于自己的项目(repository),简称repo.除了建立自己的repo之外,我们更多的 ...
- Git入门教程
参考文献: 1. Pro Git 2. Git教程 3. Git教程 4. 图解Git
- git 入门教程之备忘录[译]
备忘录[译] 创建 | Create 克隆一个已存在的仓库 | Clone an existing repository git clone git@github.com:snowdreams1006 ...
- git 入门教程之本地和远程仓库的本质
本地仓库和远程仓库在本质上没有太大区别,只不过一个是本地电脑,一个是远程电脑. 远程仓库不一定非得是 github 那种专门的"中央服务器",甚至局域网的另外一台电脑也可以充当&q ...
随机推荐
- Python编程Day3—基本运算符、数据类型
一.基本运算符 1.算数运算 print(10/3) print(10//3) print(10%3) print(10**3) 2.比较运算 print(10==10) print(10!=10) ...
- Velocity CheckingForNull
Q: I want to check for null, something like this: #if ($car.fuel == null) A: There are several appro ...
- Android利用Intent与其他应用交互
前言: 上一篇博客给大家聊了Intent的定义,分类.属性和功能,相信大家对于Intent在Android中的作用已经清楚,这一篇博客将会给大家聊Intent的用法. Android系统的一个重要特性 ...
- 项目ITP(三) 玩玩 服务端 到 app端
前言 系列文章:[传送门] 泡泡脚,写写博客,规律生活,睡个好觉,待会看会书. 正文 上面讲了二维码生成,及 手机端扫一扫,大家有兴趣去看看. 今天我们讲一下,百度云推送平台. 每天想着问题,问题只会 ...
- sudo的使用和配置
1 sudo是什么 Sudo是Unix/Linux平台上的一个非常有用的工具,它允许系统管理员分配给普通用户一些合理的“权利”,让他们执行一些只有超级用户或其他特许用户才能完成的任务,比如:运行一些像 ...
- C# 通过java生成的RSA公钥加密和解密
最近工作需要将对方公司生成的RSA加密公钥进行明文加密和解密,发现了几点贴出来做个笔记. RSA单次加密是有长度限制!微软封装的加密方法如果出现长度超出指定范围的话报错是直接报“该项不适于在指定状态下 ...
- linux四剑客-grep/find/sed/awk/详解-技术流ken
四剑客简介 相信接触过linux的大家应该都学过或者听过四剑客,即sed,grep,find,awk,有人对其望而生畏,有人对其爱不释手.参数太多,变化形式太多,使用超级灵活,让一部分人难以适从继而望 ...
- jquery获取checkbox是否选择的值
//是否被选中验证有选中的设置为true,否设置为false function myCheckbox() { flag += 1; if (flag%2 == 0){ $('#isSelf').att ...
- T-SQL :SQL Server系统数据库(二)
master:master数据库储存实例范围的元数据信息,服务器配置,实例中的所有数据库信息和初始化信息. Resource:Resource数据库是一个隐藏,只读数据库,存储所有系统对象的定义.当查 ...
- Hibernate入门(一)
1.导包 导入Hibernate最基本的包(不要忘记导入数据库驱动包了!) 下载文件名为黄色框框中的名称的压缩包在对应路径下,有个required包下的所有包就是必备的基本包 2.建表 USE TES ...