/ul>

10. git的远程仓库操作命令有哪些?

作者:jicanmeng

时间:2014年08月29日


Git的远程操作命令大概有这么几个:

  1. git clone
  2. git remote
  3. git push
  4. git fetch
  5. git pull

1. git clone

git clone命令用于把远程版本库(remote repository)克隆一份到本地,克隆的这一份版本库就称为本地版本库(local repository)。比如,要克隆Ruby语言的Git代码仓库Grit,可以用下面的命令:

[jicanmeng@andy tmp]$ git clone git://github.com/schacon/grit.git
                Cloning into 'grit'...
                remote: Counting objects: 4051, done.
                remote: Compressing objects: 100% (2824/2824), done.
                remote: Total 4051 (delta 1170), reused 4051 (delta 1170)Receiving objects:  99%
                (4029/4051), 2.10 MiB |
                Receiving objects: 100% (4051/4051), 2.10 MiB | 17 KiB/s, done.
                Resolving deltas: 100% (1170/1170), done.
                Checking out files: 100% (1384/1384), done.

这条命令会在当前目录下创建一个名为grit的目录,其中包含一个.git的目录,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝,放到工作区。如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:

[jicanmeng@andy tmp]$ git clone git://github.com/schacon/grit.git mygrit

唯一的差别就是,现在新建的目录成了 mygrit,其他的都和上边的一样。

2. git remote

为了便于管理,Git要求每个远程版本库都必须指定一个名称。git remote命令就用于查看和配置远程版本库的名称。

git remote命令列出所有的远程版本库的名称;
git remote -v命令会列出远程版本库的名称和对应的URL;
git remote show命令用于列出远程版本库的详细信息。

[jicanmeng@andy tmp]$ git remote
                origin
                [jicanmeng@andy tmp]$ git remote -v
                origin  git://github.com/schacon/grit.git (fetch)
                origin  git://github.com/schacon/grit.git (push)
                [jicanmeng@andy tmp]$ git remote show origin
                * remote origin
                  Fetch URL: git://github.com/schacon/grit.git
                  Push  URL: git://github.com/schacon/grit.git
                  HEAD branch: master
                  Remote branches:
                    gh-pages    tracked
                    integration tracked
                    master      tracked
                  Local branch configured for 'git pull':
                    master merges with remote master
                  Local ref configured for 'git push':
                    master pushes to master (up to date)

我们在使用git clone命令克隆版本库的时候,所使用的远程版本库默认情况下会被Git命名为origin。如果想用其他的名称,需要用git clone命令的-o选项指定。

[jicanmeng@andy tmp]$ git clone -o gritProject git://github.com/schacon/grit.git
                [jicanmeng@andy tmp]$ git remote
                gritProject
                [jicanmeng@andy tmp]$
  1. git remote add NameOne git://github.com/schacon/grit.git命令用于添加一个URL为git://github.com/schacon/grit.git的远程版本库,名称为NameOne。
  2. git remote rm NameOne命令用于删除名称为NameOne的远程版本库。
  3. git remote rename NameOne NameTwo用于将名称为NaneOne的远程版本库的名称修改为NameTwo。

git remote命令所进行的操作实际上是对.git/config文件进行读和写。我们可以看一看.git/config文件的内容:

[jicanmeng@andy grit]$ cat .git/config
                [core]
                      repositoryformatversion = 0
                      filemode = false
                      bare = false
                      logallrefupdates = true
                      symlinks = false
                      ignorecase = true
                      hideDotFiles = dotGitOnly
                [remote "origin"]
                      url = git://github.com/schacon/grit.git
                      fetch = +refs/heads/*:refs/remotes/origin/*
                [branch "master"]
                      remote = origin
                      merge = refs/heads/master
                [jicanmeng@andy grit]$ git config remote.origin.url
                git://github.com/schacon/grit.git
                [jicanmeng@andy grit]$ git config branch.master.remote
                origin
                [jicanmeng@andy grit]$ 

可以看到,当前的配置文件中保存了一个远程版本库的名称:origin。我们使用git config命令可以查看名称为origin的远程版本库的URL。如果使用git remote add命令,就会增加一个remote小节。如果使用git remote rm命令,就会删除对应的remote小节。

3. git push

git push命令用于将本地版本库的更新,推送到远程版本库。这条命令的格式如下:

[jicanmeng@andy grit]$ git push [<远程版本库名称> [<本地分支名称>:<远程分支名称>]]

"[]"表示可选,即我们可以执行git push,可以执行git push <远程版本库>,可以执行git push <远程版本库名称> <本地分支名称>:<本地分支名称>,但不能执行git push <本地分支名称:远程分支名称>.

如果省略了远程版本库名称,分两种情况:1. 如果为当前分支设置了<remote>,即在.git/config文件中由branch.<branch>.remote给出了远程版本库的名称,那么不带参数执行git push就相当于执行了git push <remote>; 2. 如果没有为当前分支设置<remote>,那么不带参数执行git push就相当于执行git push origin。要推送的远程版本库的URL地址由remote.<remote>.pushurl给出,如果没有这一项配置,那么就使用remote.<remote>.url给出的地址;

如果命令中包含了远程版本库名称,分下面三种情况:

1. 如果省略了本地分支名和远程分支名,分两种情况:1. 如果为注册的远程版本库设置了push参数,即通过remote.<remote>.push配置了一个引用表达式,那么使用该引用表达式进行推送。2. 如果没有设置push参数,那么就使用":"作为引用表达式。该表达式的含义是同名分支推送,即对所有在远程版本库中有同名分支的本地分支执行推送。

2. 如果只省略远程分支名,则表示将本地分支推送到同名的远程分支,如果该远程分支不存在,则会被新建。例如:git push origin master命令表示,将本地的master分支推送到名称为origin远程版本库的master分支。如果后者不存在,则会被新建。

3. 如果只省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。例如:git push origin :master命令等同于git push origin --delete master这条命令,表示删除名称为origin的远程版本库的master分支。

4. git fetch

[jicanmeng@andy grit]$ git fetch [<远程版本库名称> [<远程分支名称>:<本地跟踪分支>]]

"[]"表示可选,即我们可以执行git fetch,也可以执行git fetch <远程版本库名称>,也可以执行git fetch <远程版本库名称> <远程分支名>,但不能执行git fetch <远程分支名称>.

如果省略了远程版本库名称,分两种情况:1. 如果为当前分支设置了<remote>,即在.git/config文件中由branch.<branch>.remote给出了远程版本库的名称,那么不带参数执行git fetch就相当于执行了git fetch <remote>; 2. 如果没有为当前分支设置<remote>,那么不带参数执行git fetch就相当于执行git fetch origin。远程版本库的URL地址由remote.<remote>.url给出。

如果命令中包含了远程版本库名称,分下面两种情况:

1. 如果省略了远程分支名和本地跟踪分支名,分两种情况:1. 如果为注册的远程版本库设置了fetch参数,即通过remote.<remote>.fetch配置了一个引用表达式,则使用该引用表达式执行获取操作;2. 如果没有配置fetch参数,那么git fetch取回所有分支(branch)的更新。

2. 如果指定远程分支名,那么应该同时指定本地跟踪分支名,此时只取回这个远程分支的更新。

$ git fetch origin master:refs/remote/origin/master
                remote: Counting objects: 4, done.
                remote: Compressing objects: 100% (2/2), done.
                remote: Total 3 (delta 1), reused 0 (delta 0)
                Unpacking objects: 100% (3/3), done.
                From C:/Program Files/Git/path/to/repos/user5
                 * [new branch]      master     -> origin/master
                $ 

可以使用三幅图来形象地说明一下git fetch命令的作用:

git fetch 1

1. 我的本地版本库和远程版本库保持一致,有两个分支:master和branch01。两个本地跟踪分支分别是refs/remotes/origin/master和refs/remote/origin/branch01。

git fetch 2

2. 有其他人往远程版本库上面进行了新的提交,其中master提交两次,branch01分支提交一次。同时我的本地版本库上面master分支上面有一次新的提交。

git fetch 3

3. 执行git fetch命令后,从远程版本库获取了master分支的两次commit和branch01分支的一次commit。然后两个本地跟踪分支分别指向对应的最新的commit。至于本地分支master和branch01的指向都不改变。

从图中可以看出,git fetch命令只有两个作用:1. 将远程版本库的最新的commit获取到本地版本库;2. 将本地跟踪分支的指向进行修改。

5. git pull

[jicanmeng@andy grit]$ git pull [<远程版本库名称> [<远程分支名称>:<本地分支>]]

实际上拉回操作(git pull)是由两个步骤组成的:一个是获取操作(git fetch),另一个是合并操作(git merge),即
git pull = git fetch + git merge

前面已经详细描述了git fetch命令,这里只需要再理解git merge命令的意思就行了。接着上面的图,如果我们在master分支上面执行git merge origin/master命令,那么结果如下图:

git merge 1

由上图可以看出,在master分支下执行git merge origin/master,会将master分支指向的提交和origin/master指向的提交进行合并,生成一个新的提交。

工作中常遇到的一个问题是:git push命令不能执行成功,执行git pull也会提示冲突。所以一定要学会这两条命令的用法。

参考资料

  1. Pro Git
  2. git权威指南
  3. Learn Git Branching
  4. 阮一峰的网络日志:Git远程操作详解