git高级应用

665 查看

上篇主要介绍了git在单分支上的相关操作,还没有介绍更深的操作,比如版本回退,远程仓库操作,以及多分支的操作。这里都会一个一个介绍。

远程仓库操作

remote是与远程仓库打交道的命令的重要命令。还记得我们一开始创建一个空仓库吗?(很麻烦的那种)

git init;

他会在当前的文件夹下创建一个.git文件,但是如果你没有把该目录下的文件和远程仓库关联的话,这样做并没有什么卵用。
所以,这就需要我们时候用git remote命令来关联仓库。
当你使用git init之后,使用git o,查看你当前仓库的远端名(比如,origin). 正常情况下应该是没有的。

git init;
git remote;  //什么也没有

这时候,就是添加远程仓库的关键。 你首先要获取你远程仓库的地址,即,就是你在github或者coding上面的地址。
比如有个地址为: https://github.com/Jimmy/test.git
然后添加到本地的仓库

git remote add origin https://github.com/Jimmy/test.git

Ok~ 说一下add的参数, 首先[origin]是你自定义的仓库名,由于[origin]是git clone命令以及git相关操作默认的仓库名,所以我这里也设置为origin. 你也可以设置为自己想要的。但是在git push 的时候需要指定一样的名字.

git remote add myGit https://github.com/Jimmy/test.git
//push 命令需要一致
git push myGit

这时候,我们使用git remote查看一遍分支的信息。

git remote;
//或者使用
git remote -v;

git remote -v的作用是在显示仓库名的同时,在加上实际链接。 也许你会发现,为什么会有两个。想这样

事实上,一个仓库你可以执行两个操作(pull || fetch)。 而这样区分是因为这两个操作所需要的协议不同,方便嘛。 当然,你直接使用git remote检查也是完全没有问题的。
当然,如果你不想连接远端仓库的话,可以使用git remote rm [repositoryName]进行删除。(用到的时候真的是极少。。。)

git remote rm origin

删除origin的仓库.
远端分支的操作就介绍到这里。

版本切换

首先,我们需要使用git log来查看历史版本的序列号(永远唯一标识).

git log

会出现这样的内容:

后面52f83...什么的就是该版本的序列号。 下面的"new"就是你commit -m"xxx"里面的东西。所以说标注不好好写,到时候找到死。
我们就以该序列号来进行回退版本。
还记得我们的git reset命令吗?
一开始使用

git reset HEAD -- fileName

用来移除暂存区的内容, 其实他还有一个功能就是用来回退版本的。

git reset --hard versionId

用来回退指定版本。
这时候我们就可以使用上我们的commit 后的序列号。

git reset --hard 52f83

其实,我们只要使用前6或者5位就够了,因为这已经足够区分我们的版本啦。
另外,我们可以抽象的回退版本,比如回退上一个版本,上上一个版本,上上*一个版本等等。就需要使用到HEAD^这个指针.(由于比较难理解,有兴趣的同学可以了解,这里先pass掉)。

git reset --hard HEAD^

回退上一个版本。

git reset --hard HEAD^^

回退两个版本,当然,如果你真的像学 "万亿" 的话。估计你的"^"会用爆的。 所以,一般大于3个版本的回退,我们一般使用

git reset --hard HEAD~3

回退3个版本。
基本格式为: git reset --hard HEAD~n; 回退n个版本。
喜欢哪一种那就看你自己喜欢了。

分支操作

分支应该是git里面最棒的一个操作。通常我们开发程序的时候,通常会有两个版本,一个是master(发布版),一个是develop(开发版). 因为,我们一方面需要继续开发,一方面需要提供一个已经想对稳定的版本。 这里的却别就是,develop就是bug版,而master就是稳定版。
关于分支的相关操作是: branch 和 checkout。
创建一个分支

git branch [branchName]

加入你在master分支下面创建了一个develop分支。

git branch develop

然而此时并没什么变化。 因为git已经在后台默默的为你创建了develop分支,但是不给你看。
所以,这里我们需要使用

git branch 

查看你创建的本地分支。
不过我最喜欢用的还是

git branch -a

显示远程分支,和本地分支。 这样结构可以更加清晰,哪些我本地有,哪些我本地没有。
我们查看到我们有哪些分支后,就可以使用checkout切换分支

git checkout develop

ok~ 但事实上还有一个命令,在你创建分支的同时可以直接切换分支。

git checkout -b [branchName]

这个命令就可以达到这个效果

git checkout -b feature
git branch

并且,你会发现他会自动merge当前分支到你新建的分支上(是fast-forward的哦). 这时候,如果你做一些操作都会直接反应到你创建分支时所在的分支上。不要紧张,这时候,你只要commit一次记录,这时候,你已经脱离的fast-forward的版本了。
可以看到控制台 会显示你当前的工作区就在feature分支上.
这时候你已经创建好了分支,但是突然发现我名字起错了。
把 develop 写成 develoop(傻逼)。 没办法,只有改了。所以,我们需要先删除该分支。

git branch -d develoop
git branch develop
//或者
git checkout -b develop

that's all.
但是这个是本地的应用,如果你远端没有删除,那么远端的分支还会存在。 可以使用

git branch -a;

检查,会发现如下

那么你此时并没有完全删除远端分支,这时候就需要使用一下命令进行删除。

git push origin --delete [branchName]

这里我们要删除develoop分支。

git push origin --detele develoop

你可以使用git branch -a. 检查你的develoop远端分支是不是少了。
ok~
现在我们已经实现多分支的仓库了,但是使用下列命令不免有些繁琐。

git push origin [branchName]

这时候,我们想把所有分支都提交,则可以直接使用

git push origin --all

这样在origin仓库下的所有分支都会提交到远端。
恩,也许,在99%的时候你可以完美的推上去。那1%的情况就是别人比你先推了一次,但是特么的他把你的代码给改了,让你出现conflict(宝宝不服,谁让你改的). 我要改回来。 这时候你有两种办法,一个是回退版本,然后在commit,另外一种,就是,宝宝复原术,我强上,可以使用

git push origin --force

进行强制覆盖,这时候git自带的一切检测conflict的机制都失效了。
但,如果你已经更新git到2.x那么,此时git会弹出一个提示,要求你改动git push的效果,一般有matching和simple两种。

1. matching表示如果你push的时候没有指定分支,那么git将会push所有的分支。其实就和git push origin --all一样效果

2. simple 就是只会push当前的分支到远端

好,两种模式基本介绍完了。
现在该你选择了 :)
直接在命令行输入下列命令
第一种:matching

git config --global push.default matching

第二种: simple

git config --global push.default simple

随便选一种就可以了。
接下来,再次输入

git push --force origin

本宝宝要你覆盖我的代码。 去屎吧~
ok, 现在我们可以完成创建分支,检查分支,切换分支,提交分支这几个基本的任务。 但实际中我们还缺少了一个很重要的就是分支的合并,当你在develop分支上,已经完成新版本的测试,现在想要发布到master分支上。这里就涉及了分支的合并。
还记得我们pull的流程吗? 其实就是fetch+merge. 这里合并,同样也使用了merge这个命令。
即:

git merge [branchName]

标识合并指定分支(branchName),到当前分支。
假如我现在的分支是master,我想要合并develop分支
有:

git merge develop

Ok~ 满足~
No No No
如果你们CTO是傻子的话,当然,可以让你这么使用。
git默认情况下会使用fast-forward-merge. 即,当前的merge会直接指向develop分支,什么意思嘞?
就是在合并之后,你在master所做的一切都会反映在develop分支上。
上 上 上 啊~~例子
首先,我们先检查一下master分支和develop分支的内容。

这一作对比起见,两个分支都有相同的文件
然后,我们在develop分支里面创建一个get.js

接着我们切换到master分支看发生了什么。

<( ̄3 ̄)> 我艹。。。这么会酱汁。 多出来get.js ,要死了。
所以,为了不让这种事出现,我们需要添加上--no-ff (no- fast-forward)

git merge --no-ff develop

这时候就不会发生前面说的ff啦。 ~\(≧▽≦)/~
Ok~ 关于分支的操作我们已经学的差不多,但一些高级理念比如重构分支,hotfix分支等等我们还未理解。不急,这块内容放到下一篇。最后我在补充一点 关于tag的一些基本知识。

给你的版本打标签

如果你经常使用各种包的话,应该会有版本这个概念,比如git从以前的0.11.x版本到现在的5.x版本。 他们是如何来确定他们的版本号呢? 就是打上一个标签,比如: v0.0.1 这就是我们默认的其实版本。 而在git里面,我们需要手动给我们写的程序打上版本号。
可以使用:

git tag [tagName]

比如使用git tag v0.0.1 就可以创建一个版本号为0.0.1的标签。
之后,我们可以使用git tag来进行查看已经打的标签。 你可以打上多个标签,但是,::>_<:: , 后面你一定会忘记自己打的标签到底对应的是什么。所以,培养一个好习惯是灰常重要的。 我们需要改动一下命令,需要添加上-a -m 参数。

git tag -a v0.0.2 -m"this is first tag"

其中-a(annotation->注释),标识添加注释的意思,-m进行注释描述.
但是当我们使用git tag 查看版本的时候发现他并没有什么变化,这里我们需要该使用git show [versionId]查看指定版本。

git show v0.0.2

ok~ 这时候应该可以正常显示了。
但是,像我这么n(≧▽≦)n的人,经常会输错版本号。肿么办呢?
艹,那能怎么办,删了再创建呗。
即,先使用git tag -d [versionId]删除版本,再创建。
比如我上面将v0.0.1写成v0.1了。这时候就需要进行改动.

git tag -d v0.1;
git tag -a v0.0.1 -m"this is the default version"

Ok~
我们这里已经创建了一些版本好,但是当我们直接使用push origin 的时候并不会将你新建的tag推上去,你必须显示push才能让你的后台小弟看见。所以我们这里需要使用git push origin [tagVersion]推送
现在我们需要将v0.0.1版本推上去,有:

git push origin v0.0.1

Over~ 如果你给不同分支都创建了标签的话,那么可以使用git push origin --tags将你新增的标签全部推上去.

git push origin --tags

That's all.
一些比较高级的git操作差不多到这里啦。 最后搬一句我最喜欢的idiom:

practice makes perfect