-
1. 开始
-
2. Git 基础
-
3. Git 分支
-
4. Git 服务器
- 4.1 协议
- 4.2 在服务器上安装 Git
- 4.3 生成 SSH 公钥
- 4.4 设置服务器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管选项
- 4.10 总结
-
5. 分布式 Git
-
A1. 附录 A:其他环境中的 Git
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 总结
-
A2. 附录 B:在您的应用程序中嵌入 Git
-
A3. 附录 C:Git 命令
3.5 Git 分支 - 远程分支
远程分支
远程引用是指远程仓库中的引用(指针),包括分支、标签等等。 你可以使用git ls-remote <remote>
显式地获取完整的远程引用列表,或者使用git remote show <remote>
获取远程分支以及更多信息。 不过,更常用的方法是利用远程跟踪分支。
远程跟踪分支是远程分支状态的引用。 它们是你无法移动的本地引用; 每当你进行任何网络通信时,Git 都会为你移动它们,以确保它们准确地代表远程仓库的状态。 可以将它们视为书签,提醒你上次连接到远程仓库时,远程仓库中的分支在哪里。
远程跟踪分支名称采用<remote>/<branch>
的形式。 例如,如果你想查看上次与 `origin` 远程仓库通信时,`master` 分支是什么样的,你可以查看 `origin/master` 分支。 如果你与合作伙伴合作处理一个问题并推送了一个 `iss53` 分支,你可能拥有自己的本地 `iss53` 分支,但服务器上的分支将由远程跟踪分支 `origin/iss53` 表示。
这可能有点令人困惑,所以让我们看一个例子。 假设你的网络中有一台 Git 服务器,地址为 `git.ourcompany.com`。 如果你从中克隆,Git 的 `clone` 命令会自动将其命名为 `origin`,拉取其所有数据,创建一个指向其 `master` 分支位置的指针,并在本地将其命名为 `origin/master`。 Git 还为你提供你自己的本地 `master` 分支,它从与 origin 的 `master` 分支相同的位置开始,因此你可以从那里开始工作。
注意
|
“origin” 并非特殊
就像分支名称“master”在 Git 中没有任何特殊含义一样,“origin”也没有。 当你运行 `git init` 时,“master”是起始分支的默认名称,这是它被广泛使用的唯一原因,而当你运行 `git clone` 时,“origin”是远程仓库的默认名称。 如果你运行 `git clone -o booyah`,那么你将拥有 `booyah/master` 作为你的默认远程分支。 |

如果你在本地 `master` 分支上做了一些工作,与此同时,其他人推送到 `git.ourcompany.com` 并更新了它的 `master` 分支,那么你的历史记录就会以不同的方式前进。 此外,只要你与 `origin` 服务器保持联系,你的 `origin/master` 指针就不会移动。

要将你的工作与给定的远程仓库同步,你需要运行一个 `git fetch <remote>` 命令(在我们的例子中,是 `git fetch origin`)。 这个命令会查找 “origin” 对应的服务器(在本例中,是 `git.ourcompany.com`),从中获取你还没有的任何数据,并更新你的本地数据库,将你的 `origin/master` 指针移动到其新的、更及时的位置。

git fetch
更新你的远程跟踪分支为了演示拥有多个远程服务器,以及这些远程项目的远程分支是什么样的,假设你还有另一个内部 Git 服务器,仅供一个 sprint 团队用于开发。此服务器位于 git.team1.ourcompany.com
。你可以通过运行 git remote add
命令,将其作为新的远程引用添加到你当前正在处理的项目中,正如我们在 Git 基础 中所介绍的那样。 将此远程服务器命名为 teamone
,这将是该完整 URL 的简称。

现在,你可以运行 git fetch teamone
来抓取远程 teamone
服务器上你尚未拥有的所有内容。 由于该服务器拥有你当前 origin
服务器上数据的子集,因此 Git 不会抓取任何数据,但会将名为 teamone/master
的远程跟踪分支设置为指向 teamone
的 master
分支所在的提交。

teamone/master
的远程跟踪分支推送
当你想要与世界分享一个分支时,你需要将其推送到你有写入权限的远程仓库。 你的本地分支不会自动同步到你写入的远程仓库 — 你必须显式推送你想要共享的分支。 这样,你可以使用私有分支进行你不想共享的工作,并且只推送你想要协作的主题分支。
如果你有一个名为 serverfix
的分支,你想与其他人一起处理,你可以像推送你的第一个分支一样推送它。运行 git push <remote> <branch>
$ git push origin serverfix
Counting objects: 24, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
Total 24 (delta 2), reused 0 (delta 0)
To https://github.com/schacon/simplegit
* [new branch] serverfix -> serverfix
这是一个小技巧。 Git 会自动将 serverfix
分支名展开为 refs/heads/serverfix:refs/heads/serverfix
,这意味着“获取我的 serverfix
本地分支并推送它以更新远程的 serverfix
分支。”我们将在 Git 内部原理 中详细介绍 refs/heads/
部分,但通常你可以省略它。你也可以执行 git push origin serverfix:serverfix
,这会执行相同的操作 — 它说:“获取我的 serverfix 并将其设置为远程的 serverfix。”你可以使用此格式将本地分支推送到名称不同的远程分支中。 如果你不想在远程仓库上将其命名为 serverfix
,你可以改为运行 git push origin serverfix:awesomebranch
,将你的本地 serverfix
分支推送到远程项目的 awesomebranch
分支。
注意
|
不要每次都输入密码
如果你使用 HTTPS URL 进行推送,Git 服务器会要求你提供用户名和密码进行身份验证。默认情况下,它会在终端上提示你输入此信息,以便服务器可以判断你是否被允许推送。 如果你不想每次推送都输入密码,你可以设置“凭据缓存”。最简单的方法就是将其保存在内存中几分钟,你可以通过运行 有关各种可用凭据缓存选项的更多信息,请参阅 凭据存储。 |
下次你的协作者从服务器抓取时,他们将获得对服务器版本的 serverfix
的引用,该引用位于远程分支 origin/serverfix
下。
$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/schacon/simplegit
* [new branch] serverfix -> origin/serverfix
重要的是要注意,当你执行抓取操作并获取新的远程跟踪分支时,你不会自动拥有它们的本地可编辑副本。 换句话说,在这种情况下,你没有新的 serverfix
分支 — 你只有不能修改的 origin/serverfix
指针。
要将此工作合并到你当前的工作分支中,你可以运行 git merge origin/serverfix
。 如果你想要自己的 serverfix
分支,你可以在其上工作,你可以基于你的远程跟踪分支
$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
这为你提供了一个可以工作的本地分支,该分支从 origin/serverfix
开始。
跟踪分支
从远程跟踪分支检出一个本地分支会自动创建一个所谓的“跟踪分支”(它跟踪的分支称为“上游分支”)。跟踪分支是与远程分支具有直接关系的本地分支。 如果你位于跟踪分支上并键入 git pull
,Git 会自动知道从哪个服务器抓取以及合并哪个分支。
当你克隆一个存储库时,它通常会自动创建一个 master
分支,该分支跟踪 origin/master
。 但是,如果你愿意,你可以设置其他跟踪分支 — 跟踪其他远程仓库上的分支,或者不跟踪 master
分支。 简单的例子是你刚刚看到的,运行 git checkout -b <branch> <remote>/<branch>
。 这是一个足够常见的操作,Git 提供了 --track
简写
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
事实上,这是如此常见,以至于甚至有一个用于该简写的快捷方式。 如果你尝试检出的分支名称 (a) 不存在,并且 (b) 仅与一个远程仓库上的名称完全匹配,Git 将为你创建一个跟踪分支
$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
要使用与远程分支不同的名称设置本地分支,你可以轻松地使用第一个版本,使用不同的本地分支名称
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'
现在,你的本地分支 sf
将自动从 origin/serverfix
拉取。
如果你已经有一个本地分支,并且想要将其设置为你刚刚拉取的远程分支,或者想要更改你正在跟踪的上游分支,你可以使用 -u
或 --set-upstream-to
选项来 git branch
,以便随时显式设置它。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
注意
|
上游简写
当你设置了跟踪分支时,你可以使用 |
如果你想查看你设置了哪些跟踪分支,你可以使用 -vv
选项来 git branch
。 这将列出你的本地分支,并提供更多信息,包括每个分支正在跟踪的内容,以及你的本地分支是提前、落后还是两者兼而有之。
$ git branch -vv
iss53 7e424c3 [origin/iss53: ahead 2] Add forgotten brackets
master 1ae2a45 [origin/master] Deploy index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] This should do it
testing 5ea463a Try something new
因此,在这里我们可以看到我们的 iss53
分支正在跟踪 origin/iss53
,并且“提前”了两个,这意味着我们本地有两个尚未推送到服务器的提交。 我们还可以看到我们的 master
分支正在跟踪 origin/master
并且是最新的。 接下来,我们可以看到我们的 serverfix
分支正在跟踪我们 teamone
服务器上的 server-fix-good
分支,并且提前了三个并且落后了一个,这意味着服务器上有一个我们尚未合并的提交,并且本地有三个我们尚未推送的提交。 最后,我们可以看到我们的 testing
分支未跟踪任何远程分支。
重要的是要注意,这些数字仅自你上次从每个服务器抓取以来的时间。 此命令不会访问服务器,它会告诉你它从这些服务器在本地缓存的内容。 如果你想要完全最新的提前和落后数字,你需要先从所有远程仓库抓取,然后再运行此命令。 你可以像这样做到这一点
$ git fetch --all; git branch -vv
拉取
虽然 git fetch
命令会抓取你尚未拥有的服务器上的所有更改,但它根本不会修改你的工作目录。 它只会为你获取数据并让你自己合并它。 但是,有一个名为 git pull
的命令,它本质上是 git fetch
,然后在大多数情况下立即执行 git merge
。 如果你按照上一节中演示的方式设置了跟踪分支,无论是通过显式设置它还是通过 clone
或 checkout
命令为你创建它,git pull
都会查找你的当前分支正在跟踪哪个服务器和分支,从该服务器抓取,然后尝试合并该远程分支。
删除远程分支
假设你已完成远程分支 — 比如说你和你的协作者已经完成了一个功能,并将其合并到远程仓库的 master
分支中(或你的稳定代码库所在的任何分支)。 你可以使用 git push
的 --delete
选项删除远程分支。 如果你想从服务器中删除你的 serverfix
分支,你可以运行以下命令
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
- [deleted] serverfix
基本上,这所做的只是从服务器中删除指针。 Git 服务器通常会将数据保留在那里一段时间,直到垃圾回收运行,因此如果意外删除,通常很容易恢复。