“有人把Git的分支模型称为它的必杀技特性,也正因为这一特性,使得Git从众多版本控制系统中脱颖而出。”
冲突&合并
在上一篇的基础上,git跳转到哈希码头四位9533的commit版本上,用命令git branch命令创建分支branch01和branch02,这个时候产生疑问:
在某分支上做改动,其它支线看得到改动的部分吗?
切换到branch01上,将最后一行添加“branch01”到Hello后面。此时用git checkout命令切换到master或者branch02上,cat test.md,查看内容发现,都能看见改动的部分,再次切换到branch01,add改动的文件,再次切换到其它支线,此时在其它支线仍然能看见staged状态下modified的部分。切换到branch01,将刚刚add的文件commit,然后再切换到其它支线,此时将看不见modified(无论是否staged)的部分。
其实这不难理解,在没有提交前,所谓的分支不过是各个指针指向当前提交点而已。
需要说明的是,如果再次用同样的方法,对branch02进行修改,比如更改test.md最后一行为Hello branch02,尝试切换回branch01将会报错:
|
|
切换失败,需要commit或者使用stash
解决,关于stash
后面会讲到。
在各支线,用git log命令可以看到其它支线提交的情况吗?
将branch02分支中add的文件commit,切换到各支线进行测试,结果是不能。
不仅如此,git log --oneline --decorate
这个命令,只会追踪HEAD指针,当其它分支都停留在HEAD指针指向的地方时,命令才会将它们的名字打印出来。
但是使用git log --oneline --decorate --graph --all
可以打印出所有支线组成的树状结构。
log也可以查看公共仓库的提交,使用git log origin/master
命令即可。
怎么给Git命令取别名?
以git log --oneline --decorate --graph --all
为例,为它取一个别名git tree
可以通过如下设置:
|
|
当打下git tree
将出现和欲被修改的别名命令同样的效果。
为了以后的方便,这里将reset HEAD --
设置为unstaged
:
|
|
分支怎么合并到master?
|
|
此时输出:
|
|
这里用到fast-forward,是因为在这次合并中,master指针只是做了一个向前移动的动作。至于为什么可以fast-forward,源于branch01是master的直接上游,合并不产生没有解决的分歧。从这个动作看来,称master“合并”到branch01更适合。接着也可以使用删除命令对branch01进行删除:
|
|
branch02怎么合并到master?
branch01很迅速的就合并到master上了,但是如果现在要将branch02合并到master上,就会产生冲突:
|
|
因为此时的master和branch02已经不是一条直线上的“蚂蚱”了,变成了旁系,且branch02和之前的branch01本来就有冲突。
合并冲突后任意时刻调用git status可以查看包含合并冲突而未合并的文件,等待你去解决合并产生的冲突。使用cat test.md查看文件:
|
|
然后修改该冲突文件,一旦运行git add命令,Git就会知道冲突已经解决:
|
|
继续commit最终完成合并。
Git对行列的空格符会进行冲突检测吗?
在Git内任何空格符都是能够被识别的,下面是一个例子的结果:
|
|
分支管理
在切换到不同分支后使用git branch [新建的分支名]创建的新的分支有什么不同?
在不同分支先创建新的分支,就相当于在当前创建了一个新的指针而已。在上一个问题的最后,branch02已经合并到master上了,此时切换到branch02新建一个分支branch03,那么运行命令:
|
|
branch02和branch03都会打印出来,切换到master,如果此时合并branch03会显示Already up-to-date。同样的如果在master下新建一个分支branch04,那么尝试合并它也会打印Already up-to-date。如果要打印所有包涵未合并工作的分支,使用如下命令:
|
|
如何查看远程分支?
只需要运行git branch -r
就可以查看远程分支,而如果运行git branch -a
将罗列出所有分支。
储藏&清理
未处于staged的modified数据和处于staged状态的数据都能被stash么
实测的确是这样,stash针对的工作区的改动(Saved working directory)。在git stash apply后文件的改动被重新应用了,但是之前staged的文件却没有重新处于staged状态。如果要在调用命令后就处于staged状态,可以使用如下命令:
|
|
Git可以在同一个分支多次存储吗?
经过本人来回多次git stash apply stash@{0}
,验证出可以进行多次存储,但每次恢复其中一个后,并不能马上又恢复另一个,这样会出现以下信息:
|
|
在stash的过程中怎么添加描述信息?
我的做法是这样的:
|
|
如何移除stash的工作?
命令如下:
|
|
这条命令可以指定删除哪一条stash存储的内容。
再就是下面这条恢复后
弹出栈命令:
|
|
它会恢复栈顶stash储存的内容,恢复后,这条stash也从栈弹出,相当于删除栈顶。
工作目录下untracked状态的test02.md属于多余的“看客”,使用什么命令可以删除?
答案是 git clean。但通常最后添加参数-n,比如这里运行如下代码:
|
|
会输出这样的结果:
|
|
所以上面的命令并不会真正删除,只不过是个提醒。
如果使用命令:
|
|
即删除当前目录吓没有被track的文件和文件夹。
打标签
Git可以给历史中的某一个提交打上标签。
如何列出标签?
只需要输入git tag就可以了。而打轻量标签,是在git tag后面添加参数作为标签名,此参数不需要打引号表示字符串。
既然是给提交打标签,那么如何给过去的某个提交打标签?
比如现在我要为实验中的某次commit(9533382df5a3b45b5d6a67fe2f51ce3fafd1c8b8)打标签,我会使用如下命令:
|
|
如果不希望Write a message for tag,如何给提交打标签?
在上一个问题中,必须提供一个用来描述的message,主要是因为命令中含有-a,现在使用下面的命令,打印轻量标签:
|
|
以上反映的是轻量标签和附注标签的不同。
可以根据tag创建分支吗?
见如下命令:
|
|
如何看待git checkout [标签名]
切换tag和切换branch的命令相同,在实际的测试中,输入该命令后,各branch列表如下:
当切换到其它分支后,“临时”branch就不见了,这种状态被称为detached HEAD
状态。
上传到远程仓库:
|
|
小结
通过两篇小记,采用自问自答的形式,窥探了git最核心的几个功能。