其实上一篇《开发中关于Git那些事》写的内容仅仅是Git的冰山一角,若是你认为Git就是简简单单的几行命令,那只能说明你尚未真正了解Git这个强大的内容寻址文件系统。这篇文章,仍是接着介绍一些实用可是不多有人知晓的一些命令,比如说具备魔性的Git变基(git rebase)以及经常使用的GUI。
我以前询问过一些人,讨论到Git这块,他们当中有的直接使用GUI,说简单省事。其实,每个GUI都有它的侧重点,并非全部的GUI都适合用。我却是建议你们使用命令行。况且有些功能GUI不必定支持,并且有时候一行命令的事,还要点来点去,也不省事。以前看到过一篇文章,是关于如何使用Vim编辑器的,对,你们平时开发习惯了IDE,爱上了IDE。可是好的程序员怎么会由于简单省事而放弃学习呢。这样说可能更好提现,学习任意一款IDE,你都须要耗时好久,可是若是你平时习惯了使用Vim编辑器,爱上用Vim编辑器写代码,那么任意一款集成Vim编辑器的IDE,一上来就会很是顺手。一样的道理,若是你了解了Git内部原理,平时习惯使用命令处理,那么给你任意一款GitGUI,相信你一看就会用,并且很快就上手。因此,学习顺序有时候很重要,基础扎实了,才不会被问题难倒,地基决定高度。html
默认使用Vim编辑器,固然可使用core.editor修改git
git config --global core.editor emacs
默认使用less,可使用core.pager来设置为more或则其余,也可使用空字符串,关闭分页,一次性加载全部内容程序员
git config --global core.pager ''
使用到color.ui,默认auto,若是你不喜欢可使用false关闭。github
git config --global color.ui false
其实若是想具体到某些特定命令,都是有true、false 或 always能够设置的,好比如下服务器
color.branch color.diff color.interactive color.status
以上每一个配置项都有子选项,它们能够被用来覆盖其父设置,以达到为输出的各个部分着色的目的。例如,为了让 diff 的输出信息以蓝色前景、黑色背景和粗体显示,你能够运行app
git config --global color.diff.meta "blue black bold"
你能设置的颜色有:normal、black、red、green、yellow、blue、magenta、cyan 或 white。正如以 上例子设置的粗体属性,想要设置字体属性的话,能够选择包括:bold、dim、ul(下划线)、blink 、reverse(交换前景色和背景色)。less
git branch -v
该命令显示本地分支最后一次提交说明编辑器
* dev cdc7241a fixbug master f586f6b5 ****
若是须要显示本地和远程,加上-a即git branch -v -a
学习
* dev cdc7241a fixbug master f586f6b5 **** remotes/origin/HEAD -> origin/master remotes/origin/dev cdc7241a fixbug remotes/origin/master f586f6b5 **** remotes/origin/oldIm 97d131bb 2.5.1 封版
git branch -vv
除了具备git branch -v
命令的做用,还能够显示出每个分支正在跟踪哪一个远程分支,以及本地分支与远程分支是不是领先、落后。一样,若是想看远程加上-a
,也就是all(全部),反正我就是这么记忆的字体
* dev 6512ef90 [origin/dev: ahead 1] test master 78b4b30a [origin/master] 171227122 2.12.2 封版
其实在Git当中整合两个分支的方式除了merge,还有一种方式,那就是rebase。如上图,如今要合并C3和C4,若是使用merge合并是这样子的。它会把两个分支的最新快照(C3 和 C4)以及两者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。
可是若是使用rebase:你能够提取在 C4 中引入的补丁和修改,而后在 C3 的基础上再应用一次。在 Git 中,这种操做就叫作变基。你可使用 rebase 命令将提交到某一分支上的全部修改都移至另外一分支上,就好像“从新播放”同样。
执行步骤就是,首先切换的experiment分支git checkout experiment
,而后运行git rebase master
,此时准备“重演”,接下来就是看你要在哪一个分支重演,就切换到哪一个分支,这边在主分支重演,切换到主分支git checkout master
,而后整合便可git merge experiment
。其实此时的merge和以前的merge不同,这边的merge只须要进行一次fast-forward,就是快速合并,head快速前进到C4'。
它的原理是首先找到这两个分支(即当前分支 experiment、变基操做的目标基底分支 master)的最近共同祖 先 C2,而后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,而后将当前分支指向目标基底C3, 最后以此将以前另存为临时文件的修改依序应用。
git checkout experiment git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command
git checkout master git merge experiment
此时,C4' 指向的快照就和上面使用merge命令的例子中 C5 指向的快照如出一辙了。这两种整合方法的最终结果没有任何区别,可是变基使得提交历史更加整洁。你在查看一个通过变基的分支的历史记录时会发现,尽管实际的开发工做是并行的,但它们看上去就像是前后串行的同样,提交历史是一条直线没有分叉。
直接看下图,如今我有这样的需求,就是将C8,C9提交到主分支,可是不要C3,你如何作?
其实办法老是有的,在前篇文章中,有讲到git stash命令,其实,咱们能够在client分支找到C3的哈希值直接执行git reset 哈希值(C3)
而后把C8,C9的修改直接git stash 贮存起来,切换到master分支,来个git stash pop
搞定。如今咱们使用变基来操做,感觉下变基的魔性。
git rebase --onto master server client
以上命令含义:取出 client 分支,找出处于 client 分支和 server 分支的共同祖先以后的修改,而后把它们在 master 分支上重演一遍。
如今能够快进合并 master 分支了。
git checkout master git merge client
再举一个例子,也是关于git rebase --onto的使用
H---I---J topicB / E---F---G topicA / A---B---C---D master git rebase --onto master topicA topicB H'--I'--J' topicB / | E---F---G topicA |/ A---B---C---D master This is useful when topicB does not depend on topicA.
这样的例子好多,感兴趣可使用git rebase --help
查看。
注意事项
这点必定要看,不要对在你的仓库外还有副本的分支执行变基。也就是说,一我的开发随便搞,多人开发有原则的搞。若是你不遵循这个原则,多人开发出现问题别来找我。
为何呢?假若有我的在本地使用了merge合并分支后,push到了远程服务器,后来他感受不爽,想经过变基处理,恰是这个时候你pull了服务器的代码,那就会出现问题。问题就是,之后看记录会出现相同的提交,原本张三想丢弃的东西被你保留了。若是想看详细举例,推荐查看Pro Git这本书中关于Git变基一节。
总之,只要是你的代码和你创建的分支,尚未执行push以前,随意搞,push后就不要再想着使用变基了,避免出问题。若是你更喜欢merge,喜欢看Git实际发生的事,那就使用merge吧。反之,你更喜欢流水线同样的记录,从前到后,没有一堆堆复杂的合并,那就用rebase。
十几款GUI,点开查看便可。
SourceTree
GitHub Desktop
TortoiseGit
GitUp ...... 我比较喜欢GitUp,简洁些。可是我仍旧在使用命令行,就当为了给电脑省空间吧。