本篇将介绍一下Git中经常需要操作到的东西,以及项目中运用到的场景,会稍微带一点基础知识,笔者觉得阮一峰老师的Git入门讲的非常到位了,我就不班门弄斧了,就讲一下项目中遇到的一些情况。若是Git大牛就可以点击返回或者关闭啦~
此文多图预警~用流量的童鞋注意哦。
在版本管理中,Repository翻译成中文就是仓库的意思,每个提交到本地,或者push到远程服务器的Project,被Git以数据结构的形式保存,而这个数据结构被称之为Repository即仓库。
对于我们来说,在Repository中,我们看的见的显示信息就是代码,而其他的比如分支信息、Commit信息、Status这些状态则通过命令行去查看。
当我们多个人合作开发的时候,为了方便管理代码,会每个组开一个Branch,而master称为主分支——主干,这些Branch则称为分支。
在命令行输入git branch
就可以看到当前分支为master :
输入git branch -a
可以查看本地和远程所有分支
初始化Git后,当前默认在master分支,这个时候如果你想新建一个分支,可以执行 git branch [branchName]
后面的[branchName]是指你的分支名。这样就能把master当前的commit信息’拎’出来,成为了一个新的分支。
执行完branch命令后,你会发现你还是在原来的分支上,在master前有一个*号表示当前分支是master,这个时候执行以下 git checkout [branchName]
。
其实呢,你可以执行 git checkout -b [branchName] [fromBranchName]
生成新的Branch,后面这个[fromBranchName] 就是你想要从哪个分支生成新的分支,不写则是当前分支。
为什么要在这里讲HEAD呢,那HEAD又是什么呢,其实HEAD可以理解成一个指针,每次都是指向当前Branch的最后一次信息(可以是Commit或者Pull之类的),通过移动HEAD来达到切换分支的作用。
如果当前分支在master,那么HEAD信息如下:
真实测试效果:
在checkout到BranchC的时候变成了如下图所示:
真实测试效果:
当你的项目上线后,发现有个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.
这个时候会提示你有代码冲突,那么你需要执行git status
,查看当前文件哪些需要解决冲突。解决完再提交就好了。笔者很喜欢用AndroidStudio自带的git进行合并等操作,可以直接在Compare视图上解决冲突,非常方便。
这个时候回发现 <<<<<<<<<< HEAD
到 ========
是当前所在分支的内容,下面从 =======
到 >>>>>>>> fixBug
是合并过来的分支,解决完,再执行git add .
然后就可以提交啦。
接下来为大家看一下编译器的merge:
选择分支:
冲突提示:
冲突比较 :
rebase和merge的功能其实是一样的,都是合并代码,只是对于修改信息的节点会发生变化,rebase和merge最大的区别就是在最后的代码树上,有兴趣的同学可以用SourceTree看看,或者直接在命令行输入gitk。
当前工作状态,箭头表示上一次信息:
执行merge后:
执行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 on
:
当你想切换分支时,又不想提交当前代码,那就需要stash啦,简单的意思就是讲你当前的修改信息全部暂存起来,放进一个stack栈中,这个时候你就可以checkout到别的分支啦。下次再回来的时候 git stash pop
就好了。
这个时候Leader转头对我说:XXX模块代码我提交了,你拉一下代码,我改了你可能要用到的东西。
这个时候我对着一屏幕的蓝色提示,心想:不能commit把,都没测试过。这个时候就用到stash
这个神器了。
没有提交文件,本地修改过的文件会显示蓝色:
项目里有几个文件都没有提交,只能选择项目根目录,右击,选择stash:
会弹出一个stash的弹出框,会显示当前分支,填入message:
点击createStash后,创建一个当前的stash,可以点击刚刚的StashChanges下面的UnstashChanges查看当前的stash列表:
或者在命令行输入git stash list
查看当前的stash栈:
好啦,当前的工作全部都暂存起来了!要把刚刚Leader放到master的代码都合并过来啦!我选择的当然是rebase啦。在这之前必须得把服务器的master代码pull到本地是不是,先切换到master,然后还是选择编译器的git,在刚刚stash界面下面有个pull
。点击pull弹出一个界面,选择master分支:
点击pull就能拉下代码啦,如果有冲突也能借助编译器的compare进行合并啦。
pull完代码后,要reabse啦:
按照步骤来,1、点击当前分支,选择要rebase的目标分支,点击后选择Rebase onto
就可以执行rebase啦,rebase过程中发现出现了一个冲突:
和前面的merge一样,选择在这里解决冲突:
这个时候master的代码就过来啦,然后再把之前修改的代码拿出来继续工作:
pop完后可以继续快乐的工作啦:
在这里说明一下红色
的文件表示没有add,绿色
文件表示add过了但是没有commit,蓝色
文件表示修改过,和远端的分支代码不一样,绿色和蓝色的文件执行stash会被暂存,而红色的不会。
如果对Git原理有兴趣的同学,可以自己再去深入研究一下Git,很多东西虽然平时用不到,但是又很有深度。大家按兴趣就好啦
一边写博客,一边翻阅资料,自己也又温习一遍,接下来打算继续深入下去,下一篇将会讲几个指令的原理,以及git对象之类的。最近比较忙,需要用点心去学习,也会把自己遇到的场景尽量告诉大家,让大家能接触到更多的实际场景,努力把这个系列写的更干货一些!
其实AndroidStudio能覆盖大多数的使用场景了,下一篇将会说一些revert、reset,当发生错误提交时,怎么回滚代码。
最近大帅的开了个QQ实践群(568863373),欢迎大家一起讨论,也可以关注我们的公众号:魔都三帅