(八)标签的管理及配置别名详解
最后更新于:2022-04-01 20:06:50
**标签管理**
通常咱们发布(release)一个版本时需要打标签,这样可以方便咱们以后要取某个标签版本时,直接把那个相应标本的历史版本取出来即可,它其实是一个版本快照。
标签和分支有点像,都是指向某个commit的[指针](http://blog.csdn.net/lhy_ycu/article/details/9346377),但[分支](http://blog.csdn.net/lhy_ycu/article/details/20849807)是可以移动的,而标签是不可以移动的,并且创建和删除标签的过程是非常快的。
咱先切换到主分支master,然后再对它打标签:

咱们可以通过git tag来查看所有标签:

标签默认是打在最新的提交上,有时候如果咱们忘了打标签,前两天该打的标签没有打,这时咱们采用的方式是,找到以前的历史提交的id,然后再打上标签即可:

比如这时我们要对add 1.txt打上标签v.0.3:

然后咱查看一下标签:

这时可以使用git show v0.3来查看标签信息:

当然如果标签打错了,也可以删除:

**配置别名**:配置别名是为了咱们更简化键入的命令,使我们更方便的进行操作。
举例说明1:git config --global alias.st status

举例说明2:git config --global alias.ct checkout

这样通过简化缩写,更方便的切换到了b1分支上,当然还用很多都可以配置,这里就不再一一举例了。
';
(七)Bug和Feature分支管理详解
最后更新于:2022-04-01 20:06:47
当咱们拿到一个新的bug或者feature(功能)时,首先应该想到通过分支来完成咱们的任务。因为在软件开发中,总是会根据客户的需求不断的添加新的feature进来,同时在做移动开发过程中bug也可以说是“常客”。通过前几章的内容,相信咱们很自然会想到创建一个新的branch(分支),在此分支上来修复bug或者实现feature,完成后,然后再merge(合并)到咱们的主分支上。
当咱们接到一个比如说是关于空指针的bug,而咱们手中的活(在b1分支上的bug)还没提交,预计要半天的时间,但新的bug必须在1小时内修完。这时咱们就要用到“储存现场”的功能git stash,这样咱们可以在修护新的bug之后再恢复现场来继续原先还没有提交的操作。下面咱们先修改之前的hellogit.txt文件的,修改内容为:
~~~
Hello Git
Git is so easy.
~~~
然后咱们仍然使用git status来观察一个该文本的状态:

可以看到红色部分提示,该文件已经被修改,同时该文件的状态仍处于工作区中,这是咱们接到一个新的bug,上级要求必须尽快修复,这时咱们先“保存现场”:

用git status查看工作区,就是干净的,除非有没有被Git管理的文件:

因此咱可以放心地创建分支来修复bug,现在假定咱们使用主分支(master)来修复咱们的这个新的bug,就从主分支上创建一个临时分支b2:

现在修复1.txt中的bug:

bug修好了,下面提交:

切换到主分支上在merge(合并):

然后删除临时分支b2:

好了,新的bug已经修复完,下面就可以继续回到咱们原来的分支(b1)上继续工作了:

咱们可以看到,工作区是干净的,之前咱们“储存的现场”哪去了呢?咱可以用git stash list来查看:

存储的工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
方法一:先用git stash apply来恢复现场,然后再用git stash drop来删除stash内容;
方法二:直接使用git statch pop来恢复并删除stash内容。
咱们为了方便,就直接用git stash pop了:

可以看到b1分支上hellogit.txt的状态又回来了,咱又可以继续在b1分支上干活了
。
**总结**:(1)存储现场:git stash
(2)查看工作现场:git stach list
(3)恢复现场有两种:1,使用git stash apply 来恢复,然后再使用git stash drop来删除stash的内容。
2.使用git stash pop,来恢复并删除stash内容。
(4)如果要多次使用stash,恢复的时候先用git stash list查看,然后在指定你要恢复的内容:git stash apply stash@{0}。
( 5) 如果要丢弃一个没有合并的分支,可以使用git branch -D branch-name。
';
(六)解决分支冲突及分支管理策略
最后更新于:2022-04-01 20:06:45
**解决分支冲突**
通常当Git无法自动合并分支时,就必须首先解决冲突后,再提交。
下面咱们先创建一个分支并切换到b1分支:

修改咱们之前的hellogit.txt内容,添加一行:Create a new named f1 branch

查看该文件的状态,并提交至本地仓库:

然后切换至master分支:

然后在master分支上把hellogit.txt文件的最后一行改为:switch to master.
最后在master分支上提交:

现在,master分支和b1分支各自都有自己新的提交,这种情况下,Git无法执行想上一章一样进行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。

Git告诉我们,hellogit.txt文件存在冲突,必须手动解决冲突后再提交,通过git status可以告诉我们冲突详情:

可以看到hellogit.txt在两个分支上都没修改且这两个分支没有merge,下面来看看helligit.txt的内容:

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:Create a new named f1 branch;再提交:

好了冲突已经解决并提交了,那么现在就可以删除b1分支了:

小结: 当Git无法自动合并分支时,就必须首先解决冲突后,再提交。
**分支管理策略:**
现在我们仍然创建并切换至b1分支:

然后修改一下hellogit.txt的内容,再提交:

然后回到master主分支上:

这时,我们merge加上两个参数:--no-ff参数(表示禁用“Fast forward”),-m(和comimt一样,为merge新提交时的信息):
**使用--no-ff好处是**:能看出来哪些分支曾经做过合并。

合并后,我们用git log看看分支历史:

**小结**:合并分支时,Git会默认使用“Fast forward”模式,但这种模式下,删除分支后,会丢掉分支信息。
在实际工作中,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面进行开发,一般都是依赖(你和你的同事)各自的分支去进行新的feature开发或解决新的bug,有需要的时候再merge一下就可以了。
';
(五)分支管理详解
最后更新于:2022-04-01 20:06:43
分支管理在咱们实际工作中经常用到,因此掌握分支对于咱们从事移动开发并且使用到了Git这样的分布式版本管理工具来说是很有必要的。比如当你饿了的时候,甲帮你做饭,一帮你烧菜:

当然你也可以自己做饭烧菜。但是咱们仍然可以看到,我是从一个饿的状态变成了一个饱的状态,也就是我之前空腹,后来我由甲(分支)和乙(分支)两人同时来帮我完成了完成了“做饭”和“烧菜”的功能,而我的状态也从饥饿变成了吃饱的状态(即饭和菜都提交到了我的肚子里
),这样咱又有力气干活了。
分支在实际中有什么用呢?假设你准备开发一个新feature,但是需要10天才能完成,前5天你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了,但是如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。有了分支,你创建了一个你自己的分支,别人是看不到的,你还继续在原来的分支上正常工作,直到开发完毕后,再一次性合并到原来的分支(俺饿了...)上,这样,既安全,又不影响别人工作,而且Git分支的创建和修改、删除都是非常快的。
**创建分支**:
使用Git时的每一次提交,Git都会把它们串成一条时间线,这条线就是一条分支。咱们之前一直在master分支上操作,它是一条主分支,并且它指向的是最新的提交,而咱们前面章节讲的HEAD其实指向的就是master,这样就能确定当前分支,以及当前分支的提交点:每次咱们提交时,master就会向前移动一步。当咱们创建新的分支,例如Git新建了一个分支叫dms001,指向master相同的提交,再把HEAD指向dms001,就表示当前分支在dms001上了。(这里可能不好理解,不过你只要记住一点就行了:HEAD指向的是当前分支,而刚创建的分支dms001指向的是提交)

下面咱们开始操作一下:
首先创建一个dms001分支,然后切换到dms001分支上(即让HEAD指向该分支)

然后咱们可以通过git branch来查看当前分支是不是在dms001上(当然也可以直接使用git checkout -b dms001来创建并切换至dms001分支):

可以看到星号指向了dms001,这里暂且把星号(*)看成HEAD指针,如果大家对指针不怎么理解的话,可以看看我之前写的一篇“[谈谈我对指针的认识”](http://blog.csdn.net/lhy_ycu/article/details/9346377)。
创建好分支后,咱们再来对之前hellogit.txt文件做做修改,先cat hellogit.txt看看里面的内容:

在该文件中再加一句:Create a named dms001 branch.

通过git status咱们可以看到,hellogit.txt确实被修改了,而且该状态位于[工作区](http://blog.csdn.net/lhy_ycu/article/details/20651051)。
下面通过前两章讲的,将该文件状态变成[暂存区](http://blog.csdn.net/lhy_ycu/article/details/20651051)状态:

然后提交到咱们的[本地仓库](http://blog.csdn.net/lhy_ycu/article/details/20651051):

最好咱们将分支切换回主分支master:

切换回master分支后,再看一下hellogit.txt文件,刚才添加的那句“Create a named dms001 branch.”不见了!因为那个提交是在发生在dms001分支上,而master分支此刻的提交点并没有变:

**合并分支:**
合并分支命令很简单,但请注意:合并分支一定要切换至主分支,并且要合并的分支必须commit了:

这时master就指向了dms001的提交了。
请注意:咱们实际工作时一般是没有权限merge的,但因为是学习,所以还是有必要了解一下的。
**删除分支:**
好了,既然已经merge好了,那么我们就可以放心的删除分支dms001了。删除命令如下:

好了,咱又只剩master分支了,可以看到无论是创建、合并还是删除分支,速度都是非常迅速的,这也是Git一个非常重要的[特点](http://blog.csdn.net/lhy_ycu/article/details/20574453),而且工作中常用分支来完成咱们的工作。
**小结**:
本章出现的一些概念和常用命令希望大家多花点时间消化和多多操作。
';
(四)远程仓库及其与本地仓库交互
最后更新于:2022-04-01 20:06:41
**创建GitHub账号及获取SSH秘钥对**
创建远程仓库通常有两种方式:
1、把一台电脑充当服务器,让它每天开机,其他人都从这台“服务器”仓库clone一份到自己的电脑上,并把各自的修改(包括添加了新的feature、解决了新的bug等)提交到“服务器”仓库中,当然你也可以从“服务器”仓库中拉取别人的提交。实际开发中一般就是这么做的。
2、因为咱毕竟还是处于学习当中,为了学Git去整个"服务器"未免有点“杀鸡焉用牛刀”的感觉。好在有个为Git仓库提供托管服务网站的名为GitHub的网站,可以由它来创建并管理远程仓库。
因此,咱选择第二种方式来创建远程仓库,先进官网去瞧瞧,[GitHub官网](https://github.com/):

账号请大家自行注册。由于你的本地Git仓库和远程GitHub仓库之间的传输是通过[SSH](http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html)协议加密的,因此需要进行一些设置。
步骤如下:
1)、创建SSH Key。在创建SHH Key之前看看在用户主目录有没有.ssh文件夹,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可以直接跳过这一步。如果没有,打开咱第一章叫大家安装的Git Bash,创建的命令如下:

注意:把email地址换成你自己的,然后一直按回车键即可(只为学习,也无需设密码)。
然后,你将看到主目录里面多了一个.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,id_rsa.pub是公钥。
2)、用你刚创建的GitHub账号登录GitHub网站,打开“Account settings”(你可能看到上面有个感叹号,那是因为像我们平常注册账号一样,需要激活,我们可以点进去填入**Name,**Email (will be public)**然后进入邮箱确认激活即可),然后点击左侧的“SSH Keys”页面,

然后,点“Add SSH Key”,输入Title,在Key文本框里粘贴id_rsa.pub文件的内容:

点击Add key:

为什么GitHub需要SSH Key呢?因为GitHub需要确认推送的提交是你做的,而不是别人冒充的,而Git支持SSH协议,所以GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。然后你也可以添加多个SSH key,只需把别的电脑上的Key添加即可,这里不再赘述。注意:在GitHub上免费托管的Git仓库(既然是免费,那然后大家都可以看到),只有自己才能修改,所以建议大家不要把重要的资料托管上去。如果你不想让别人看到你的Git仓库,有两种办法,一是交点钱给GitHub,让它把你管理(其他人是看不到的,也就是说你的Git仓库变为了私有);还有一种方法,那就自己搭个Git服务器吧,通常公司做开发也就是这么干的。
**创建并添加远程仓库**
有了GitBub账号,登录后找到右上角的“Create new...”:

点击New repository(即创建一个新的仓库):

然后在Repository name中输入mygit,点击Create repository即可:

好了,这样就创建了一个仓库。现在这个远程的mygit仓库还是空的,下面我们把上面章节中创建的本地mygit仓库推送到这个远程仓库中。咱们的思路是把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
**将本地仓库推送至远程仓库**

其实GitHub已经帮我们写好要在Git Bash中输入的命令了,我们只需按它写的来执行即可:

这里添加名为origin1的远程库,当然你也可以把名字换成别的。注意:这里的xiaokefeixia换成你的GitHub账户名。
下面就可以把本地库的所有内容推送到远程库上:

用git push命令把本地库的内容推送到远程,实际上是把当前分支(关于分支,后面会讲到)master推送到远程。
以后只要本地做了提交。就可以使用git push origin1 master #把本地master分支的最新修改推送至GitHub。
**从远程仓库clone至本地**
和之前一样,先登录GitHub创建一个新的远程库,叫做clonegit,记得勾选一下:

这样就可以帮我们创建一个README.md文件,如图:

好了,远程库准备好了,下面咱再用git clone 命令来clone一个到本地:

然后把们将看到,用户主目录下多了一个clonegit目录,而且里面还有README.md和.git:

这样我们就成功的从远程仓库clone了一个到本地了。是不是so easy呢~
**小结**:
将本地仓库推送至远程仓库(以下的用户名及仓库名要换成自己的哦):
1、关联一个远程仓库,使用git remote add origin git@github.com:xiaokefeixia/mygit.git ;
2、关联之后,可使用git push -u origin master第一次推送master分支的所有内容;
3、以后每次本地提交后,就只需敲入命令git push origin master推送最新修改到远程即可。
从远程仓库clone(要克隆得知道远程仓库的地址)至本地:
1、创建一个远程库clonegit;
2、然后使用命令:git clone git@github.com:xiaokefeixia/clonegit.git即可。
';
(三)版本回退和管理文件的修改及删除操作
最后更新于:2022-04-01 20:06:38
**版本回退**
前面我们成功的提交了一次mygit.txt,下面咱对它进行修改,内容如下:
~~~
Hello Git
Git is so easy.
~~~
然后用git status来跟踪该文件的状态:

可以看到hellogit.txt已经被修改过了,到底这次修改的内容与上次的内容有什么不同的,咱们可以使用git diff查看:

当然你也可以查看上次提交的信息,使用git log:

通过前面一章我们知道,该文件还处于工作区,因此我们又可以使用add、commit操作了:


这里笔者偷了个懒,直接用-m表示提交的信息,当然在学习过程中咱可以这样,但实际工作中一般不这么写。
好了,提交完后咱再用git status来跟踪一下(建议多使用git status)状态:

这里依然是:Git告诉咱们当前没有需要提交的修改,而且工作目录是干净的。
下面再学一个命令:git reflog,它主要用来记录你的每一次命令和commit id,这个命令非常有效,也建议大家常用。

可以看到咱提交的id号和提交的message被显示出来了。
加入你现在不想修改了,想回到原来那个版本,该怎么办呢?别急,这一点Git早就帮我们想好了,使用git reset --hard HEAD^
注意:这里HEAD上面^表示回到上一个版本,如果想回到前面第五个版本呢?我们可以用git reset --hard HEAD~5,当然因为我们这里只修改了1次,所以我们最多只能回到前面一个版本。打开hellogit.txt看看,是内容不是Hello Git呢?
当然如果你又想修改回去,那么咱们还有办法,用git reset --hard commit-id:

注意:这里的e75e865指的是commit id,上面已经说了,这里就不再赘述。
**撤销修改:**
下面我们再次对helliogit.txt进行修改,内容如下:
~~~
Hello Git
Git is so easy.
Easily learn the Git.
~~~
然后我们用git status跟踪状态:

这里Git会告诉你,git checkout -- file可以丢弃工作区的修改:

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,然后在查看状态:

工作目录有变回”clean“了,查看hellogit.txt内容 cat hellogit.txt

内容又改回来了,这样就完成了一次简单的修改撤销。如果你把文件内容修改为原来添加时的:
~~~
Hello Git
Git is so easy.
Easily learn the Git.
~~~
git add hellogit.txt到了暂存区,咱们还有办法,使用git reset HEAD hellogit.txt来返回到工作区状态:

竟然已经回到了工作区,那么咱们就可以向之前那样,使用git checkout -- hellogit.txt了:

好了,一切又回到了,原来的状态。如果你还从暂存区提交到了版本库,还记得上面的版本回退吗?可以回到上一个版本就OK了,不过如果你还将本地的修改推送到远程版本库(后面会讲),那就没有后悔药吃了。
**删除文件**:
前面已经说了,在Git中,删除也算一个修改操作。下面咱们先添加一个新文件1.txt到Git并且提交:

这是你如果执行rm 1.txt把1.txt文件删了,那么这个时候,Git知道你删了文件,工作区和版本库就不一致了,我们再用git status跟踪一下:

这是你有两个选择,一是确实要从版本库中删除,使用git rm 1.txt并commit一下:

注意:你删除之后,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
另一种情况,你觉得你删除了想修改过来,因为版本库中还存在,所以可以很轻松地把误删的文件恢复到原来版本。

可以看到,1.txt有回到工作区了。
**总结**
今天内容比较多,可能需要点时间慢慢消化,如果有哪里写的不对多需要改进或哪里的地方可以留言,我现在的工作很闲。
明天开始讲远程仓库。
';
(二)创建本地仓库及文件操作
最后更新于:2022-04-01 20:06:36
**仓库(repository ),**我们也成它为版本库。这个库里面的所有文件(包括对文件的添加、删除、修改等操作)都被Git管理起来,而且我们随时可以跟踪版本以便更好的对库里的每个文件进行更新和还原。咱还是像昨天一样,先进[官方网站](http://git-scm.com/docs)瞧瞧:

点击init,你将看到这样一句话:

git init—创建一个空的Git存储库或初始化现有的一个版本库。不难发现,咱们要初始化一个本地版本库,用的就是它了。
~~~
$ mkdir mygit
$ cd mygit
$ git init
~~~
注意咱创建目录的时候,最好不要出现中文,以免出现乱码等不必要的问题。Git仓库创建很快,这里需要值得注意的是,由于Git仓库在创建创建时,它会生成一个隐藏的.git目录(这里面的文件大家千万不要手动修改,以免版本库被破坏),查看隐藏文件的方式相信大家都会,这里不再赘述。
下面咱们学习一下几个命令来修改和跟踪咱们的文件:

首先咱先了解**几个名词**:工作区<-->暂存区<-->版本库。
工作区(Working area):就是咱们刚才创建的mygit文件夹。
暂存区(Staging area):对文件操作(也就是需要提交的文件修改)的地方就叫暂存区。--注意:这里的修改包括对文件的增删改。
版本库(Repository):就是你所看到的的那个隐藏的“.git”目录,它就是咱们的版本(仓)库。
下面我们在mygit目录(或其子目录)下编写一个hellogit.txt,在里面写上内容如下:
~~~
Hello Git
~~~
然后咱们用git status来查看该文件的状态:

注:git status命令可以让咱们随时了解当前版本库的状态,而上面的打印的信息告诉我们,hellogit.txt被修改过了,红色告诉我们该本件的状态仍处于工作区。
接着咱们通过git add hellogit.txt命令将该本件添加到暂存区:

执行上面命令后,没有任何显示,就说明添加成功。
下面咱用命令git commit告诉Git,把该文件提交到仓库:

接着你将看到:

这里一定要注意:咱们要在里面编写(按i键)的内容就是咱们要提交时的信息(message),实际工作中,这个信息一般分3行title、describe、FIX=DMSXXXXXXXX。信息一定要精确,笔者第一个提交的时候,总是因为描述不够精确被打下来了好几次。这里是笔者随手的一个demo,仅供参考:

然后按Esc键后,输入:wq即可。咱们再用git status来跟踪一下该文件的状态:

Git告诉咱们当前没有需要提交的修改,而且工作目录是干净的。
**总结:**
由于内容多,所以笔者打算分两篇写完,还请见谅。
';
(一)初识Git
最后更新于:2022-04-01 20:06:34
Git作为一个版本控制工具,在工作中我们常常会用到它,尤其是在移动开发中,Git可谓是版本管理神器。下面让我们来认识一下Git:
Git是一个分布式版本控制软件,它是由Linux的作者Linus用C写的一个分布式版本控制系统。
如果大家对Git的历史比较感兴趣,可以点击链接进入官网了解:[A Short History of Git](http://git-scm.com/book/en/Getting-Started-A-Short-History-of-Git)
**Git主要特点有如下**:
1、速度:Git在本地上保存着所有当前项目的版本和更新,并且Git中的绝大多数操作都在本地,无需连网,所以处理起来速度。
2、简单的设计:Git的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。
3、完全分布式模式:每个人电脑上都有一个完整的版本库,而且它支持离线工作(大部分操作都是本地执行),本地提交可以稍后提交到服务器上。
4、对非线性开发模式的强力支持:允许上千个并行开发的分支。
要学习Git,当然咱首先得下载安装了,大家可以点击[链接下载Git](http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git),看到下图:

由于是以前笔者就安装过了,所以还是用的以前的1.8.4版本。安装的过程比较简单,直接点击下一步就可以了。
安装后双击Git Bash,蹦出一个类似命令行窗口的东西,输入git --version,可以看到如下图:

好了,既然Git已经安装成功了,在正式学习Git之前,咱先去官网瞧瞧,去看看[官方文档](http://git-scm.com/docs)有些啥东东。

官网的说明都比较详细,如果有英语比较好的朋友,相信很快就能掌握。对于笔者这样英语不怎么好的童鞋来说,看起来还是要费些精力滴
。但咱毕竟还是得“穿一手鞋”。
一看命令有点多,先别急。由于Git是分布式版本控制系统,所以咱先“自报家门”,点击config,然后CTRL+F找到user.name、user.email

大家可以在命令行输入:
$ git config --global user.name "your name"
$ git config --global user.email "email@example.com"
注意git config命令的--global参数,顾名思义,用了这个参数,表示你这台电脑上所有的Git仓库都会使用这个配置(这个应该很好理解),当然你也可以对某个仓库指定不同的uer.name和user.email。当然如果大家没有配置该信息的话, 一般情况下在git提交时会使用机器名,这样肯定不方便了。所以笔者建议大家都配置明确的user.name 和 user.email信息。
配置好了后,大家可以使用git config -l来查看当前的git配置列表。
**注意:如果你是在windows中执行Git命令,遇到WARNING: terminal is not fully functional
解决方案:环境变量中新建一个变量名为TERM,值为cygwin,重新执行git命令即可。**
**小结**:
今天主要是让大家认识一下Git,明天开始正式学习用Git来管理我们的仓库(版本库)及版本更新。
';
前言
最后更新于:2022-04-01 20:06:31
> 原文出处:[Git学习系列](http://blog.csdn.net/column/details/git-lover.html)
作者:[lhy_ycu](http://blog.csdn.net/lhy_ycu)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# Git学习系列
> 主要为Git初学者提供帮助,内容丰富详实、具体、通俗易懂
';