前言
git 作为日常开发中最常用的版本控制工具,已经成为多人协同开发中不可或缺的部分。随着 IDE 功能的不断集成发展,我们开始更依赖于使用 IDE 中的集成命令,来进行代码提交和版本管理。
然而,这也使得很多人并不了解 git 的底层命令和工作原理,所以本篇文章就使用 git 命令行操作,深入探究一下在脱离IDE的情况下,git 是如何工作的。
工作区域
首先,我们先认识 git 的工作区域,在 git 中,不同的命令是对不同的 git 工作区域进行操作。
如图,git 一共分为四个区域,其中三个区域是在个人电脑上,一个是在远程服务器上。
- 工作目录:工作目录就可以理解为磁盘上所有的文件和文件夹
- 暂存区:暂存区是一个临时保存修改的区域,用于commit之前暂存你的改动,执行 git add 你的修改会被放入暂存区。
- 本地仓库:当你执行 git commit 时,暂存区的内容会被提交到本地仓库中
- 远程仓库:指的是 gitee、github 这样的代码托管平台,当你执行 git push 时,本地仓库的 commit 就会被推送到远程仓库。
git init
在需要版本管理的文件下,执行 git init 初始化,在当前目录下就生成了 .git 隐藏文件夹,里面记录了 git 信息。
新建aqi文本,在里面输入一行 Hello World,此时我执行 git status 查看工作区状态。
git操作
在 git 中,最基本的操作就是 git add 和 commit。git add 负责将文件和变更提交到暂存区,commit 则是将暂存区的变更提交到本地仓库。
git add
提示你aqi这个文件,需要执行 git add 进行跟踪,那么我们执行 add 之后,aqi就被放到了暂存区,再 git status 查看工作区状态。
这时候,在 workspace 工作区中就没有未被跟踪的文件了,而 aqi 就成了暂存区要提交(commit)的变更。这样,你可以选择性地提交部分改动,而不是整个工作目录的状态。
git commit
执行 git commit 将暂存区的变更提交到本地仓库, -m 指定提交信息。
提交完成之后,使用 git log 可以看到提交日志,这时候暂存区已经没有了可以提交的变更。
此时,如果修改aqi,新增一行 Hello qi,再查看工作区状态,提示aqi有可提交的变更。
也就是说,加入暂存区被跟踪的文件,在 workspace 中只要修改,就能被捕捉到变更,这时候就要执行 git add 将这些变更更新到暂存区,然后 git commit 提交到本地仓库。
和第一次 git add 将文件添加到暂存区不同的是,这次只是提交变更到暂存区,所以可以使用 git commit -a 来合并 add 和 commit 命令。
提交变更之后,又多了一条提交日志。我在aqi中又新增一行 “Hello a”,然后 git add 提交到暂存区。
再 git commit提交到本地仓库,这两步操作和合并命令结果是一样的。
至此,本地仓库中已经有了三条提交信息。
分支branch
在讲完 git 的常用命令之后,再结合 branch 分支命令深入探讨一下 git 的工作区域。git 中的默认分支是 master,不同的 branch 可以完成不同的代码开发和变更,在本地仓库也会有各自的提交信息。
git branch
使用 git branch 新建一个dev分支,git checkout 切换到dev分支。
git branch 也可以查看分支信息,*星号指向当前所在的分支。*此时,dev 是基于本地仓库中 master 分支生成的,所以此时 dev 和 master 分支的提交信息是相同的。
在 dev 分支下,我再添加一行数据,如下图所示:
然后 git status 查看工作区已经有了aqi的变更信息。
这里需要明确的是:文件的变更我是在dev分支进行的,文件变更没有add到暂存区,而是在 workspace 中。当我切换到 master 分支上,查看 aqi,居然看到了在dev分支是的变更。
这也就意味着,workspace区域是分支之间共享的。 在 master 分支下,我执行 git add 将 workspce 中的变更提交到暂存区。然后我再 checkout 切换到dev分支。
当我再次查看aqi,虽然在master分支将变更更新到了暂存区,但是dev分支仍可以看到变更的数据。
所以,暂存区也是分支之间共享的。这次我在 dev 分支上,直接 git commit 到本地仓库。
这时候再 checkout 到master分支,就看不到aqi中的第四行数据了。总结:对于所有分支而言,工作区和暂存区是公共的,已add未commit的内容不属于任何一个分支。只有commit到本地仓库,变更才会归属到具体的分支。
我们在 dev 和 master 分支下分别执行 git log。
如上图,dev 相对于 master 而言,已经多了一条提交信息。此时将 git log 界面展示,如图:
dev 是在3时基于 master 生成的,所以 dev 也有1 ~ 3的提交信息。此时,master 分支的 HEAD 指向3,dev 分支的 HEAD 指向4,两个分支的 aqi 文件此时内容也是不一样的。
冲突
在 master 分支上,我在aqi中,新增了一行数据“Hello master”。然后我 git add 更新到了暂存区。
这时候,我想 checkout 到 dev 分支,就会切换失败,提示在 checkout 之前,要将暂存区的变更 commit 或者 stage。
我们按照提示,将变更提交到本地仓库,然后就成功 checkout 到了dev分支。
为什么之前分支修改了 aqi 文件之后,不需要 commit 就能切换到另一个分支,而这次在 master修改了就得先 commit 才能 checkout?
原因就是当时 master 和 dev 分支的HEAD指向的都是3,所以此时两个分支的 aqi 文件都是一样的,不会造成冲突。但是这次修改时,master 分支的 HEAD 指向3,而 dev 分支的 HEAD 指向的是4, 而暂存区的变更是共享的,你在 3 的基础上做的变更,想要共享到4上,岂不是会造成冲突。
在 master 提交之后, 在界面化查看分支情况。
master 和 dev 分支都有了不同的提交信息。