章节 ▾ 第二版

2.5 Git基础 - 使用远程仓库

使用远程仓库

为了能够协作开发任何 Git 项目,您需要了解如何管理您的远程仓库。远程仓库是您项目托管在互联网或网络上的版本。您可以拥有多个远程仓库,每个仓库通常对您来说要么是只读的,要么是读写兼备的。与他人协作涉及到管理这些远程仓库,并在需要共享工作时将数据推送到这些仓库或从中拉取数据。管理远程仓库包括如何添加远程仓库、删除不再有效的远程仓库、管理各种远程分支并将它们定义为跟踪或非跟踪状态,等等。在本节中,我们将介绍其中一些远程管理技巧。

注意
远程仓库可以位于您的本地机器上。

完全有可能您正在处理一个“远程”仓库,但实际上它就在您所在的同一台主机上。“远程”一词不一定意味着仓库位于网络的另一端或互联网上,只表示它在别处。处理这样一个远程仓库仍然会涉及与任何其他远程仓库一样的标准推送、拉取和获取操作。

显示您的远程仓库

要查看您配置了哪些远程服务器,您可以运行 git remote 命令。它会列出您指定的每个远程句柄的短名称。如果您克隆了您的仓库,至少应该会看到 origin — 这是 Git 默认给您克隆来源服务器起的名称。

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

您还可以指定 -v,它会显示 Git 为短名称存储的用于读写该远程仓库的 URL。

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

如果您有多个远程仓库,该命令会列出所有。例如,一个与多个协作者协作的仓库可能看起来像这样。

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

这意味着我们可以很方便地拉取任何一位用户的贡献。我们可能还有权限推送到其中一个或多个仓库,尽管这里无法得知。

请注意,这些远程仓库使用了各种协议;我们将在 在服务器上获取 Git 中更详细地介绍。

添加远程仓库

我们已经提到并演示了 git clone 命令如何为您隐式地添加 origin 远程仓库。以下是如何显式添加新远程仓库的方法。要添加一个新的远程 Git 仓库并为其指定一个易于引用的短名称,请运行 git remote add <shortname> <url>

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

现在您可以在命令行中使用字符串 pb 而不是整个 URL。例如,如果您想获取 Paul 所拥有的、但您仓库中还没有的所有信息,您可以运行 git fetch pb

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

Paul 的 master 分支现在可以在本地通过 pb/master 访问 — 您可以将其合并到您的一个分支中,或者如果您想检查它,可以 checkout 到该点的一个本地分支。我们将在 Git 分支 中更详细地介绍分支是什么以及如何使用它们。

从远程仓库获取和拉取

正如您刚才看到的,要从您的远程项目获取数据,您可以运行:

$ git fetch <remote>

该命令会连接到远程项目,并将您还没有的该远程项目的所有数据拉取下来。完成此操作后,您应该会有对该远程所有分支的引用,您可以随时合并或检查它们。

如果您克隆了一个仓库,该命令会自动将该远程仓库添加为名为“origin”的远程。因此,git fetch origin 会获取自您克隆(或上次获取)以来推送到该服务器的任何新工作。需要注意的是,git fetch 命令只将数据下载到您的本地仓库 — 它不会自动与您的任何工作合并,也不会修改您当前正在进行的工作。准备好后,您需要手动将其合并到您的工作中。

如果您的当前分支设置为跟踪远程分支(有关更多信息,请参阅下一节和 Git 分支),您可以使用 git pull 命令自动获取然后将该远程分支合并到您的当前分支。这可能对您来说是一种更简单或更方便的工作流程;默认情况下,git clone 命令会自动设置您的本地 master 分支以跟踪您克隆来源服务器上的远程 master 分支(或任何默认分支名)。运行 git pull 通常会从您最初克隆的服务器获取数据,并尝试将其自动合并到您当前正在处理的代码中。

注意

从 Git 版本 2.27 开始,如果 pull.rebase 变量未设置,git pull 将会发出警告。Git 将会一直警告您,直到您设置该变量。

如果您想要 Git 的默认行为(如果可能则快进,否则创建合并提交):git config --global pull.rebase "false"

如果您想在拉取时进行 rebase:git config --global pull.rebase "true"

推送到您的远程仓库

当您的项目达到可以共享的点时,您需要将其推送到上游。用于此目的的命令很简单:git push <remote> <branch>。如果您想将您的 master 分支推送到您的 origin 服务器(再次强调,克隆通常会自动为您设置这两个名称),那么您可以运行此命令将您已完成的任何提交推送到服务器。

$ git push origin master

此命令仅在您从您具有写入权限的服务器克隆,并且在此期间没有人推送时才有效。如果您和另一个人同时克隆,他们先推送到上游,然后您再推送到上游,您的推送将被正确拒绝。您需要先获取他们的工作并将其合并到您的工作之后,才允许您推送。有关如何推送到远程服务器的详细信息,请参阅 Git 分支

检查远程仓库

如果您想查看特定远程仓库的更多信息,可以使用 git remote show <remote> 命令。如果您使用特定的短名称(例如 origin)运行此命令,您会看到类似这样的输出:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           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)

它列出了远程仓库的 URL 以及跟踪分支信息。该命令还会很有用地告诉您,如果您当前在 master 分支上并运行 git pull,它将在获取远程的 master 分支后自动将其合并到本地分支。它还会列出它已拉取的所有远程引用。

这是一个您很可能会遇到的简单示例。然而,当您更深入地使用 Git 时,您可能会从 git remote show 中看到更多信息。

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

此命令显示当您在特定分支上运行 git push 时会自动推送到哪个分支。它还显示您在服务器上尚未拥有的远程分支,您拥有但已从服务器删除的远程分支,以及当您运行 git pull 时可以自动与远程跟踪分支合并的多个本地分支。

重命名和删除远程仓库

您可以通过运行 git remote rename 来更改远程仓库的短名称。例如,如果您想将 pb 重命名为 paul,您可以使用 git remote rename 来完成。

$ git remote rename pb paul
$ git remote
origin
paul

值得一提的是,这也会更改您所有的远程跟踪分支名称。以前以 pb/master 引用的内容,现在以 paul/master 引用。

如果您因为某种原因想删除一个远程仓库 — 比如服务器已移动、不再使用某个镜像,或者某个贡献者不再贡献 — 您可以使用 git remote removegit remote rm

$ git remote remove paul
$ git remote
origin

一旦您以这种方式删除了对远程仓库的引用,所有与该远程仓库相关的远程跟踪分支和配置设置也会被删除。