上篇文章咱们主要简单的介绍了有关git的一些基本常识和一些简单的命令。但那终究是皮毛,咱们使用git最主要的目的仍是管理咱们的项目,多人协做。本篇文章主要涉及如下两个大模块:git
1、分支
在介绍分支以前,咱们首先先考虑为何须要引入分支这个概念,究竟有哪些没法解决的问题,须要咱们引入新的概念。github
在没有分支这个概念以前,咱们对于一个项目的开发只有一个进度,可是一旦发现项目的以前版本的某个节点出现bug,难道放弃到目前为止的全部开发,回退到bug节点进行修复吗?这是第一个亟待解决的问题。服务器
对于咱们软件业来讲,一个软件确定有不止一个版本,那么你不能要求全部用户所有升级到最新版本。那么对于同一个项目,难道咱们放弃那些仍使用旧版本的用户,直接在原项目中开发新功能吗?这也是一个未解决的问题。ssh
下面咱们从解决上述问题出发,引出分支的概念。分布式
咱们沿着一条路进行开发,head指向当前最新一次commit,整条线路咱们管它叫作分支(branch),可是咱们发现以前的某次提交中出现bug,咱们固然可使用reset指令回退版本,但会丢失掉很大一部分代码。学习
针对这种状况,咱们能够建立一个分支用于修复bug,而主分支继续开发,等bug修复完成以后,两分支合并便可。fetch
对于上述的第二种问题,版本维护的问题。加密
这样在不一样分支上的开发,两个分支彻底不相互影响。一条分支维护这旧版本,另外一条分支开发着新功能,等到旧版本再也不须要维护时,删除该分支便可。那下面咱们开始介绍分支的的相关命令。版本控制
一、git branch
和branch相关的命令主要有四个。指针
git branch:显示当前版本库中全部分支
git branch <branchname>:建立一个分支
咱们都知道,版本库中有一个head指针,它指向的是当前分支的最新提交,而咱们的上述命令只负责建立一个分支,可是不会将head指针移动到该分支上,也就是说head指针仍是指向原分支。
git branch -d <branchname>;尝试删除某个分支 git branch -D <branchname>:强制删除某个分支
在执行分支删除命令的时候,若是该分支没有合并到其余分支中,git会拒绝删除,这是为了防误删。可是若是你实在不满意对新分支的开发也能够强制删除。
下面两个命令主要用于修改分支的名称。
git branch -m <oldbranchname> <newbranchname>:尝试修改 git branch -M <oldbranchname> <newbranchname>:强制修改
若是重命名的分支名已经存在的话将会被拒绝。那么强制修改分支名称将会覆盖被同名的分支,因此全部强制操做必定要慎重。
二、git merge
要分支就必然须要合并,不然新分支上的全部开发都没法影响到主分支,这是没有意义的。因此咱们每每在新分支开发结束以后往主分支上合并。下面咱们首先看一种快进式(Fast Forwarld)的合并方式。
快进式的合并就是直接将head指针快进到较远的一个分支的最新提交,也就是说,快进式合并的两个分支是一种从属关系,像这样的:
当前head指针是指向master分支的,而当咱们对newBranch分支进行合并的时候,git将会直接把head指针移动到newBranch的最新提交上,可是head指针依然是指向master的。
咱们在进行分支合并的时候,最常遇到的问题就是合并冲突,可是咱们快进式合并是不会出现冲突的,由于两个分支是一种从属关系,进度慢的是进度快的一部分。下面咱们看看合并时遇到冲突该如何解决。
分支合并的冲突指的是,两个不一样的分支在各自开发过程当中对相同文件进行了修改,那么git在合并分支的时候将不知道选择哪一个分支上的修改做为该文件的修改,这样就产生冲突了。例如,咱们在工做区建立两个分支,在两个分支上分别对文件test进行修改,而后再合并两分支。
咱们打开致使两个分支合并冲突的文件,
git为咱们向其中添加了一些符号,其中"<<<<<<< HEAD"表示的是当前的master分支,">>>>>>> newbranch"表示的是咱们建立的新分支,而位于他们之间的"======="用于分隔两个分支的内容。从中咱们很容易的看出来,master分支中这次的提交增长了如下信息,newbranch分支上也作了一次提交并增长了以上信息,因此两个分支冲突的地方就是在这里。
为了解决这种冲突状况,咱们能够选择删除致使冲突的任意一方的修改,例如咱们删除分支newbranch上的提交。
而后咱们能够add,提交到当前分支便可完成冲突的解决。也就是说当咱们执行merge指令来合并两个分支的时候,git会尽可能去合并,可是若是遇到冲突,git也会呈现出两个文件之间的差别,要求咱们手动的去解决它。还有一些关于远程分支的内容,咱们将在下一节远程仓库中介绍。
二、远程仓库
Git做为分布式的版本控制系统,你是你本地仓库的主人,可是想要实现多人的协做开发,你就要将你本地的开发推送到远程共享仓库中供你们下载,本篇主要以github做为远程服务器来介绍有关远程仓库这块内容。
做为咱们的服务器,并不能让任何人向咱们的git服务器上推送代码,只能让有凭证的人向服务器推送。git本地和github服务器之间是经过ssh对称秘钥来完成二者的身份确认的,至于ssh是什么,不了解的同窗能够自行学习下,简单来讲,它就是一个通信加密协议。下面咱们先生成一对ssh秘钥,执行如下代码:
$ ssh-keygen -t rsa -C "youremail@example.com"
而后一路回车便可,等生成成功以后,咱们打开这个.ssh文件夹(这个文件夹的保存路径git已经给出,每一个人都不同),这里就是一对秘钥,一个是公钥,一个是私钥。公钥能够泄露出去,私钥必定保存好。接着,咱们将公钥添加到github上,
这样咱们本地的提交,github服务器就能够用列表中的公钥来识别提交者的身份,对于不认识的提交者服务器将予以拒绝。接下来咱们看如何将本地的仓库关联服务器上的某个仓库。首先,咱们在服务器上建立一个git仓库,
而后咱们执行如下这条命令来为本地git库关联远程仓库,
$ git remote add origin git@github.com:Programer-yang/TestGit.git
上述这条命令不是绝对的,读者要根据本身的github帐户和建立的远程仓库作适当的改动。执行成功以后,git是没有任何提示的,只有出现错误才会有所提示。这里的远程仓库名字,咱们默认为origin,固然也是能够修改的,这个远程仓库的简称是为了简单替代长串的URL,在之后的推送和拉取中就可使用这个简称来简化命令了。下面咱们将介绍两个命令,一个用于将本地分支推送合并到远程仓库中,一个用于从远程仓库拉取最新分支。
一、git push
该命令用于将本地分支提交到远程分支上,它的完整命令格式为:
$ git push <远程主机名> <本地分支名>:<远程分支名>
例如咱们向在本地分支新建一个test文件,而后向github推送。
而后咱们打开github帐户,能够明显看到咱们建立的仓库收到一次提交,时间显示几分钟以前,而咱们本地新建的文件也随着提交被建立在服务器上。
二、git pull
该命令主要用于拉取位于服务器上的最新分支到本地并合并,它等效于 git fetch + git merge。命令git fetch 会拉取服务器上的分支并保存在版本库的某个文件夹下,命令git merge则会将拉取下来的版本库与本地版本库进行合并。而咱们的git pull命令就是两个命令的结合。它的格式以下:
git pull <远程主机名> <远程分支名>:<本地分支名>
基本格式和上述介绍的push 命令相似,下面咱们在服务器上新建一个文件index,模拟他人对仓库的提交,这样服务器上的分支就比本地的分支上游一次提交,咱们在本地拉取服务器上最新分支。
打开咱们工做目录,便可看到拉取下来的index文件,此时咱们的本地版本库就和服务器上的仓库如出一辙。
至此,咱们简单的介绍了git中较为强大的两部份内容,分支的远程仓库。不少命令都有其简写的方式,以及使用参数和选项来简化操做,这里咱们并无介绍,在后续更加深刻的文章中,这里的某些命令可能还会出现。整体上来讲,本篇介绍的内容还算简单,总结不到之处,望指出,下一篇咱们将介绍强大的检出和重置命令。