最新超详细的万字Git分支教程(保姆级别),2024年最新10天用Flutter撸了个高仿携程App

学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

【示例代码】

初始化项目:

rm -rf .git ./*
git init
echo '用户名+密码登录' >> login.txt
git add ./
git commit -m '用户名+密码登录功能完成' ./

①创建login分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all
2f5d87a (HEAD -> master, login) 用户名+密码登录功能完成

②切换到login分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
2f5d87a (HEAD -> login, master) 用户名+密码登录功能完成

③使用login分支开发:集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成QQ登录" >> login.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成QQ登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
a879a6c (HEAD -> login) 集成QQ登录
2f5d87a (master) 用户名+密码登录功能完成

④使用login分支开发:集成微信登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成微信登录" >> login.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成微信登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all
c5a2584 (HEAD -> login) 集成微信登录
a879a6c 集成QQ登录
2f5d87a (master) 用户名+密码登录功能完成

当login分支基于稳定后,将功能集成到maste分支:

  • 如图所示:

⑤切换回master分支,将login分支的代码合并到master分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat login.txt
用户名+密码登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git merge login
Updating 2f5d87a..c5a2584
Fast-forward
 login.txt | 2 ++
 1 file changed, 2 insertions(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat login.txt
用户名+密码登录
集成QQ登录
集成微信登录

将login分支的代码合并到master分支,其实本质上就是让master也指向与login一样的提交对象;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# master与login分支指向的是同一个Commit对象
$ cat .git/refs/heads/login
c5a258428f0bec398017159126f0b87b0d05a1e4
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat .git/refs/heads/master
c5a258428f0bec398017159126f0b87b0d05a1e4

1.4.2 典型合并
  • 非同轴开发的典型合并:

非同轴开发:创建一个新分支,使用新分支开发,与此同时master分支也在开发行功能,等到新分支开发的功能完毕后,将master分支与新分支进行合并,将新分支集成到master分支中,但是新分支在开发过程中master分支也进行了一部分开发。

==在非同轴开发中,后面的版本(v3)需要合并前面的版本(v2),这种合并方式称为典型合并;==由于典型合并存在于非同轴

  • 如图所示:

需要注意的是,如果是同轴开发,后面版本的内容肯定包含前面版本的内容,因此==同轴开发不存在典型合并==,只存在快进合并。另外,非同轴开发也存在快进合并,例如上图中的③步骤中,前面的版本(v2)想要合并后面的版本(v3),这也是一种快进合并。

总结:

  • 同轴开发:只存在快进合并
  • 非同轴开发:
    • 前面的版本合并后面的版本:快进合并
    • 后面的版本合并前面的版本:典型合并

Tips:典型合并必定是非同轴,快进合并可以是非同轴也可以是同轴。

【示例代码】

初始化项目:

rm -rf .git ./*
git init
echo '用户名+密码登录' >> project.txt
git add ./
git commit -m '用户名+密码登录功能完成' ./

①创建login分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看不同轴的日志需要加上--graph
$ git log --oneline --all --graph
* 7c0b2a3 (HEAD -> master, login) 用户名+密码登录功能完成

②切换到login分支,使用login分支进行开发:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ echo "集成QQ登录" >> project.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git commit -m "集成QQ登录" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
* 9c968e0 (HEAD -> login) 集成QQ登录
* 7c0b2a3 (master) 用户名+密码登录功能完成

③切换回master分支添加注册功能:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看master分支的project.txt文件,代码并没有合并过来
$ cat project.txt
用户名+密码登录
添加头像上传功能

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看日志,处于不同轴开发路径
$ git log --oneline --all --graph
* fecdb41 (HEAD -> master) 添加头像上传功能
| * 9c968e0 (login) 集成QQ登录
|/
* 7c0b2a3 用户名+密码登录功能完成

④将login分支的合并到master分支:产生代码冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git merge login
Auto-merging project.txt
CONFLICT (content): Merge conflict in project.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
<<<<<<< HEAD
添加头像上传功能
=======
集成QQ登录
>>>>>>> login

解决代码冲突:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
<<<<<<< HEAD
添加头像上传功能
=======
集成QQ登录
>>>>>>> login

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ vi project.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat project.txt
用户名+密码登录
添加头像上传功能
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ git commit -a -m "合并login分支,并解决代码冲突"
[master 9ccdde2] 合并login分支,并解决代码冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   9ccdde2 (HEAD -> master) 合并login分支,并解决代码冲突			# 解决冲突后提交产生一次新的版本
|\
| * 9c968e0 (login) 集成QQ登录
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

经过上一次合并后,master与login属于同轴了,当切换为login分支,可以使用快进合并来合并master分支;

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 切换为login分支
$ git checkout login
Switched to branch 'login'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# login分支的代码
$ cat project.txt
用户名+密码登录
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
*   9ccdde2 (master) 合并login分支,并解决代码冲突
|\
| * 9c968e0 (HEAD -> login) 集成QQ登录			
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# 合并master分支
$ git merge master
Updating 9c968e0..9ccdde2
Fast-forward
 project.txt | 1 +
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)			# 查看login分支的代码,发现master的代码被合并过来了
$ cat project.txt
用户名+密码登录
添加头像上传功能
集成QQ登录

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (login)
$ git log --oneline --all --graph
*   9ccdde2 (HEAD -> login, master) 合并login分支,并解决代码冲突
|\
| * 9c968e0 集成QQ登录
* | fecdb41 添加头像上传功能
|/
* 7c0b2a3 用户名+密码登录功能完成

1.5 Git的代码冲突

1.5.1 Git的代码冲突的分类与特点

Git存在代码冲突的情况分为协同开发时的代码冲突分支合并时的代码冲突;其中分支合并时的代码冲突又分为快进合并代码冲突典型合并代码冲突

另外还需要注意的是,Git与SVN的代码冲突逻辑不一致。

Tips:我们本章主要讨论分支合并时的代码冲突。

  • 在SVN中:只要两个用户编辑的不是同一行则不会出现代码冲突。
  • 在Git中:只要两个文件内容不一致,在合并分支时必定会产生冲突,无论两个文件是否编辑的是同一行。不过具体情况还得细分如下:
    • 快进合并:两个分支属于不同轴开发,前面版本合并后面版本时,只要两个文件不一致,合并时必定出现冲突,不管两个分支编辑的是不是同一行。
    • 典型合并:由于典型合并两个分支属于不同的开发轴,而后面的分支想要合并前面的分支,两个文件必定不一致,因此典型合并必定出现代码冲突。

Tips:同轴开发的快进合并是不会产生冲突的。

【SVN代码冲突模拟】

SVN的情况:两个用户编辑的代码是同一行则出现冲突

xiaohuixiaolan
创建abc.txt
内容为:
111
222
执行add
执行commit
执行update
修改内容为:
111aaa
222
执行commit
修改内容为:
111bbb
222
执行update(冲突)

如果"xiaolan"用户最后更改的文件内容为:

111
222bbb

然后再执行update,则不会出现代码冲突,因为SVN判断代码冲突的代码单元为行,即:两个用户编辑的不是同一行就不会出现代码冲突。

1.5.2 快进合并代码冲突

快进合并属于前面的版本合并后面的版本,需要注意的是==前面的版本并非是"旧版本",后面的版本并非是"新版本"==,这主要取决于是否是同轴开发。对于同轴开发,后面的版本自然是新版本,其内容肯定包含前面版本的内容。但对于非同轴开发,后面的版本内容大概率是不包含前面的版本内容的;

在同轴开发情况下,快进合并不会产生代码冲突,但如果在非同轴开发情况下,快进合并就会产生代码冲突了。我们观察下列操作:

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
切换回master分支,合并test分支,属于快进合并,但会出现冲突

Tips:注意,上述操作在SVN中则不会认为是冲突,因为SVN判断是否冲突的标准是操作同一个文件的同一行记录;

  • 快进合并冲突演示:

【使用Git演示代码冲突】

①初始化项目

rm -rf .git ./*
git init

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "111 222" ./

②创建test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch test

③继续使用master分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* d40d605 (HEAD -> master, test) 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* 09fe9cb (HEAD -> master) aaa
* d40d605 (test) 111 222

④切换到test分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 注意,和master分支修改的文件内容不是同一行
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git commit -m "bbb" ./
[test dfe1b42] bbb
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 查看日志,test与master分支已经不同轴
$ git log --oneline --all --graph	
* dfe1b42 (HEAD -> test) bbb
| * 09fe9cb (master) aaa
|/
* d40d605 111 222

⑤切换回master分支,合并test分支,出现冲突:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)			# 切换回master分支
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 合并test分支,属于快进合并,但是会产生冲突
$ git merge test
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111aaa
222
=======
111
222bbb
>>>>>>> test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)
$ cat aaa.txt
111aaa
222bbb


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master|MERGING)			# 解决冲突
$ git commit -a -m "master合并test分支"
[master adaec78] master合并test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (HEAD -> master) master合并test分支
|\
| * 7b14536 (test) bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

需要注意的是:此时切换回test分支,合并master分支内容不会出现冲突(属于快进合并,但是内容不一致,但不会出现冲突):因为master分支的内容是刚刚解决了冲突之后用户确定了的内容。

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (master) master合并test分支
|\
| * 7b14536 (HEAD -> test) bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git merge master
Updating 7b14536..adaec78
Fast-forward
 aaa.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   adaec78 (HEAD -> test, master) master合并test分支
|\
| * 7b14536 () bbb
* | eeca4c9 aaa
|/
* 5f41035 111 222

1.5.3 典型合并代码冲突

典型合并时的代码冲突就是我们之前遇到的那种情况,典型合并属于不同轴的开发,并且后面版本需要合并前面版本的情况,由于不同轴,因此后面版本的内容不一定包含前面版本的内容,由于Git代码冲突的特点,因此典型合并必定会出现代码冲突,因为后面版本的内容不可能和前面版本内容一致。

我们观察下列操作:

master分支test分支
创建abc.txt
内容为:
111
222
执行add
执行commit
创建分支 – 此时test分支的abc.txt的内容也是111、222
修改内容为:
111aaa
222
执行commit
切换到test分支
修改内容为:
111
222bbb
执行commit – 此时test分支和master分支已经不同轴了
合并master分支的代码,属于典型合并,出现代码冲突。
  • 典型合并冲突演示:

【使用Git演示代码冲突】

①初始化项目:

rm -rf .git ./*
git init

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "111 222" ./

②创建test分支

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git branch test

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* 45fa06b (HEAD -> master, test) 111 222

③继续使用master分支开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout master
Already on 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m "aaa" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
* c86283b (HEAD -> master) aaa
* 45fa06b (test) 111 222

④切换到test分支,继续开发

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout test
Switched to branch 'test'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ cat aaa.txt
111
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git commit -m "bbb" ./
[test e61df5a] bbb
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
* e61df5a (HEAD -> test) bbb
| * c86283b (master) aaa
|/
* 45fa06b 111 222

⑤使用test分支合并master分支(属于典型合并)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git merge master
Auto-merging aaa.txt
CONFLICT (content): Merge conflict in aaa.txt
Automatic merge failed; fix conflicts and then commit the result.

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ cat aaa.txt
<<<<<<< HEAD
111
222bbb
=======
111aaa
222
>>>>>>> master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ vi aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test|MERGING)
$ git commit -a -m "合并master分支,并解决冲突"
[test 448d619] 合并master分支,并解决冲突

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
*   448d619 (HEAD -> test) 合并master分支,并解决冲突
|\
| * c86283b (master) aaa
* | e61df5a bbb
|/
* 45fa06b 111 222

同样的,如果此时切换回master分支,合并test分支虽然属于快进合并并且不同轴,但合并依旧不会出现冲突,因为test分支的内容是解决冲突并且经过用户确认之后的内容。

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git log --oneline --all --graph
*   448d619 (HEAD -> test) 合并master分支,并解决冲突
|\
| * c86283b (master) aaa
* | e61df5a bbb
|/
* 45fa06b 111 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (test)
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git merge test
Updating c86283b..448d619
Fast-forward
 aaa.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ cat aaa.txt
111aaa
222bbb

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all --graph
*   448d619 (HEAD -> master, test) 合并master分支,并解决冲突
|\
| * c86283b aaa
* | e61df5a bbb
|/
* 45fa06b 111 222

1.6 Git的分支状态存储

有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态,而这时你想要切换到另一个分支做一点别的事情。 但你必须将当前工作空间所做的操作提交到版本库,否则Git不允许切换分支;但是当前的操作还不足以生成一次版本快照,此时,我们就可以使用Git的存储功能,将当前工作状态存储起来,然后再切换到其他分支工作,最终工作完毕后切回当前分支,从Git存储中取出之前的工作内容;

1.6.1 Git存储引入

【初始化项目环境】

rm -rf ./* .git
git init
echo '111-master' >> aaa.txt
git add ./
git commit -m '111-master' ./
git branch b1
git checkout b1
echo '111-b1' >> aaa.txt
git add ./
git commit -m '111-b1' ./
echo '222-b1' >> aaa.txt
git commit -m '222-b1' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看分支详情
$ git log --oneline --graph --all
* 01ca592 (HEAD -> b1) 222-b1			# b1的位置
* 1337456 111-b1
* f828bbd (master) 111-master			# master的位置

编辑文件:

echo '333-b1' >> aaa.txt

编辑完了后还不想提交,此时接收到了新的"临时任务",想要切换到其他分支继续操作,发现切换失败:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 查看git状态
$ git status
On branch b1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")			# 有修改操作还未提交

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 切换到master失败
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        aaa.txt
Please commit your changes or stash them before you switch branches.
Aborting

1.6.2 Git存储的使用
1) 使用存储状态
  • 语法:
git stash list 		# 查看当前Git中存储的所有状态
git stath 			# 将当前状态保存
git stash apply {stashName}		# 根据存储名称读取Git存储
git stash drop {stashName}		# 根据存储名称删除Git存储

【使用Git存储将当前状态存储起来】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看当前Git存储列表,发现列表为空
$ git stash list

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 使用Git存储
$ git stash
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory
Saved working directory and index state WIP on b1: 01ca592 222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git stash list
stash@{0}: WIP on b1: 01ca592 222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 使用Git将当前状态存储起来后,文件内容变为了未更改前的内容
$ cat aaa.txt
111-master
111-b1
222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 再次查看git的状态,发现工作空间正常
$ git status
On branch b1
nothing to commit, working tree clean

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 查看日志,发现使用Git存储也会产生一次日志
$ git log --oneline --graph --all
*   082f406 (refs/stash) WIP on b1: 01ca592 222-b1
|\
| * c613227 index on b1: 01ca592 222-b1
|/
* 01ca592 (HEAD -> b1) 222-b1
* 1337456 111-b1
* f828bbd (master) 111-master

【当前状态被Git存储了,当前的工作空间也是正常的,因此可以切换到其他分支继续操作】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 切换分支到master
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看master分支的内容
$ cat aaa.txt
111-master

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ echo "222-master" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		
$ git commit -m '222-master' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --graph --all
* 4974e13 (HEAD -> master) 222-master
| *   082f406 (refs/stash) WIP on b1: 01ca592 222-b1
| |\
| | * c613227 index on b1: 01ca592 222-b1
| |/
| * 01ca592 (b1) 222-b1
| * 1337456 111-b1
|/
* f828bbd 111-master

2) 读取存储状态

等到"临时任务"处理完后,我们可以切换回test分支,并将上一次使用Git存储的状态读取出来

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 切换回b1分支
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 查看文件内容,依旧是没有编辑前的状态
$ cat aaa.txt
111-master
111-b1
222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 查看Git存储的状态
$ git stash list
stash@{0}: WIP on b1: 01ca592 222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 读取状态
$ git stash apply stash@{0}
On branch b1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")			# 读取成功后回到我们当初的状态(当前工作空间未提交)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)				# 查看文件内容,将文件内容还原回来了
$ cat aaa.txt
111-master
111-b1
222-b1
333-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git commit -m "333-b1" ./
[b1 1f0ebea] 333-b1
 1 file changed, 1 insertion(+)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git log --oneline --graph --all
* 1f0ebea (HEAD -> b1) 333-b1
| * 4974e13 (master) 222-master
| | * 082f406 (refs/stash) WIP on b1: 01ca592 222-b1
| |/|
|/| |
| | * c613227 index on b1: 01ca592 222-b1
| |/
|/|
* | 01ca592 222-b1
* | 1337456 111-b1
|/
* f828bbd 111-master

3) 存储状态的删除

Git存储被读取之后状态并不会被删除,我们可以手动删除存储状态

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 查看Git存储状态,发现依旧存在
$ git stash list
stash@{0}: WIP on b1: 01ca592 222-b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 手动删除状态
$ git stash drop stash@{0}
Dropped stash@{0} (082f40626ab35cf6b1bd413e634e0a1a946824aa)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 查看Git存储的状态,发现没有了
$ git stash list

1.6.3 Git存储的原理
  • 使用Git存储:

Git存储的原理其实是在使用git stash命令后,Git直接将当前工作状态的更改添加到暂存区,然后提交,中途生成了Blob对象、Tree对象、Commit对象等三个对象;其中Commit对象会生成2次,第一次指向原来的Tree对象,第二次指向新的Tree对象,之后再将暂存区改回原来的样子(执行git stash命令之前的样子)

由于当前工作空间的操作均已提交,因此当前工作空间的状态自然为nothing to commit,然后就可以切换到其他分支了;

当使用git stash命令以后,会产生两个Commit对象,其还会再.git/refs/目录创建一个名为stash的文件,该文件保存着最新Commit对象的hash值;

  • 读取Git存储状态的原理:

当使用git stash apply {stashName}命令读取Git存储状态时,其底层其实就是读取到stash文件中的Commit对象,通过该Commit对象找到执行git stash命令后生成的Blob对象,读取该Blob对象的内容写入当前工作空间,达到还原工作空间的目的。

  • 删除Git存储状态的原理:

在Git日志中查询不到了,然后将git/refs/stash文件删除掉

【准备环境】

rm -rf ./* .git
git init
echo '111' >> aaa.txt
git add ./
git commit -m "111" ./
git branch b1
git checkout b1

.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af
$ find .git/objects/ -type f
.git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c			# Blob对象
.git/objects/7d/811c6d8fa7794fc7a0a2371a4cf197e8cfb47d			# Commit对象
.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af			# Tree对象

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 查看当前暂存区
$ git ls-files -s
100644 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git log --oneline --all --graph
* 7d811c6 (HEAD -> b1, master) 111

1) 使用存储状态的原理

【编辑文件】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ echo "222" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git status
On branch b1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")


Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 使用Git存储
$ git stash
warning: LF will be replaced by CRLF in aaa.txt.
The file will have its original line endings in your working directory
Saved working directory and index state WIP on b1: 7d811c6 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git ls-files -s
100644 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 0       aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 暂存区没有变化
$ git cat-file -p 58c9bdf9
111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ find .git/objects/ -type f
.git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c			# Blob对象.v1
.git/objects/70/3a3923a3f4d516543ba3e6e9182467f31b328c			# Tree对象.v2
.git/objects/7d/811c6d8fa7794fc7a0a2371a4cf197e8cfb47d			# Commit对象.v1
.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af			# Tree对象.v1
.git/objects/99/11efb0f75f3280b2e8581bd83724e9a7a10528			# Commit对象.v2
.git/objects/a3/0a52a3be2c12cbc448a5c9be960577d13f4755			# Blob对象.v2
.git/objects/b3/e1f5cd5d92a906cff3dfc4816d6e22c72afffe			# Commit对象.v3

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看stash文件,保存的是最新Commit对象的hash值
$ cat .git/refs/stash
b3e1f5cd5d92a906cff3dfc4816d6e22c72afffe

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看Blob对象.v2
$ git cat-file -p a30a52a3be2c12cbc448a5c9be960577d13f4755
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看Tree对象.v2
$ git cat-file -p 703a3923a3f4d516543ba3e6e9182467f31b328c
100644 blob a30a52a3be2c12cbc448a5c9be960577d13f4755    aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看Commit对象.v2
$ git cat-file -p 9911efb0f75f3280b2e8581bd83724e9a7a10528
tree 8f96f2f60c766a6a6b78591e06e6c1529c0ad9af		# 包裹的是原来的Tree对象(v1版本)
parent 7d811c6d8fa7794fc7a0a2371a4cf197e8cfb47d		# 指向的是Commit对象.v1
author xiaohui <xiaohui@aliyun.com> 1697278938 +0800
committer xiaohui <xiaohui@aliyun.com> 1697278938 +0800

index on b1: 7d811c6 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看Commit对象.v3
$ git cat-file -p b3e1f5cd5d92a906cff3dfc4816d6e22c72afffe
tree 703a3923a3f4d516543ba3e6e9182467f31b328c		# 包裹的是新的Tree对象(v3)
parent 7d811c6d8fa7794fc7a0a2371a4cf197e8cfb47d		# 指向Commit对象.v1
parent 9911efb0f75f3280b2e8581bd83724e9a7a10528		# 指向Commit对象.v2
author xiaohui <xiaohui@aliyun.com> 1697278938 +0800
committer xiaohui <xiaohui@aliyun.com> 1697278938 +0800

WIP on b1: 7d811c6 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看日志,发现生成了两个Commit对象
$ git log --oneline --all --graph
*   b3e1f5c (refs/stash) WIP on b1: 7d811c6 111		# Commit对象.v3
|\
| * 9911efb index on b1: 7d811c6 111				# Commit对象.v2
|/
* 7d811c6 (HEAD -> b1, master) 111					# HEAD指针还是指向b1

2) 读取存储状态的原理
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 由于当前是Git
$ git checkout master
Switched to branch 'master'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)			# 读取Git存储
$ git stash apply stash@{0}
On branch b1
Changes not staged for commit:		
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   aaa.txt

no changes added to commit (use "git add" and/or "git commit -a")		# 工作空间状态恢复成原来的状态了

3) 删除存储状态的原理
Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git stash list
stash@{0}: WIP on b1: 7d811c6 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 删除Git存储状态
$ git stash drop stash@{0}
Dropped stash@{0} (b3e1f5cd5d92a906cff3dfc4816d6e22c72afffe)

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 发现stash文件已经被删除
$ ll .git/refs/
total 0
drwxr-xr-x 1 Adminstrator 197121 0 Oct 14 18:22 heads/
drwxr-xr-x 1 Adminstrator 197121 0 Oct 14 18:20 tags/

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git log --oneline --all --graph
* 7d811c6 (HEAD -> b1, master) 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ find .git/objects/ -type f
.git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c			# Blob对象.v1
.git/objects/70/3a3923a3f4d516543ba3e6e9182467f31b328c			# Tree对象.v2
.git/objects/7d/811c6d8fa7794fc7a0a2371a4cf197e8cfb47d			# Commit对象.v1
.git/objects/8f/96f2f60c766a6a6b78591e06e6c1529c0ad9af			# Tree对象.v1
.git/objects/99/11efb0f75f3280b2e8581bd83724e9a7a10528			# Commit对象.v2
.git/objects/a3/0a52a3be2c12cbc448a5c9be960577d13f4755			# Blob对象.v2
.git/objects/b3/e1f5cd5d92a906cff3dfc4816d6e22c72afffe			# Commit对象.v3

1.7 Git打标签

1.7.1 标签的语法与介绍

像其他版本控制系统(VCS)一样,Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0v2.0 等等)。

  • 创建标签:
git tag {tagName}						# 以当前状态创建标签 (轻量标签)
git tag {tagName} {commitHash}			# 以指定的提交对象来创建标签(轻量标签)

git tag {tagName} {commitHash} -m {注释}		# 以当前状态创建标签 (附注标签)
git tag {tagName} {commitHash} -m {注释}		# 以指定的提交对象来创建标签(附注标签)

  • 查看标签:
git tag						# 查看所有标签
git show {tagName}			# 查看特定标签

  • 删除标签:
git tag -d {tagName}

  • 检出标签:
git checkout {tagName}						# 检出到指定标签位置,会出现"头指针分离"现象
git checkout -b {branchName} {tagName}		# 检出到指定标签位置,并在此位置创建分支

Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。

  • 轻量标签:轻量标签指向某个版本的提交对象的hash值;
  • 附注标签:会在Git数据库中创建一个全新的Git对象——tag对象,该tag对象保存了这个版本的提交对象的hash值,同时还存储了一些有关于tag本身的日志信息;

创建好的标签存储在.git/refs/tags目录;

1.7.2 标签的使用

【初始化版本库】

rm -rf ./* .git
git init
echo "111" >> aaa.txt
git add ./
git commit -m '111' ./
echo "222" >> aaa.txt
git add ./
git commit -m '222' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline
794c1a9 (HEAD -> master) 222
a25c873 111

【创建标签】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看当前有多少标签
$ git tag

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 创建一个附注标签
$ git tag v1.0 -m "这是我的1.0版本"

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看标签
$ git tag
v1.0

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看日志
$ git log --oneline
794c1a9 (HEAD -> master, tag: v1.0) 222
a25c873 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 创建一个轻量标签
$ git tag v1.2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看标签
$ git tag
v1.0
v1.2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 查看日志
$ git log --oneline
794c1a9 (HEAD -> master, tag: v1.2, tag: v1.0) 222
a25c873 111

查看.git/refs/tags目录:

v1.0是一个附注标签,创建附注标签时会创建一个新的tag对象,该tag对象保存了所引用的提交对象hash值即一些其他日志信息;

v1.2是一个轻量标签,创建轻量标签时并不会创建一个tag对象,仅仅是将这个表情所指向的提交对象的hash值保存下来;

查看轻量标签和附注标签的内容:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ ll .git/refs/tags/
total 2
-rw-r--r-- 1 Adminstrator 197121 41 Oct 16 15:38 v1.0			# 创建了两个标签文件
-rw-r--r-- 1 Adminstrator 197121 41 Oct 16 15:38 v1.2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# v1.0(附注标签)保存的是tag对象的hash值
$ cat .git/refs/tags/v1.0
8223942a63f358c9f958d39c06f85a7837a29526

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# v1.2(轻量标签)保存的是提交对象的hash值
$ cat .git/refs/tags/v1.2
794c1a9c132d391e31dfd3c37b16aa948c46d3b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 是一个tag对象
$ git cat-file -t 8223942a63f358c9f958d39c06f85a7837a29526
tag

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 是一个commit对象
$ git cat-file -t 794c1a9c132d391e31dfd3c37b16aa948c46d3b1
commit

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 轻量标签的内容(就是一个提交对象)
$ git cat-file -p 8223942a63f358c9f958d39c06f85a7837a29526
object 794c1a9c132d391e31dfd3c37b16aa948c46d3b1
type commit
tag v1.0
tagger xiaohui <xiaohui@aliyun.com> 1697441891 +0800

这是我的1.0版本

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)		# 附注标签的内容
$ git cat-file -p 794c1a9c132d391e31dfd3c37b16aa948c46d3b1
tree 703a3923a3f4d516543ba3e6e9182467f31b328c
parent a25c8731c03a7c07dc574d8809f6ad7a69c09f27
author xiaohui <xiaohui@aliyun.com> 1697441871 +0800
committer xiaohui <xiaohui@aliyun.com> 1697441871 +0800

222

【查看标签】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看v1.0标签(附注标签)
$ git show v1.0
tag v1.0
Tagger: xiaohui <xiaohui@aliyun.com>
Date:   Mon Oct 16 15:38:11 2023 +0800

这是我的1.0版本

commit 794c1a9c132d391e31dfd3c37b16aa948c46d3b1 (HEAD -> master, tag: v1.2, tag: v1.0)
Author: xiaohui <xiaohui@aliyun.com>
Date:   Mon Oct 16 15:37:51 2023 +0800

    222

diff --git a/aaa.txt b/aaa.txt
index 58c9bdf..a30a52a 100644
--- a/aaa.txt
+++ b/aaa.txt
@@ -1 +1,2 @@
 111
+222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)			# 查看v1.2标签(轻量标签)
$ git show v1.2
commit 794c1a9c132d391e31dfd3c37b16aa948c46d3b1 (HEAD -> master, tag: v1.2, tag: v1.0)
Author: xiaohui <xiaohui@aliyun.com>
Date:   Mon Oct 16 15:37:51 2023 +0800

    222

diff --git a/aaa.txt b/aaa.txt
index 58c9bdf..a30a52a 100644
--- a/aaa.txt
+++ b/aaa.txt
@@ -1 +1,2 @@
 111
+222

【使用master分支继续开发】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ echo "333" >> ccc.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git add ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git commit -m '333' ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all
472d1e1 (HEAD -> master) 333
794c1a9 (tag: v1.2, tag: v1.0) 222
a25c873 111

【检出标签】

如果你想查看某个标签所指向的文件版本,可以使用 git checkout 命令, 虽然这会使你的仓库处于“分离头指针(detached HEAD)”的状态——这个状态有些不好的副作用:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git log --oneline --all
472d1e1 (HEAD -> master) 333
794c1a9 (tag: v1.2, tag: v1.0) 222
a25c873 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (master)
$ git checkout v1.0
Note: switching to 'v1.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 794c1a9 222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((v1.0))		# 记得使用-all,不然不会显示HEAD之后的内容
$ git log --oneline --all
472d1e1 (master) 333
794c1a9 (HEAD, tag: v1.2, tag: v1.0) 222		# HEAD指针指向的位置并没有指针
a25c873 111

在“分离头指针”状态下,如果你做了某些更改然后提交它们,标签不会发生变化, 但你的新提交将不属于任何分支,并且将无法访问,除非通过确切的提交哈希才能访问。 因此,如果你需要进行更改,比如你要修复旧版本中的错误,那么通常需要创建一个新分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((v1.0))
$ git log --oneline --all
472d1e1 (master) 333
794c1a9 (HEAD, tag: v1.2, tag: v1.0) 222
a25c873 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((v1.0))		# 查看当前HEAD指针位置的工作空间内容,发现并没有333
$ cat aaa.txt
111
222

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((v1.0))		# 追加内容1010
$ echo "1010" >> aaa.txt

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((v1.0))
$ git commit -m "1010" ./

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((830c1d5...))
$ git log --oneline --all --graph
* 830c1d5 (HEAD) 1010
| * 472d1e1 (master) 333
|/
* 794c1a9 (tag: v1.2, tag: v1.0) 222
* a25c873 111

【在当前位置创建分支】

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((830c1d5...))
$ git branch b1

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((830c1d5...))		# 在当前位置创建b1指针,但HEAD指针并没有执行b1
$ git log --oneline --all --graph
* 830c1d5 (HEAD, b1) 1010
| * 472d1e1 (master) 333
|/
* 794c1a9 (tag: v1.2, tag: v1.0) 222
* a25c873 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace ((830c1d5...))		# 切换到b1分支
$ git checkout b1
Switched to branch 'b1'

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git log --oneline --all --graph
* 830c1d5 (HEAD -> b1) 1010
| * 472d1e1 (master) 333
|/
* 794c1a9 (tag: v1.2, tag: v1.0) 222
* a25c873 111

【检出标签创建分支】

为了避免出现"分离头指针"现象,因此在检出标签时通常会创建一个新的分支:

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)
$ git log --oneline --all --graph
* 830c1d5 (HEAD -> b1) 1010
| * 472d1e1 (master) 333
|/
* 794c1a9 (tag: v1.2, tag: v1.0) 222
* a25c873 111

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 查看所有标签
$ git tag
v1.0
v1.2

Adminstrator@LAPTOP-OC90J78H MINGW64 ~/Desktop/workspace (b1)		# 检出到v1.2标签,并且在这个位置创建一个新的分支


### 给大家的福利


**零基础入门**


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)


同时每个成长路线对应的板块都有配套的视频提供:


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)


因篇幅有限,仅展示部分资料

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值