19.2 分支追踪

为了能够在远程分支refs/remotes/origin/hello-1.x上进行工作,需要基于该远程分支创建本地分支。远程分支可以使用简写origin/hello-1.x。如果Git的版本是1.6.6或更新的版本,可以使用下面的命令同时完成分支的创建和切换。


$git checkout hello-1.x

Branch hello-1.x set up to track remote branch hello-1.x from origin.

Switched to a new branch 'hello-1.x'


如果Git的版本比较老,或注册了多个远程版本库,因此存在多个名为hello-1.x的远程分支,就不能使用上面简洁的分支创建和切换命令,而需要使用在上一章中学习到的分支创建命令,显式地从远程分支中创建本地分支。


$git checkout-b hello-1.x origin/hello-1.x

Branch hello-1.x set up to track remote branch hello-1.x from origin.

Switched to a new branch 'hello-1.x'


在上面基于远程分支创建本地分支的过程中,命令输出的第一行说的是建立了本地分支和远程分支的跟踪。和远程分支建立跟踪后,本地分支就具有下列特征:

检查工作区状态时,会显示本地分支和被跟踪远程分支提交之间的关系。

当执行git pull命令时,会和被跟踪的远程分支进行合并(或者变基),如果两者出现版本偏离的话。

当执行git push命令时,会推送到远程版本库的同名分支中。

下面就在基于远程分支创建的本地跟踪分支中进行操作,看看本地分支是如何与远程分支建立关联的,具体操作过程如下。

(1)先将本地hello-1.x分支向后重置两个版本。


$git reset—hard HEAD^^

HEAD is now at ebcf6d6 blank commit for GnuPG-signed tag test.


(2)然后查看状态,显示当前分支相比跟踪分支落后了3个版本。

之所以落后三个版本而非两个版本是因为hello-1.x的最新提交是一个合并提交,包含两个父提交,因此上面的重置命令丢弃掉了三个提交。


$git status

On branch hello-1.x

Your branch is behind'origin/hello-1.x'by 3 commits,and can be fast-

forwarded.

#

nothing to commit(working directory clean)


(3)执行git pull命令,会自动与跟踪的远程分支进行合并,相当于找回最新的3个提交。


$git pull

Updating ebcf6d6..8cffe5f

Fast-forward

src/main.c|11+++++++++—

1 files changed,9 insertions(+),2 deletions(-)


但是如果基于本地分支创建另外一个本地分支则没有分支跟踪的功能。下面就从本地的hello-1.x分支中创建hello-jx分支。

(1)从hello-1.x分支中创建新的本地分支hello-jx。

下面的创建分支操作只有一行输出,看不到分支间建立跟踪的提示。


$git checkout-b hello-jx hello-1.x

Switched to a new branch 'hello-jx'


(2)将hello-jx分支重置。


$git reset—hard HEAD^^

HEAD is now at ebcf6d6 blank commit for GnuPG-signed tag test.


(3)检查状态看不到分支间的跟踪信息。


$git status

On branch hello-jx

nothing to commit(working directory clean)


(4)执行git pull命令会报错。


$git pull

You asked me to pull without telling me which branch you

want to merge with,and 'branch.hello-jx.merge' in

your configuration file does not tell me,either.Please

specify which branch you want to use on the command line and

try again(e.g.'git pull<repository><refspec>').

See git-pull(1)for details.

If you often merge with the same branch,you may want to

use something like the following in your configuration file:

[branch "hello-jx"]

remote=<nickname>

merge=<remote-ref>

[remote"<nickname>"]

url=<url>

fetch=<refspec>

See git-config(1)for details.


将上面命令执行中的错误信息翻译过来,就是:


$git pull

您让我执行拉回操作,但是没有告诉我您希望与哪个远程分支进行合并,

而且也没有通过配置'branch.hello-jx.merge'来告诉我。

请在命令行中提供足够的参数,如'git pull<repository><refspec>'。

或者如果您经常与同一个分支进行合并,可以和该分支建立跟踪。在配置

中添加如下配置信息:

[branch "hello-jx"]

remote=<nickname>

merge=<remote-ref>

[remote "<nickname>"]

url=<url>

fetch=<refspec>


为什么用同样方法建立的分支hello-1.x和hello-jx,差距咋就那么大呢?奥秘就在于从远程分支创建本地分支,自动建立了分支间的跟踪,而从一个本地分支创建另外一个本地分支则没有。看看配置文件.git/config中是不是专门为分支hello-1.x创建了相应的配置信息?


9[branch "master"]

10 remote=origin

11 merge=refs/heads/master

12[branch "hello-1.x"]

13 remote=origin

14 merge=refs/heads/hello-1.x


其中第9~11行是针对master分支设置的分支间跟踪,是在版本库克隆的时候自动建立的。而第12~14行是前面基于远程分支创建本地分支时建立的。至于分支hello-jx则没有建立相关的配置。

如果希望在基于一个本地分支创建另外一个本地分支时也能够使用分支间的跟踪功能,就要在创建分支时提供—track参数。下面实践一下,具体操作过程如下。

(1)删除之前创建的hello-jx分支。


$git checkout master

Switched to branch 'master'

$git branch-d hello-jx

Deleted branch hello-jx(was ebcf6d6).


(2)使用参数—track重新基于hello-1.x创建hello-jx分支。


$git checkout—track-b hello-jx hello-1.x

Branch hello-jx set up to track local branch hello-1.x.

Switched to a new branch 'hello-jx'


(3)从Git库的配置文件中会看到为hello-jx分支设置的跟踪。

因为跟踪的是本版本库的本地分支,所以第16行设置的远程版本库的名字为一个点。


15 [branch "hello-jx"]

16 remote=.

17 merge=refs/heads/hello-1.x