从0开始学习 GITHUB 系列之「GIT 进阶」【转】

本文转载自:http://stormzhang.com/github/2016/06/16/learn-github-from-zero5/git

版权声明:本文为 stormzhang 原创文章,能够随意转载,但必须在明确位置注明出处!!!github

关于 Git 相信你们看了以前一系列的文章已经初步会使用了, 可是关于Git还有不少知识与技巧是你不知道的,今天就来给你们介绍下一些 Git 进阶的知识。vim

1. 用户名和邮箱

咱们知道咱们进行的每一次commit都会产生一条log,这条log标记了提交人的姓名与邮箱,以便其余人方便的查看与联系提交人,因此咱们在进行提交代码的第一步就是要设置本身的用户名与邮箱。执行如下代码:app

git config --global user.name "stormzhang"
git config --global user.email "stormzhang.dev@gmail.com"

以上进行了全局配置,固然有些时候咱们的某一个项目想要用特定的邮箱,这个时候只需切换到你的项目,以上代码把 –global 参数去除,再从新执行一遍就ok了。编辑器

PS:咱们在 GitHub 的每次提交理论上都会在 主页的下面产生一条绿色小方块的记录,若是你确认你提交了,可是没有绿色方块显示,那确定是你提交代码配置的邮箱跟你 GitHub 上的邮箱不一致,GitHub 上的邮箱能够到 Setting -> Emails里查看。gradle

2. alias

咱们知道咱们执行的一些Git命令其实操做很频繁的相似有:ui

git commit
git checkout
git branch
git status
...

这些操做很是频繁,每次都要输入彻底是否是有点麻烦,有没有一种简单的缩写输入呢?好比我对应的直接输入如下:插件

git c
git co
git br
git s
...

是否是很简单快捷啊?这个时候就用到了alias配置了,翻译过来就是别名的意思,输入如下命令就能够直接知足了以上的需求。翻译

git config --global alias.co checkout  # 别名
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch

固然以上别名不是固定的,你彻底能够根据本身的习惯去定制,除此以外还能够设置组合,好比:日志

git config --global alias.psm 'push origin master'
git config --global alias.plm 'pull origin master'

以后常常用到的git push origin master 和 git pull origin master 直接就用 git psm 和 git plm 代替了,是否是很方便?

另外这里给你们推荐一个很强大的 alias 命令,咱们知道咱们输入 git log 查看日志的时候是相似这样的:

告诉你们一个比较屌的命令,输入**git log –graph –pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit –date=relative ** 而后日志这样了:

是否是比较清晰,整个分支的走向也很明确,可是每次都要输这么一大串是否是也很烦?这时候你就该想到 alias 啊:

git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"

这样之后直接输入 git lg 就好了。

3. 其余配置

固然还有一些其余有用的配置,默认状况下 git 用的编辑器是 vi ,若是不喜欢能够改为其余编辑器,好比我习惯 vim 。

git config --global core.editor "vim"  # 设置Editor使用vim

大家若是喜欢其余编辑器可自行搜索配置,前提是本机有安装。

有些人纳闷个人终端怎么有各类颜色,本身却不是这样的,那是由于大家没有开启给 Git 着色,输入以下命令便可:

git config --global color.ui true

还有些其余的配置如:

git config --global core.quotepath false # 设置显示中文文件名

以上基本全部的配置就差很少了,默认这些配置都在 ~/.gitconfig 文件下的,你能够找到这个文件查看本身的配置,也能够输入 git config -l 命令查看。

4. diff

diff命令算是很经常使用的,使用场景是咱们常常在作代码改动,可是有的时候2天前的代码了,作了哪些改动都忘记了,在提交以前须要确认下,这个时候就能够用diff来查看你到底作了哪些改动,举个例子,好比我有一个 a.md 的文件,我如今作了一些改动,而后输入 git diff 就会看到以下:

红色的部分前面有个 - 表明我删除的,绿色的部分前面有个 + 表明我增长的,因此从这里大家很一目了然的知道我到底对这个文件作了哪些改动。

值得一提的是直接输入 git diff 只能比较当前文件和暂存区文件差别,什么是暂存区?就是你尚未执行 git add 的文件。

固然跟暂存区作比较以外,他还能够有其余用法,如比较两次 commit 之间的差别,比较两个分支之间的差别,比较暂存区和版本库之间的差别等,具体用法以下:

git diff <$id1> <$id2>   # 比较两次提交之间的差别
git diff <branch1>..<branch2> # 在两个分支之间比较 
git diff --staged   # 比较暂存区和版本库差别

5. checkout

咱们知道 checkout 通常用做切换分支使用,好比切换到 develop 分支,能够执行:

git checkout develop

可是 checkout 不仅用做切换分支,他能够用来切换tag,切换到某次commit,如:

git checkout v1.0
git checkout ffd9f2dd68f1eb21d36cee50dbdd504e95d9c8f7 # 后面的一长串是commit_id,是每次commit的SHA1值,能够根据 git log 看到。

除了有“切换”的意思,checkout 还有一个撤销的做用,举个例子,假设咱们在一个分支开发一个小功能,刚写完一半,这时候需求变了,并且是大变化,以前写的代码彻底用不了了,好在你刚写,甚至都没有 git add 进暂存区,这个时候很简单的一个操做就直接把原文件还原:

git checkout a.md

这里稍微提下,checkout 命令只能撤销尚未 add 进暂存区的文件。

6. stash

设想一个场景,假设咱们正在一个新的分支作新的功能,这个时候忽然有一个紧急的bug须要修复,并且修复完以后须要当即发布。固然你说我先把刚写的一点代码进行提交不就好了么?这样理论上固然是ok的,可是这会产品垃圾commit,原则上咱们每次的commit都要有实际的意义,你的代码只是刚写了一半,尚未什么实际的意义是不建议就这样commit的,那么有没有一种比较好的办法,可让我暂时切到别的分支,修复完bug再切回来,并且代码也能保留的呢?

这个时候 stash 命令就大有用处了,前提是咱们的代码没有进行 commit ,哪怕你执行了add 也不要紧,咱们先执行

git stash

命令,什么意思呢?意思就是把当前分支全部没有 commit 的代码先暂存起来,这个时候你再执行 git status 你会发现当前分支很干净,几乎看不到任何改动,你的代码改动也看不见了,但实际上是暂存起来了。执行

git stash list

你会发现此时暂存区已经有了一条记录。

这个时候你能够切换会其余分支,赶忙把bug修复好,而后发布。以后一切都解决了,你再切换回来继续作你以前没作完的功能,可是以前的代码怎么还原呢?

git stash apply

你会发现你以前的代码所有又回来了,就好像一切都没发生过同样,紧接着你最好须要把暂存区的此次 stash 记录删除,执行:

git stash drop

就把最近一条的 stash 记录删除了,是否是很方便?其实还有更方便的,你可使用:

git stash pop

来代替 apply 命令,pop 跟 apply 的惟一区别就是 pop 不但会帮你把代码还原,还自动帮你把这条 stash 记录删除,省的本身再 drop 一次了,为了验证你能够紧接着执行 git stash list 命令来确认是否是已经没有记录了。

最后还有一个命令介绍下:

git stash clear

就是清空全部暂存区的记录,drop 是只删除一条,固然后面能够跟 stash_id 参数来删除指定的某条记录,不跟参数就是删除最近的,而 clear 是清空。

7. merge & rebase

咱们知道 merge 分支是合并的意思,咱们在一个 featureA 分支开发完了一个功能,这个时候须要合并到主分支 master 上去,咱们只须要进行以下操做:

git checkout master
git merge featureA

其实 rebase 命令也是合并的意思,上面的需求咱们同样能够以下操做:

git checkout master
git rebase featureA

rebase 跟 merge 的区别大家能够理解成有两个书架,你须要把两个书架的书整理到一块儿去,第一种作法是 merge ,比较粗鲁暴力,就直接腾出一块地方把另外一个书架的书所有放进去,虽然暴力,可是这种作法你能够知道哪些书是来自另外一个书架的;第二种作法就是rebase ,他会把两个书架的书先进行比较,按照购书的时间来给他从新排序,而后从新放置好,这样作的好处就是合并以后的书架看起来颇有逻辑,可是你很难清晰的知道哪些书来自哪一个书架的。

只能说各有好处的,不一样的团队根据不一样的须要以及不一样的习惯来选择就好。

8. 解决冲突

假设这样一个场景,A和B两位同窗各自开了两个分支来开发不一样的功能,大部分状况下都会尽可能互不干扰的,可是有一个需求A须要改动一个基础库中的一个类的方法,不巧B这个时候因为业务须要也改动了基础库的这个方法,由于这种状况比较特殊,A和B都认为不会对地方形成影响,等两人各自把功能作完了,须要合并的到主分支 master 的时候,咱们假设先合并A的分支,这个时候没问题的,以后再继续合并B的分支,这个时候想一想也知道就有冲突了,由于A和B两我的同时更改了同一个地方,Git 自己他无法判断大家两个谁更改的对,可是这个时候他会智能的提示有 conflicts ,须要手动解决这个冲突以后再从新进行一次 commit 提交。我随便在项目搞了一个冲突作下示例:

以上截图里就是冲突的示例,冲突的地方由 ==== 分出了上下两个部分,上部分一个叫HEAD 的字样表明是我当前所在分支的代码,下半部分是一个叫 baidu_activity 分支的代码,能够看到 HEAD 对 gradle 插件进行了升级,同时新增了一个插件,因此咱们很容易判断哪些代码该保留,哪些代码该删除,咱们只须要移除掉那些老旧代码,并且同时也要把那些 «< HEAD、==== 以及 »»»baidu_activity 这些标记符号也一并删除,最后进行一次 commit 就ok了。

咱们在开发的过程当中通常都会约定尽可能你们写的代码不要彼此影响,以减小出现冲突的可能,可是冲突总归没法避免的,咱们须要了解并掌握解决冲突的方法。

相关文章
相关标签/搜索