图解Git

这篇文章旨在以图象的形式介绍 Git 的常见用法,包括 文件夹的初始化添加文件、提交快照、分支的管理的等。代码部分从上到下是在均是在一个仓库中完成的,对于第一次出现的 git 命令均标识出命令的功能。 但是文章的简洁,对于上文出现的命令就能够的完成的任务有时使用注释代替。

git 的基本使用

如下图所示,git 概念上将文件的分为了以下的三个阶段:工作区、暂存区、git仓库区。当你在工作区修改代码以后,你需要使用 git add 命令让文件”进入”暂存区,这实际上是在告诉 git 系统: 文件发生了修改,你需要注意记录它的更改情况。当文件进入暂存区之后,git 便记录了当前的文件的变化。在这之后,当你使用git commit 命令,git 系统会生成暂存区的快照,并快照永久性存储到”git 仓库”。

(这个时候,当你再次更改文件时,你需要再次使用 git add 命令)

1
2
3
4
5
6
7
//一个典型的 git 使用过程如下
git init GitPractice//使用 git init 命令初始化 GitPractice 文件夹
cd GitPractice && touch 1.sh //在工作区新建了一个文件
git status //显示当前的状态(此时 git 检测到新建了一个文件,但是当前文件的状态是 untracked 的,所以 git 系统并不能对它进行跟踪)

git add 1.sh //提交当前文件到暂存区
git commit -m "新建1.sh文件" //生成快照,并永久存储

当使用 git commit 进行提交操作时,Git 会先计算目录的校验和, 然后在 Git 仓库中保存这些信息(其实是更详细的信息参见[1])。

当我们再次新建 2.sh 文件,并执行 git add 2.sh 和 git commit -m “新建2.sh文件” 提交一次快照后, git 记录了之前和现在的快照信息(17734da 和 aed2f4a 表示两次不同的快照信息)

1
2
3
4
git log //显示提交历史
git reset 17734da//使用 git reset hash值,可以丢弃 git commit 的提交返回到之前特定的版本
//git reset -- 文件名 则是退回某个文件到指定版本
git status //检查当前的状态

而使用 “git reset HEAD 文件名”则可以丢弃掉使用 git add 命令添加到 暂存区 的修改。

1
2
3
4
//回到 master 分支 修改 2.sh,使用 git add 提交到 暂存区
git reset -- 2.sh //丢弃这次 git add 命令的提交
git checkout -- 1.sh //在工作区丢弃文件的修改
//git checkout 快照值 -- 文件名 则能将快照中的文件覆盖当前的文件

注意,之前从未使用”git add”添加的文件,这时 git 并没有对这个文件进行跟踪,所以不能使用 git checkout – 命令丢弃修改

Git 中的分支

Git 保存的不是文件的变化或者差异,而是一系列不同时刻的快照。Git 维护两个指针分别是: master 指向的是当前的主分支,head 则表示当前所在的位置。

1
2
git branch fixbug //创建名为 fixbug 的分支
git checkout fixbug //通过这条命令能够很快的切换到 fixbug 分支

此时 masterfixbug 指向同一个文件快照。

1
2
3
git log //查看系统提交记录和分支情况
touch 3.sh
git commit -am "新建 3.sh"

在我们提交一次快照之后,git 系统的状态如下:


系统保存了这次的快照,fix_bug 分支因此也向前移动了一步。

HEAD 指向的当前所在的分支,所以也跟着一起移动了

试想一下,如果此时你切换回 master ,并提交一次快照之后会发生什么。这一次提交的修改会合并到 fixbug 分支吗?
答案显示是否定的,此时系统会产生分叉。

1
2
3
git branch // 显示所有分支以及当前分支
//回到 master 分支,并提交一次快照
git log --oneline --decorate --graph --all //显示分支和分叉情况

Git-Bifurcation
如果我们这个时候再提交一次修改时,会发生什么? 无非就是 新建一个”节点”, main 和 head 向前移动一步而已

当我们在 fix_bug 分支,完成 debug 任务以后,我们就能够将 fix_bug 中的代码合并到 master 分支中去。

1
2
git branch -d fixbug //删除 fixbug分支
git log --oneline --decorate --graph --all

参考