Git Step by Step (6):Git远程仓库

jopen 10年前

原文出处: 田小计划的博客    

前面文章中出现的所有Git操作都是基于本地仓库的,但是日常工作中需要多人合作,不可能一直都在自己的代码仓库工作。所以,这里我们就开始介绍Git远程仓库。

在Git系统中,用户可以通过push/pull命令来推送/获取别的开发人员的更新,当时对于一个工作组来说,这种方式会效率比较低。所以,在一个Git系统中,都会有一个中心服务器,大家都通过中心服务器来推送/获取更新。

为了方便本篇例子的进行,我就使用多个目录来模拟多个用户以及中心服务器,这样就不用搭建Git服务器了。

  • 中心服务器:C:\VM\CentralRepo
  • 用户wilber:C:\VM\wilberWorkSpace
  • 用户will:C:\VM\willWorkSpace

Git远程仓库命令

建立中心服务器

通过前面的文章我们知道可以通过”git init”来建立一个Git仓库,这里,我们使用”git init –bare”来建立中心仓库,注意”–bare”参数,后面进行介绍。

到这里,一个空的中心服务器就建好了。

 Git Step by Step (6):Git远程仓库

Clone一个仓库

在Git中,我们有两种方式建立Git仓库:一个是通过”git init”建立一个新的仓库,另一个是通过”git clone”命令clone一个已有的Git仓库。

既然中心服务器,用户will就可以通过clone命令来复制一个Git仓库。

 Git Step by Step (6):Git远程仓库

从上面的clone操作可以看到,在clone命令中需要给出目标仓库的地址,Git支持http、ssh以及git原生协议来进行clone。这里为了演示,我们就使用本地目录。

这时,用户will就从中心服务器clone了一个空的仓库,接下来will就可以在这个本地仓库工作了。

更新的push和pull

现在will在本地仓库中添加了一个”calc.py”的文件,并且提交到了本地仓库。

 Git Step by Step (6):Git远程仓库

为了是其他用户可以得到这个更新,will需要把这个更新push到中心服务器上。

 Git Step by Step (6):Git远程仓库

现在用户wilber通过clone方式获得了中心服务器上的仓库副本,通过”git log”will的更新已经自动被clone了下来。

 Git Step by Step (6):Git远程仓库

现在,wilber提交了一个新的更新,那么will就可以通过pull的方式从中心服务器得到这个更新。

 Git Step by Step (6):Git远程仓库

–bare

现在我们看看建立中心服务器时候用到的”–bare”选项。

“git init –bare”方法创建的是一个裸仓库,之所以叫裸仓库是因为这个仓库只保存Git历史提交的版本信息,而不允许用户在上面进行各种git操作。

之所以有裸仓库,是因为用”git init”初始化的版本库,用户也可以在该目录下执行所有git方面的操作。但别的用户在将更新push上来的时候容易出现冲突。在这种情况下,最好就是使用”–bare”选项建立一个裸仓库。

上游仓库(upstream repository)

在Git系统中,通常用”origin” 来表示上有仓库。我们可以通过 “git branch -r”命令查看上游仓库里所有的分支,再用 origin/name-of-upstream-branch 的名字来抓取(fetch)远程追踪分支里的内容。

 Git Step by Step (6):Git远程仓库

从上面可以看出,对于wilber的仓库,master分支的上游分支是中心服务器的master分支。

通过上一篇文章的内容,我们可以在中心服务器上建立两个新的”release-1.0″和”release-1.1″分支,通过pull命令,用户wilber就看到了这些上游分支。

 Git Step by Step (6):Git远程仓库

–set-upstream-to

当我们相当然的按照前一篇文章在本地仓库建立一个branch的时候,我们的pull操作会遇到以下问题,提示我们这个branch没有任何的跟踪信息。仔细想想也是,我们应该把本地仓库中的分支与上游分支关联起来。这时,我们就可以根据Git的提示,使用”–set-upstream-to”命令进行关联了。

 Git Step by Step (6):Git远程仓库

当然,在Git中我们可以直接通过”git checkout -b localBranchName origin/remoteBranchName”来创建关联分支。建议一般把”localBranchName”名称跟”remoteBranchName”名称设置成一样。

 Git Step by Step (6):Git远程仓库

牛叉的patch

在Git中patch绝对是一个很有用的东西。假设在一个没有网络的环境中,wilber和will还要继续工作,这时wilber有一个更新,will需要基于这个更新进行下一步的工作。如果是集中式的代码版本工具,这种情况就没有办法工作了,但是在Git中,我们就可以通过patch的方式,把wilber的更新拷贝给will。

在Git中有两种patch的方式:一是通过”git diff”生成一个标准的patch,另一个是通过”git format-patch”生成一个Git专用的patch。

基于”git diff”的patch

假设现在wilber更新”calc.py”文件并且通过”git diff”生成了一个patch。

 Git Step by Step (6):Git远程仓库

下面,我们把wilberPatch这个文件拷贝到will的工作目录中,然后通过”git apply”应用这个patch,从而得到wilber的更新。

 Git Step by Step (6):Git远程仓库

基于”git format-patch”的patch

同样使用上面的例子,这次我们使用”git format-patch”来生成patch。

注意”git format-patch”命令的参数”origin/master”,这个参数的含义是,找出当前master跟origin/master之间的差别,然后生成一个patch。

 Git Step by Step (6):Git远程仓库

把patch文件拷贝到will的工作目录,则此我们通过”git am”命令来应用这个patch。

 Git Step by Step (6):Git远程仓库

两种patch方式的比较

下面简单看看两种patch方式的比较。

  • patch兼容性:”git diff”生成的patch兼容性强。也就是说,如果别人的代码版本库不是Git,那么必须使用git diff生成的patch才能被别的版本控制系统接受。
  • patch合并提示:对于”git diff”生成的patch,你可以用git apply –check 查看patch是否能够干净顺利地应用到当前分支中;如果”git format-patch” 生成的patch不能打到当前分支,git am会给出提示,帮你解决冲突,两者都有较好的提示功能。
  • patch信息管理:通过”git format-patch”生成的patch中有很多信息,比如开发者的名字,因此在应用patch时,这个名字会被记录进版本库,这样做是比较合理的。

总结

通过这篇文章,我们了解了远程仓库的命令以及操作。其实,这才是Git中最常见的工作方式,大家都通过中心服务器来交换跟新。

同时,我们见识到了Git的patch工具,patch也是一种很常用的交换更新的方式。