凯少

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

目前为止,所有的Git操作都是在一个本地版本库中。现在是时候来体验Git分布式的特性了。

说到远程版本库,大家最为熟悉的就是GitHub了,它实际上就相当于一个远程版本库,托管着所有的本地版本库的提交,同时也可以把GitHub上的内容抓取到本地,从而实现多人协同工作。

1,版本库概念

  1-1,裸版本库开发版本库

    一个 Git版本库 要么是一个裸(bare)版本库,要么是一个开发(非裸,development,nonbare)版本库。

    开发版本库用于常规的日常开发,前面章节中所使用到的都是开发版本库。

    裸版本库是是没有 工作区 的,并且不应该用于正常开发,它也没有检出分支的概念。裸版本库可以简单得看做 .git 目录的内容。但它的角色是关键的:作为协作开发的权威焦点,其他人员从裸版本库中克隆(clone)和抓取(fetch),并退sing(push)本地更新。

    git init --bare 会创建一个新的空的裸版本库。

  

  1-2,版本库克隆

    git clone --bare 则会创建一个新的包含上游版本内容的副本的裸版本库。

    git clone 命令基于我们通过文件系统或网络地址指定的原始版本库。正常使用 git clone 命令时,原始版本库存储在 refs/heads 下的本地分支,会成为新的克隆版本库中 refs/remotes/ 下的远程分支。而原始版本库中 refs/remotes/ 下的远程分支则不会被克隆。(克隆是不需要知道有什么上游版本库被追踪的。)

    原始版本库中的标签会被复制到克隆版本库中,然而,如原始版本库中的钩子,配置文件,引用日志,储藏都不在克隆中重现。

  

    默认情况下,每个新的克隆版本库都通过一个成为 origin 的远程版本库,建立一个链接指向它的父版本库。但,原始版本库并不知道任何克隆版本库,仅仅是一个单向关系!

    origin 这个名称并没有什么特别之处,可以在克隆操作过程中使用 --origin 名称 选项带指定替代名。

    远程版本库的分支在克隆版本库中是可用的,只要在分支名前加上 origin/ 前缀,如 origin/master 标识原始版本库的 master 分支。

 

  1-3,远程版本库

    我们在工作中使用的版本库成为本地(local)或者当前(current)版本库,我们交换文件用的版本库成为远程版本库(remote repository)。

    Git使用远程版本库和远程追踪分支来引用另一个版本库。使用 git remote 命令创建,删除,操作和查看远程版本库。所引入的所有远程版本库都记录在 .git/config 文件中,可以用 git config 来操作,出了 git clone 命令之外,跟远程版本库有关的其他常见的Git命令有:

    * git fetch

      从远程版本库中抓取对象及其相关的元数据。

    * git pull 

      根 git fetch 类似,但合并修改到相应的本地分支。

    * git push

      将本地对象及其相关的元数据推送到远程版本库。

    * git ls-remote

      显示一个给定的远程版本库的引用列表。

   

2,git clone 命令

  远程操作的第一步,通常都是从远程版本库中克隆一个版本库,最简单的命令如下 git clone <远程版本库地址>,比如克隆GitHub上托管的Linux内核的版本库:https://github.com/torvalds/linux.git 。该命令会在本地目录生成一个目录,默认与远程版本库同名。想要指定不同的目录名,可以使用 git clone <远程版本库地址> <本地目录>。为远程版本库指定名字可以使用 git clone -o <主机名> <远程版本库地址> <本地目录>

  克隆命令支持多种协议:

  1,git clone http[s]://abc.com/path/repo.git/

  2,git clone ssh://abc.com/path/repo.git/ 

  3,git clone git://abc.com/path/repo.git/

  4,git clone /home/git/repo.git/

  5,git clone file:///home/git/repo.git/

  6,git clone ftp[s]://abc.com/path/repo.git/

  7,git clone rsync://abc.com/path/repo.git/

  通常来说,git协议的下载速度是最快的,SSH协议用于需要用户认证的场合。

 

3,git remote 命令

  Git要求每个远程版本库都必须指定一个主机名。git remote 就是用于管理主机名的。上面已经说过,该主机名默认为 origin,也可以自己指定。

  

  git remote -v 选项可以查看远程主机的抓取和推送地址:

    

  git remote show <主机名> 命令可以查看远程版本库的详细信息:

  

  git remote add <主机名> <地址> 用于添加远程主机

  git remote rm <主机名> 用于删除远程主机

  git remote rename <原主机名> <新主机名> 用于远程主机名的修改   

 

4,git fetch 命令

  一旦 远程主机 的版本有了更新(有了新的commit),那么就需要将这些更新到本地。这时,就要用到 git fetch 命令了:git fetch <远程主机名>

  

  默认情况下,git fetch 取回所有分支的更新。如果指向取回特定分支的更新,可以指定分支名:git fetch <远程主机名> <远程分支名>

  前面在《Git分支》介绍过,命令 git branch -r 可以用来查看远程分支,git branch -a 可以查看所有分支(本地分支+远程分支)。

  

  

  取回远程主机的更新之后,就可以在它的基础上,使用 git checkout 命令来创建一个新的本地分支:git checkout -b <branchname> origin/master 。在 origin/master 的基础上,创建一个新的本地分支。

  此外,也可以使用 git merge 命令或者 git rebase 命令:

  git merge origin/master 在当前分支上合并 origin/master 远程分支。

  git rebase origin/master 变更当前分支的基点 origin/master

 

5,git pull 命令

  命令 git pull 的作用是,取回 远程主机 的 某个分支 的更新,再与本地的指定分支进行合并。它的完整格式有点复杂:git pull <远程主机名> <远程分支>:<本地分支>

  比如取回 originbug/no-8080 分支,与本地 master 分支进行合并:git pull origin bug/no-8080:master

  

  在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在 git clone 时,所有本地分支默认与远程主机的 同名分支 建立追踪关系。也就是说,本地的 master 分支自动追踪 origin/master  分支。

  Git也允许手动建立本地分支与远程分支的追踪关系:git branch --set upstream master origin/bug/no-8080

  如果本地的当前分支与目标远程分支存在追踪关系,那么 git pull 就可以省略远程分支名。

  

  如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致 git pull 不知不觉删除了本地分支。但是,我们可以改变这个行为,加上选项 -p 就会在本地删除远程主机已经被删除掉的分支:git pull -p 其等价于:

  git fetch --prune origin

  git fetch -p

  

6,git push 命令

  命令 git push 用于将本地分支的更新,推送到远程主机,它的格式与 git pull 命令相似:git push <远程主机名> <本地分支>:<远程分支>

  如果省略远程分支明,则表示将本地分支推送到与之存在“追踪关系”的远程分支(通常来说 两者同名)。如果该远程分支不存在,则会被新建。

  如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程主机。

  如果本地的当前分支与目标远程分支存在“追踪关系”,则本地分支与远程分支都可以省略。

  如果当前分支只有一个追踪分支,那么主机名都可以省略掉。

 

  如果当前分支与多个 远程主机 存在“追踪关系”,则可以使用 -u 选项指定一个默认主机:git push -u origin master

 

  还有一种情况是,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时可以使用 -all 选项:git push -all origin

  

  如果远程主机的版本比本地版本的更新,推送时候Git会报错,要求先在本地做 git pull 合并差异,然后再推送到远程主机。如果执意要推送,可以使用 --force 选项:git push --force origin。这样做回导致远程主机上更新的版本被覆盖。除非非常确定要这样做,否则应该避免。

  最后,git push 不会推送标签tag,除非使用 --tags 选项:git push origin --tags

 

posted on 2017-04-06 16:00  凯少  阅读(348)  评论(0编辑  收藏  举报