原创 | Git入门教程,详解Git文件的四大状态

2020-09-07 00:00:00 命令 文件 提交 状态 改动

大家好,欢迎来到周一git专题。

git clone

在上一篇文章当中我们聊了怎么在github当中创建一个属于自己的项目(repository),简称repo。除了建立自己的repo之外,我们更多的情况是拷贝别人的repo,这样才可以获得别人整理好的代码资料什么的,也更符合开源(白嫖)精神嘛。

这也不是什么难题,相信很多人都知道,当我们想要获取其他人的repo的时候,可以通过git clone命令进行拉取。比如你想要获取我们这个教程的repo,可以通过下面这个命令。

git clone git@github.com:moutsea/git-tutorial.git

这个命令我们都知道,通过git clone再加上repo的地址就可以了。但是这里的地址是哪里来的呢?简单介绍一下,这是在github当中找到的。我们点击Code那个绿色按钮,在下方的弹框里点击一下,就可以复制下来。一般情况下我们默认使用SSH协议,如果你看过我们上篇文章的话,你一定知道我在说什么。当然你也可以用HTTPS。

还有一个问题是我们clone下来的这个repo它存在哪里呢?答案也很简单,就是我们在哪里运行的命令它就存在哪里。

另外再说一个小技巧,我们这样clone下来之后会在我们本地新建一个文件夹,然后把这个repo当中的内容存在里面。这个文件夹的名字默认是这个repo的名字,如果你不喜欢这个名字,也可以在命令当中进行设置,设置的方法也很简单,就是在命令后加上一个你想要起的名字。

比如这样,你得到的文件夹就是TechFlow。

git clone git@github.com:moutsea/git-tutorial.git techflow

git 四大状态

即使是git新手应该也都知道git三板斧,也就是常说的git add,git commit和git push。但是当我们使用这些命令的时候,有没有想过我们为什么要用这些命令呢?它们究竟代表了什么含义,这么做的意义是什么,如果我们不这么干又会发生什么?

如果我只是简单地告诉你git add就是添加,git commit就是提交,那么其实一点用也没有,和没说一样。因为关于git底层的运行机制一点也没提,我们也不知道为什么要添加,要提交,提交了添加了意味着什么。所以要解释清楚git这三板斧的原理,需要我们做一些更细致地解释,至少需要把git内部的四个状态讲清楚。

在我们进行这一段之前,首先和大家明确一个概念,就是git系统和我们计算机当中的文件系统其实是两码事。虽然git有很多神奇的操作,可以自由地回滚或者是创建文件,但它们依然是两套系统。git并不会自发地感知文件系统当中文件的变更,除非我们执行相关的命令。可以理解为它是被动响应的,毕竟git只是我们安装的一个软件,并不是操作系统的一部分。

这一点看似是废话,但是是很重要的基础,如果没搞明白,后面会产生很多疑惑。

我们继续来说git内部的状态,这四个状态分别是untrack,modified,committed和staged。之所以用英文,是为了大家以后阅读其他文档不会产生歧义。因为大家翻译的译名可能有多个版本,这会导致歧义。下面来简单介绍一下这几个状态分别意味着什么。


untrack

首先是untrack,untrack我们直译就可以了。track有轨道以及记录的意思,所以untrack就是还没记录。那么什么样的东西是还没记录的呢?比如可以想到新生儿,刚出生的新生儿名字都没有,当然也没有记录在案,所以需要登记一下人口。那么在登记之前,就可以认为这些新生儿是untrack的。

迁移到开发当中来,我们新创建的文件其实就是系统里的“新生儿”。在我们将它们记录在案之前,它们的状态就是untrack。所以当你在一个git项目当中新建了文件的时候,如果你用git status命令去查看git当中的状态,就会看到系统会提示你有些文件状态是untrack。

这里的展示是乱码,是因为我用的中文。这一串乱码就是“第三篇”的意思。我们可以注意到,在输出的结果后一行,系统提示我们可以用git add命令来track它。这个也是git很人性化的一点,很多时候它会提醒我们可以使用什么命令做成什么样的事情。所以大家千万不要忽视这些日志,里面的信息是很重要的。


modified

下一个说的状态是modified,modified顾名思义就是修改过的意思。针对的就是已经登记在案的文件近又发生了改动的情况,也就是说我们近改过了某一个之前已经登记在案的文件,那么当我们查看状态的时候得到的就是modified,表示改动了,之前的记录已经不是新的了,我们需要更新。

同样,我们可以通过git status命名来查看modified的情况。

我们看下方的红字,它说的是“第三篇”这个文件我们已经有了新的改动,可以使用git add命令来将它更新,或者是使用git restore命令来取消这个文件的登记信息,也就是让他回到“新生儿”的状态。


staged

接下来介绍的状态是staged,它没有很好的翻译,可以大概理解成暂存。也就是说我们把所有的改动都记录下来了,现在git系统当中记录的已经是这个文件新的状态了。

当我们创建了新的文件,或者是有了新的改动,执行git add之后,得到的状态就是staged。这个时候当我们执行git status,就会看到我们当下创建和更新了哪些文件。注意在所有的改动都暂存的情况下,git status是不会出现红色的提示的,只会有绿色的提示信息。

当然这里的文字之所以有颜色是因为我使用了zsh这个终端,如果不配置是没有的,就只能看到白色的的文字。zsh这个终端只在Linux和MacOS当中有,windows没有。而win的终端和系统一直被程序员们吐槽难用,建议有条件的同学可以研究一下Linux,装个虚拟机也好。

当我们终端没有颜色高亮的时候,就只能通过上面的文本来判断了,如果出现了Untracked files或者是Changes to be committed这些提示语的话,说明你还有改动没有同步到git当中来,可以通过git add命令完成。


committed

后讲的一个状态就是committed,这个committed表示的已提交。前面说了staged只是暂存,还没有真正提交进git系统当中。只有通过命令git commit之后,才算是真正把暂存区的代码提交了。经过git commit命令之后,所有被提交的文件的状态就是committed。

这个时候如果我们执行git status再来查看,会看到提示nothing to commit, working tree clean.

这就表示我们所有的改动都已经提交进本地的git仓库当中了,以后及时我们不小心删错了代码,或者是做了一些修改。只要本地的git仓库还在,这些代码就都还可以找得回来。一直到这里为止,我们所有的操作都是离线的,都不需要网络参与。这也是我们前文说的git的一个优点之一。

git commit之后,我们就可以通过git push来把本地的改动同步到远程了。当然这一步是肯定需要网络的,并且也可能会遇到很多问题,其中也有很多细节,我们之后再详细展开。

我们用一张图来总结一下上面提到四种状态,以及git的整个工作流来加深一下印象。

总结

看完了上面关于git状态的介绍之后,想必大家就可以明白,我们在使用git的时候,常用的三板斧也就是git add,git commit以及git push的命令究竟是干嘛的了。

git add可以把所有的改动,无论是修改的还是新建的都存入暂存区。git commit可以将暂存区的改动提交到本地git仓库,后git push可以把本地仓库的改动同步到远端。看起来好像平平无奇对吧,但我们仔细琢磨会发现一个很奇怪的点,那就是既然我们git add和git commit都是提交,只不过是提交的目的地不同,一个是暂存区一个是本地仓库。那么为什么我们不能直接将它们合并呢?我们git add就是直接提交到本地仓库不行吗?

实际上SVN这个版本控制工具就是这么做的,但是这有一个问题就是当我们提交的时候,它会让我们选择我们要提交的文件。如果改动量小还好,如果改动量很大,我们要手动去一个一个输入需要提交的文件显然是一个非常麻烦的事情。而有了暂存区之后,我们就可以在开发的时候,一边开发一个边把文件提交到暂存区,后直接一起commit到仓库就可以了。就可以避免后提交之前的麻烦了,因为反正提交这个操作一定是原子的,要么全部成功,要么全部失败,是不允许部分成功这种情况发生的。

而且很多极客更加喜欢在终端环境当中操作代码,而不是在一个弹出来的界面里点点点,这会让他们觉得非常不极客(逼格太低)。有了暂存区之后就可以很方便地做到这一点。

到这里,我们的文章就结束了,感谢您的阅读。相信看完之后,对于git当中的状态以及它们的作用应该有了一个基础的了解,并且应该还学到了一个装逼技能,就是问你的小伙伴,你知道为什么git里有一个暂存区而SVN里没有吗?因为不极客。

衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、在看、转发

- END -

相关文章