git 入门教程之版本控制 原

版本控制

我们知道 git 是分布式版本控制系统,所以称被控制对象是版本本身没错,但是从git 命令中发现,并没有版本这个名词,有的只是commit,所以前几节我一直称其为提交.

为了避免后续教程引发歧义,特意说明,无论是版本也好,提交也罢,都是中文翻译而已,不必太过较真,直接原汁原味称commit也可以啊!

假设你已掌握暂存区的相关概念,简单来说,暂存区就是更改文件的缓存集合,等待一次性全部提交到版本库,正因如此,方便我们批量操作相关性文件,打包提交到版本库,这正是暂存区的独特魅力.

我们反复在说 git 是分布式版本控制系统,分布式的概念已经粗略讲过多次了,下面我们讲一下版本控制,谈谈 git 的版本控制和其他系统的版本控制有什么不同,为什么 git 这么优秀,如此流行?

git 跟踪并管理的是更改,而非文件本身.正如linux 一切皆文件,java 一切皆对象一样,git 一切皆更改.新增文件是一个更改,新增文件内容是一个更改,修改文件内容是一个更改,删除文件内容也是一个更改,换言之,git 管理的正是这一个个的更改,并不是文件本身.

下面我们用事实说话,证明 git 管理的是更改而不是文件本身:

第一步,追加 git tracks changestest.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
$ 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 fielsgit 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 版本控制的是文件的更改,而不是文件本身,是全量更新模式,而不是差量更新模式.

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Hadoop实操

0541-6.1.0-如何为Cloudera Manager设置反向代理

在复杂的网络环境下,总会遇到办公网络因为端口放通问题无法访问生产网或其他网段的服务,可以通过部署Nginx服务实现跨网段的多个服务反向代理(确保Nginx所在服...

27630
来自专栏日常学python

还在为面试心慌慌,69道面试题,助你提升功力

上周很多同学都考完试放假了,常舒了一口气,但是准备找工作的同学还是心慌慌,明年的春招压力更大,笔试题,面试题,算法题怎么破,有没有好的网站,资料可以参考? 周末...

16230
来自专栏新智元

盘点NLP最新进展:多语种40+任务最优结果任你查

本文实际上是一个索引,旨在记录自然语言处理(NLP)领域的新进展,并概述最常见的NLP任务及其相应数据集的新技术。

15920
来自专栏机器学习算法与Python学习

开源星际争霸2多智能体挑战smac

SMAC是Github上的一个用于在暴雪星际争霸2上进行多智能体协同强化学习(MARL)的环境。SMAC用了暴雪星际争霸2的机器学习API和DeepMing的P...

12620
来自专栏新智元

中文NLP福利!大规模中文自然语言处理语料

众所周知,中文NLP领域缺乏高质量的中文语料。作者徐亮(实在智能算法专家) 创建了一个中文自然语言处理语料库项目:nlp_chinese_corpus ,初步贡...

1.1K20
来自专栏日常学python

这里告诉你如何用Python下载各大平台上的音乐

今天给大家推荐一个 GitHub 上的 Python 项目,可以从各大音乐平台上下载音乐歌曲到本地,支持的平台有网易云音乐、QQ音乐、酷狗音乐、百度音乐、虾米音...

19040
来自专栏java思维导图

四天3500+star,快速浏览文件修改记录的Git History

开发者 pomber 开源了一个可以轻松快速浏览 GitHub 文件操作历史记录的工具 Git History。

8230
来自专栏Hadoop实操

0545-Cloudera Manager中Entryopy警告处理

在使用CDH集群的过程中,有时会在Cloudera Manager的控制台上看到关于Entropy的告警如下显示:

23840
来自专栏Hadoop实操

0542-6.1.0-非安全环境下Kafka管理工具Kafka Eagle安装使用

Fayson在前面的文章介绍了《如何在CDH集群安装Kafka Manager》,本篇文章Fayson介绍另外一款的监控工具Kafka-eagle,它可以同时监...

25470
来自专栏Hadoop实操

0540-5.15.0-Spark2使用HBase-Spark访问HBase

越来越多的用户使用Spark对接HBase,对接HBase的方式有多种,通过HBase-client API实现,也有直接Spark On HBase的方式实现...

93340

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励