查看远程数据
在我们新建了与某个远程仓库的连接之后,它到底改变了什么?现在让我们来看看分支列表:
$ git branch -va
contact-form 56eddd1 Add new contact form page
* master 56eddd1 Add new contact form page
remotes/origin/HEAD -> origin/master
remotes/origin/master 2b504be Change headlines for about and imprint
显然并没有太大的变化,始终是我们那两个本地分支(“master” 和 “contact-form”)以及两个在 “origin” 上的远程分支(“remotes/origin/HEAD” 和 “remotes/origin/master”)。为什么我们没有看到那个新的远程链接 “crash-course-remote” 呢?因为通过命令 “git remote add”,我们仅仅建立了一种关系,还没有进行任何数据交换。
概念
远程数据是一个快照(Snapshot)
Git 会在你的本地仓库中保存远程数据的信息(例如分支,提交等等)。但是它并不是 “实时地” 连接到你的远程仓库上的。例如,其他团队成员在这个远程仓库中所提交的新改动或是发布的分支,是不能自动地与你分享的,因为你必须明确地告诉 Git 去升级你的本地仓库!
关于远程的分支,远程的提交等等信息只会按照你的要求更新到最新的一个快照。Git 不会在后台 “自动” 升级这些信息。
要更新有关远程的信息,你必须明确地请求这个数据。在这里可以使用最为常用的,“抓取(Fetch)” 操作来完成:
$ git fetch crash-course-remote
From https://github.com/gittower/git-crash-course-remote
* [new branch] faq-content -> crash-course-remote/faq-content
* [new branch] master -> crash-course-remote/master
“抓取” 操作不会改动你任何的本地分支或是在你工作副本中的文件。这个操作仅仅为你从一个特定远程仓库下载你所需要的数据,并设置为可见。你可以在之后决定是否需要整合这些新的改动本地项目中来。
在我们完成了关于 “crash-course-remote” 升级后,让我们一起来看一下现在发生了什么变化:
$ git branch -va
contact-form 56eddd1 Add new contact form page
* master 56eddd1 Add new contact form page
remotes/crash-course-remote/faq-content e29fb3f Add FAQ questions
remotes/crash-course-remote/master 2b504be Change headlines f...
remotes/origin/HEAD -> origin/master
remotes/origin/master 2b504be Change headlines for about and imprint
很好,我们看到了这个远程分支的 “crash-course-remote” 的信息了。
现在准备开始在分支 “faq-content” 上工作吧!但是现在它只是一个远程分支的指针。为了能够真正地在这个分支上工作,并且切换当前工作副本(working copy)的内容,我们需要创建一个基于这个远程的本地分支。执行 “git checkout” 命令来切换到这个远程分支:
$ git checkout --track crash-course-remote/faq-content
Branch faq-content set up to track remote branch faq-content from crash-course-remote.
Switched to a new branch 'faq-content'
$ git branch -va
contact-form 56eddd1 Add new contact form page
* faq-content e29fb3f Add FAQ questions
master 56eddd1 Add new contact form page
remotes/crash-course-remote/faq-content e29fb3f Add FAQ questions
remotes/crash-course-remote/master 2b504be Change headlines f...
remotes/origin/HEAD -> origin/master
remotes/origin/master 2b504be Change headlines for about and imprint
这个命令完成了一系列的操作:
- (a) 它创建了一个同名的本地分支(“faq-content”)。
- (b) 它签出(check out)了这个新建的的分支,把它设置成当前的本地 HEAD ,然后更新了你的工作副本,并且关联到分支文件的最新版本上去。
- (c) 由于我们使用了 “--track” 参数,它会在新的本地分支和它所位于的远程分支之间创建一个跟踪联系 “tracking relationship”。
跟踪分支
一般来说,分支之间并无任何关系。然而我们可以定义一个本地分支去 “跟踪 (track)” 一个远程分支。这样 Git 就会通知你,如果那个被跟踪的远程分支发生了一些新的提交,而它们并不存在于这个关联的本地分支中时:
- 如果在你的本地分支上提交了一些改动,而且你也并没有发布它和推送到远程仓库中。相对于这些提交来说你的本地分支就 “领先(ahead)” 于那些它所对应的远程分支。
- 如果团队的其他开发人员提交并且发布了一些改动到远程仓库中,这时远程仓库就拥有了那些你还没有下载到本地仓库的提交。你的本地仓库就 “落后(behind)” 于它所关联的远程仓库。
如果分支间存在 “跟踪” 联系,当你使用 “git status” 命令时,Git 显示出所有关联分支上的差异:
$ git status
# On branch dev
# Your branch and 'origin/dev' have diverged,
# and have 1 and 2 different commits each, respectively.
#
nothing to commit (working directory clean)
当在一个已存在的远程分支的基础上来建立本地分支时,创建这个 “跟踪” 联系是很简单的,可以使用 “git checkout” 命令加 “--track” 参数来完成。
在切换到那个新创建的本地分支 “faq-content” 后, 我们已经自动拥有了这个 “跟踪” 联系。来让我们对这个工作副本中的文件 “faq.html” 进行一些修改吧!(如何更改这个文件就不详细介绍了,发挥你的想象力吧):
$ git status
# On branch faq-content
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working
# directory)
#
# modified: faq.html
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git add faq.html
$ git commit -m "Add new question"
[faq-content 814927a] Add new question
1 file changed, 1 insertion(+)
现在,是时候把这些新的改动共享给其他开发人员了:
$ git push
注释
在你的本地计算机上,这个 “git push” 命令将会被远程仓库拒绝掉,因为你现在还没有获得这个远程仓库的修改权限。如果你想要继续的尝试这个操作,我建议你建立一个自己的远程仓库,例如:GitHub 或者 Beanstalk。
“git push” 命令将会把当前 HEAD 分支上所有新的提交上传到它所关联的远程分支上去。
概念
回顾 “跟踪” 联系
“git push” 命令默认地要求我们为它提供两个信息:
- (a) 你想要推送到哪一个远程仓库上去?
- (b) 你想要推送到那个远程仓库上的哪一个分支上去?
这个完整的命令应该是这样的: $ git push crash-course-remote faq-content
我们已经设置了 “跟踪” 联系,也就是说我们已经为那个本地分支定义了一个 “ 远程对应的(remote counterpart)” 分支。在我们使用 “git push” and “git pull” 命令时,我们不需要特别地给出那些参数, Git 会自动地使用这些已经定义好的 “跟踪” 信息。