简而言之,在git分布式版本管理中,都是遵循“Head -> branch -> commit版本“顺序执行的,如果直接checkout或switch到一个commit版本号(用F代替),此时就是分离头指针指向。若修改一些东西后commit生成新版本号G,此时会提示“建议在当前版本号上创建一个新的branch再提交,否则commit内容会丢失“。因为此时是Head -> commit版本,若直接跳过branch交给commit,是不行的。
有关分离头指针的详细概念,请看这篇博文。
在本文中,还会使用一些基础git指令,不清楚的同学可以看本人另一篇博客。同时,我会大量使用switch指令来代替checkout,详情可见switch、restore讲解。
安利大家gitk
,只需要gitk --all
便可视化出git库中的所有分支状态,十分方便!下面展示图都是gitk
得到的。
【step1】在master分支中创建1.txt并输入‘11’:
git init
touch 1.txt
gedit 1.txt
git add .
git commit -m 'create 1.txt and add '11''
【step2】在master分支中给1.txt添加’22’和’33’,分开来提交:
gedit 1.txt
git add .
git commit -m 'add '22' in 1.txt'
gedit 1.txt
git add .
git commit -m 'add '33' in 1.txt'
【step3】创建一个branch1分支,给1.txt添加’aa’和’bb’,分两次提交:
git switch -c branch1
gedit 1.txt
git add .
git commit -m 'add 'aa' in 1.txt'
gedit 1.txt
git add .
git commit -m 'add 'bb' in 1.txt'
可见通过branch提交commit,可以很好的保存下来。
【step4】switch到最新的版本号上,然后在1.txt中添加’success`:
git switch -d 908dfe
gedit 1.txt
git add .
git commit -m 'add 'success'in 1.txt'
可见,commit后创建了一个bbe385a版本号,但是此时是分离头指针,不属于任何分支。虽然1.txt已经有了“success”,但是如果回到branch1上发现1.txt上并没有"success"。如果后面记不住版本号就丢失了,而且git也会自动回收这些没有分支归属的commit版本号。
【step5】在bbe385a版本上创建一个临时分支tmp并跳转过去,来保存我们的更改,以防丢失:
git switch -c tmp
【step6】跳转到master上,并merge tmp,这样就可以将bbe385commit更新到master上:
git switch master
git merge tmp
【step7】再试一试,跳回tmp,然后添加’final’给1.txt:
git switch tmp
git gedit 1.txt
git add .
git commit 'add 'final'in 1.txt'
【step8】再回master,merge ,并删除tmp:
git switch master
git merge tmp
git branch -d tmp
【step9】如果我们找过去某一个历史版本,在上面修改,然后更新到最新版本上呢:
git switch -d e20ba5f7571accc9cc444dd577aad58c7c41d047
git add .
it commit -m 'add 'try' in 1.txt'
【step10】老办法,设置一个tmp给它,然后master merge一下:
git branch tmp
git switch master
git merge tmp
会发现合并冲突,原因就是tmp分支和master分支不在一条直线上!!而之前那个案例可以是因为他们在一条直线上。
git branch -d tmp
git status
【step11】就是想要并起来怎么办,如下:
git add . ; git commit -m ‘强制合并’
【step12】如果我回到add 22 in 1.txt版本,并且创建2.txt、添加’bb’,命名为branch2分支。再回到add aa in 1.txt版本处,命名为branch3,然后merge branch2,中间不会报错,因为没有修改文件引起冲突,结果如下:
如果删除branch2分支,也不会报错,结果如下: