从什么都不懂开始(三)—实践带你飞之Branch操作

本篇将介绍一下Git中经常需要操作到的东西,以及项目中运用到的场景,会稍微带一点基础知识,笔者觉得阮一峰老师的Git入门讲的非常到位了,我就不班门弄斧了,就讲一下项目中遇到的一些情况。若是Git大牛就可以点击返回或者关闭啦~
此文多图预警~用流量的童鞋注意哦。

Repository介绍

在版本管理中,Repository翻译成中文就是仓库的意思,每个提交到本地,或者push到远程服务器的Project,被Git以数据结构的形式保存,而这个数据结构被称之为Repository即仓库。

对于我们来说,在Repository中,我们看的见的显示信息就是代码,而其他的比如分支信息、Commit信息、Status这些状态则通过命令行去查看。

Branch介绍

当我们多个人合作开发的时候,为了方便管理代码,会每个组开一个Branch,而master称为主分支——主干,这些Branch则称为分支。

BranchAndMaster

查看当前分支

在命令行输入git branch就可以看到当前分支为master :
查看当前分支

输入git branch -a 可以查看本地和远程所有分支
查看本地和远程所有分支

切换分支

初始化Git后,当前默认在master分支,这个时候如果你想新建一个分支,可以执行 git branch [branchName] 后面的[branchName]是指你的分支名。这样就能把master当前的commit信息’拎’出来,成为了一个新的分支。

新建分支

执行完branch命令后,你会发现你还是在原来的分支上,在master前有一个*号表示当前分支是master,这个时候执行以下 git checkout [branchName]
切换当前分支到testBranch
其实呢,你可以执行
git checkout -b [branchName] [fromBranchName] 生成新的Branch,后面这个[fromBranchName] 就是你想要从哪个分支生成新的分支,不写则是当前分支。

从当前分支检出新分支

从master分支检出新分支

HEAD信息

为什么要在这里讲HEAD呢,那HEAD又是什么呢,其实HEAD可以理解成一个指针,每次都是指向当前Branch的最后一次信息(可以是Commit或者Pull之类的),通过移动HEAD来达到切换分支的作用。
如果当前分支在master,那么HEAD信息如下:
HEAD_MASTER

真实测试效果:

HEAD_IN_MASTER
在checkout到BranchC的时候变成了如下图所示:

HEAD_BRANCH

真实测试效果:

HEAD_IN_BRANCH

合并分支

当你的项目上线后,发现有个bug,这个时候需要在master分支上checkout -b 一个新的分支用来修bug,那么这个bug分支上的代码,最后怎么给’整’到master上去呢。很简单先切回master分支,然后git merge bugBranch 就好了。

冲突

当你merge的时候出现了

$ git merge myBranch Auto-merging AndroidManifest.xml CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
切换到bug分支
merge

这个时候会提示你有代码冲突,那么你需要执行git status,查看当前文件哪些需要解决冲突。解决完再提交就好了。笔者很喜欢用AndroidStudio自带的git进行合并等操作,可以直接在Compare视图上解决冲突,非常方便。
发现冲突

冲突文件

这个时候回发现 <<<<<<<<<< HEAD======== 是当前所在分支的内容,下面从 =======>>>>>>>> fixBug 是合并过来的分支,解决完,再执行git add . 然后就可以提交啦。

接下来为大家看一下编译器的merge:

选择merge

选择分支:

选择分支

冲突提示:

冲突提示

冲突比较 :

合并操作

rebase

rebase和merge的功能其实是一样的,都是合并代码,只是对于修改信息的节点会发生变化,rebase和merge最大的区别就是在最后的代码树上,有兴趣的同学可以用SourceTree看看,或者直接在命令行输入gitk。

当前工作状态,箭头表示上一次信息:
当前状态

执行merge后:
merge

执行rebase后
rebase

之所以会有5-1,6-1就是和原来的commit是不同的,算是一次新的commit了。

简而言之就是rebase的代码会比merge的干净许多。rebase会保留你合并的顺序,而merge则会按照你的修改时间排序。笔者有点强迫症,会使用rebase(搞基),另外一些图方便的人喜欢merge(合体)。

另外值得注意的是,在rebase前,千万别push,不然等rebase完毕后,因为tree发生了变化,会提示push reject,意味着你需要 git push --f才能提交了,这是有风险的!!!注意安全!!!

比如branch要reabse onto master,那么会比较两个分支的最近的共同节点,再根据master提交的节点生成一系列不同的文件,最后在branch上针对每个提交将之前不同的文件去合并,并且生成新的commit节点,这时rebase完毕后branch的tree已经和rebase前的branch tree完全不一样了,所以在rebase前你push过后,rebase后再push会提示不是同一个tree而reject(拒绝)提交。

下面是AndroidStudio上的rebase操作:
rebase选择

想要从哪个分支rebase到当前分支,就选择哪个Rebase on

选择分支

stash

当你想切换分支时,又不想提交当前代码,那就需要stash啦,简单的意思就是讲你当前的修改信息全部暂存起来,放进一个stack栈中,这个时候你就可以checkout到别的分支啦。下次再回来的时候
git stash pop就好了。

这个时候Leader转头对我说:XXX模块代码我提交了,你拉一下代码,我改了你可能要用到的东西。
这个时候我对着一屏幕的蓝色提示,心想:不能commit把,都没测试过。这个时候就用到stash这个神器了。

没有提交文件,本地修改过的文件会显示蓝色:
蓝色

项目里有几个文件都没有提交,只能选择项目根目录,右击,选择stash:

stash

会弹出一个stash的弹出框,会显示当前分支,填入message:
stash弹出框

点击createStash后,创建一个当前的stash,可以点击刚刚的StashChanges下面的UnstashChanges查看当前的stash列表:

查看stashInAs

或者在命令行输入git stash list 查看当前的stash栈:
查看stash

结果

好啦,当前的工作全部都暂存起来了!要把刚刚Leader放到master的代码都合并过来啦!我选择的当然是rebase啦。在这之前必须得把服务器的master代码pull到本地是不是,先切换到master,然后还是选择编译器的git,在刚刚stash界面下面有个pull。点击pull弹出一个界面,选择master分支:

pull

点击pull就能拉下代码啦,如果有冲突也能借助编译器的compare进行合并啦。

pull完代码后,要reabse啦:

rebase

按照步骤来,1、点击当前分支,选择要rebase的目标分支,点击后选择Rebase onto就可以执行rebase啦,rebase过程中发现出现了一个冲突:

冲突

和前面的merge一样,选择在这里解决冲突:

解决冲突
这个时候master的代码就过来啦,然后再把之前修改的代码拿出来继续工作:

pop

pop完后可以继续快乐的工作啦:

pop完毕

在这里说明一下红色的文件表示没有add,绿色文件表示add过了但是没有commit,蓝色文件表示修改过,和版本库分支不一样,绿色和蓝色的文件执行stash会被暂存,而红色的不会。

拓展

如果对Git原理有兴趣的同学,可以自己再去深入研究一下Git,很多东西虽然平时用不到,但是又很有深度。大家按兴趣就好啦

总结

一边写博客,一边翻阅资料,自己也又温习一遍,接下来打算继续深入下去,下一篇将会讲几个指令的原理,以及git对象之类的。最近比较忙,需要用点心去学习,也会把自己遇到的场景尽量告诉大家,让大家能接触到更多的实际场景,努力把这个系列写的更干货一些!

其实AndroidStudio能覆盖大多数的使用场景了,下一篇将会说一些revert、reset,当发生错误提交时,怎么回滚代码。

最近大帅的开了个QQ实践群(568863373),欢迎大家一起讨论,也可以关注我们的公众号:魔都三帅

公众号

Abner_泥阿布 wechat
欢迎您扫一扫上面的微信公众号,订阅我们的公众号!
或者欢迎加入QQ群:568863373。


如果你觉得这篇文章对你有帮助,请点击下面的分享链接,你还可以选择扫描二维码进行打赏!

我的Github

我的新浪微博