三、远程仓库
1. 远程仓库简介
远程仓库是指托管在因特网或其他网络中的你的项目的版本库。
你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。
管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。
2. git remote
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 选项
使用指定选项 -v
会显示读写远程仓库时使用的仓库简写及其对应的 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 中了解关于它们的更多信息。
3. git remote add <shortname> <url>
运行 git remote add <shortname> <url>
关联一个新的远程 Git 仓库,同时指定一个方便使用的简写:
$ 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
访问到——你可以将它合并到自己的某个分支中, 或者如果你想要查看它的话,可以检出一个指向该点的本地分支。
我们将会在 Git 分支 中详细介绍什么是分支以及如何使用分支。
4. git fetch | pull <remote>
git fetch 或 git pull 是从远程仓库中拉取的命令。
- fetch
- 执行
git fetch <remote>
命令会访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。 - 注意
git fetch
命令只会将数据下载到你的本地仓库——它并不会自动合并或修改你当前的工作。 当准备好时你必须手动将其合并入你的工作。
- 执行
- pull
- 如果你的当前分支设置了跟踪远程分支(阅读下一节和 Git 分支 了解更多信息), 那么可以用
git pull
命令来自动抓取后合并该远程分支到当前分支。 这或许是个更加简单舒服的工作流程。
- 如果你的当前分支设置了跟踪远程分支(阅读下一节和 Git 分支 了解更多信息), 那么可以用
5. git push <remote> <branch>
git push <remote> <branch>
命令将你的本地内容推送到远端。
当你想要将 master
分支推送到 origin
服务器时, 那么运行这个命令就可以将你所做的备份到服务器:
$ git push origin master
只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。
当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先抓取他们的工作并将其合并进你的工作后才能推送。 阅读 Git 分支 了解如何推送到远程仓库服务器的详细信息。
-u 选项
当关联的远程库为空时,即第一次把当前本地分支推送到远程,需要使用-u
参数。
$ git push -u <remote> <branch>
-f 选项
-f
选项可以强制推送本地当前分支,使得远端即使有冲突也被覆盖。显然这是一个危险的命令。
6. git remote show <remote>
如果想要查看某一个远程仓库的更多信息,可以使用 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
分支合并到本地 master
分支。 它也会列出拉取到的所有远程引用。
git remote show
如果你是 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
时哪些本地分支可以与它跟踪的远程分支自动合并。
7. git remote rename
git remote rename
可以修改一个远程仓库的简写名。 例如,想要将 pb
重命名为 paul
,可以用 git remote rename
这样做:
$ git remote rename pb paul
$ git remote
origin
paul
值得注意的是这同样也会修改你所有远程跟踪的分支名字。 那些过去引用 pb/master
的现在会引用 paul/master
。
那这样的话,如果远程分支名不叫
paul
,是不是和远程就关联不上了?
8. git remote remove | rm
如果因为一些原因想要移除一个远程仓库——你已经从服务器上搬走了或不再想使用某一个特定的镜像了, 又或者某一个贡献者不再贡献了——可以使用 git remote remove
或 git remote rm
:
$ git remote remove paul
$ git remote
origin
一旦你使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。
9. 本地仓库关联多个远程仓库
方法 1:git remote add <shortname> <url>
即使用第 3 节的git remote add <shortname> <url>
命令添加新的远程仓库,因此过程不再贅述。
但这个命令会导致以后每次 push、pull 时需要显示指定目标仓库,即需输入git push <remote> <branch>
、git pull <remote> <branch>
。
方法 2:git remote set-url --add <shotname> <url>
在许多情况下,我们只需要保持远程仓库的完全一致,而不需要对其进行区分,因而方法 1 可能显得有得囉嗦。
方法 2 的实质是:不额外添加远程仓库,而是给现有的远程仓库添加额外的 URL。使用git remote set-url --add <shortname> <url>
,给已有的名为shortname
的远程仓库添加一个远程地址即可,比如:
$ git remote set-url --add origin https://github.com/paulboone/ticgit
再次查看所关联的远程仓库:
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
origin https://github.com/paulboone/ticgit (push)
可以看到,我们并没有如方法 1 一般增加远程仓库的数目,而是给一个远程仓库赋予了多个地址,或者更准确地说,赋予了多个用于push
的地址。
因此,这样设置后的push
和pull
操作与只有一个远程仓库的操作完全一致,不需要进行调整。