18.5.5 发布分支的提交合并到主线

当开发者user1和user2都相继在hello-1.x分支中将相应的Bug修改完后,就可以从hello-1.x分支中编译新的软件产品交给客户使用了。接下来别忘了在主线master分支中也做出同样的更改,因为在hello-1.x分支中修改的Bug同样也存在于主线master分支中。

1.拣选操作

使用Git提供的拣选命令,就可以直接将发布分支上进行的Bug修正合并到主线上。下面就以开发者user2的身份进行操作,具体操作过程如下。

(1)进入user2工作区并切换到master分支。


$cd/path/to/user2/workspace/hello-world/

$git checkout master


(2)从远程共享版本库同步master分支。

同步后本地master分支包含了开发者user1提交的命令行参数解析重构的代码。


$git pull

remote:Counting objects:7,done.

remote:Compressing objects:100%(4/4),done.

remote:Total 4(delta 3),reused 0(delta 0)

Unpacking objects:100%(4/4),done.

From file:///path/to/repos/hello-world

ebcf6d6..0881ca3 master->origin/master

Updating ebcf6d6..0881ca3

Fast-forward

src/main.c|41++++++++++++++++++++++++++++++++++++——-

1 files changed,36 insertions(+),5 deletions(-)


(3)查看分支hello-1.x的日志,确认要拣选的提交ID。

从下面的日志中可以看出分支hello-1.x的最新提交是一个合并提交,而要拣选的提交分别是其第一个父提交和第二个父提交,可以分别用"hello-1.x^1"和"hello-1.x^2"表示。


$git log-3—graph—oneline hello-1.x

*8cffe5f Merge branch 'hello-1.x' of file:///path/to/repos/hello-world into

hello-1.x

|\

|*b56bb51 Fix typo:-help to—help.

*|e64f3a2 Bugfix:allow spaces in username.

|/


(4)执行拣选操作。先将开发者user2提交的修正代码拣选到当前分支(即主线)。

拣选操作遇到了冲突,见下面的命令输出。


$git cherry-pick hello-1.x^1

Automatic cherry-pick failed.After resolving the conflicts,

mark the corrected paths with 'git add<paths>' or 'git rm<paths>'

and commit the result with:

git commit-c e64f3a216d346669b85807ffcfb23a21f9c5c187


(5)拣选操作发生冲突,通过查看状态可以看到是在文件src/main.c上发生了冲突。


$git status

On branch master

Unmerged paths:

(use "git reset HEAD<file>…" to unstage)

(use "git add/rm<file>…" as appropriate to mark resolution)

#

both modified:src/main.c

#

no changes added to commit(use "git add" and/or "git commit-a")


2.冲突发生的原因

为什么发生了冲突呢?这是因为拣选hello-1.x分支上的一个提交到master分支时,因为两个甚至多个提交在重叠的位置更改代码所致。通过下面的命令可以看到到底是哪些提交引起的冲突。


$git log master…hello-1.x^1

commit e64f3a216d346669b85807ffcfb23a21f9c5c187

Author:user2<user2@moon.ossxp.com>

Date:Sun Jan 9 13:11:19 2011+0800

Bugfix:allow spaces in username.

commit 0881ca3f62ddadcddec08bd9f2f529a44d17cfbf Author:user1<user1@sun.ossxp.com>

Date:Mon Jan 3 22:44:52 2011+0800

Refactor:use getopt_long for arguments parsing.


可以看出引发冲突的提交一个是当前工作分支master上的最新提交,即开发者user1的重构命令行参数解析的提交,而另外一个引发冲突的是要拣选的提交,即开发者user2针对用户名显示不全所做的错误修正提交。一定是因为这两个提交的更改发生了重叠导致了冲突的发生。下面就来解决冲突。

3.冲突解决

冲突解决可以使用图形界面工具,不过对于本例直接编辑冲突文件,手工进行冲突解决也很方便。打开文件src/main.c就可以看到发生冲突的区域都用特有的标记符标识出来,参见表18-1中左侧一列的内容。

18.5.5 发布分支的提交合并到主线 - 图1

在文件src/main.c冲突内容中,第25-52行及第61行是master分支中由开发者user1重构命令行解析时提交的内容,而第54~56行及第63-68行则是分支hello-1.x中由开发者user2提交的修正用户名显示不全的Bug的相应代码。

表18-1右侧的一列则是冲突解决后的内容。为了和冲突前的内容相对照,重新进行了排版,并对差异内容进行加粗显示。您可以参照完成冲突解决。

将手动编辑完成的文件src/main.c添加到暂存区才真正地完成了冲突解决。


$git add src/main.c


因为是拣选操作,提交时最好重用所拣选提交的提交说明和作者信息,而且也省下了自己写提交说明的麻烦。使用下面的命令完成提交操作。


$git commit-C hello-1.x^1

[master 10765a7]Bugfix:allow spaces in username.

1 files changed,8 insertions(+),4 deletions(-)


4.完成全部拣选操作

接下来再将开发者user1在分支hello-1.x中的提交也拣选到当前分支。所拣选的提交非常简单,不过是修改了提交说明中的文字错误而已,拣选操作也不会引发异常,直接完成。


$git cherry-pick hello-1.x^2

Finished one cherry-pick.

[master d81896e]Fix typo:-help to—help.

Author:user1<user1@sun.ossxp.com>

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


现在通过日志可以看到master分支已经完成了对已知Bug的修复。


$git log-3—graph—oneline

*d81896e Fix typo:-help to—help.

*10765a7 Bugfix:allow spaces in username.

*0881ca3 Refactor:use getopt_long for arguments parsing.


查看状态可以看到当前的工作分支相对于远程服务器有两个新提交。


$git status

On branch master

Your branch is ahead of 'origin/master' by 2 commits.

#

nothing to commit(working directory clean)


执行推送命令将本地master分支同步到远程共享版本库。


$git push

Counting objects:11,done.

Delta compression using up to 2 threads.

Compressing objects:100%(8/8),done.

Writing objects:100%(8/8),802 bytes,done.

Total 8(delta 6),reused 0(delta 0)

Unpacking objects:100%(8/8),done.

To file:///path/to/repos/hello-world.git

0881ca3..d81896e master->master