人生不如意之事十之八九,合并分支时同样也会遇到种种挑战。现在,让我们继续分支开发的旅程,并探索合并过程中可能遇到的问题。
首先,我们准备一个新的feature1
分支,以便在上面进行开发工作。使用git switch -c
命令可以创建并切换到新分支:
$ git switch -c feature1
Switched to a new branch 'feature1'
在feature1
分支上,我们修改readme.txt
文件的最后一行,将其改为:“Creating a new branch is quick AND simple.”。然后,将这个修改提交到Git仓库:
$ git add readme.txt
$ git commit -m "AND simple"
[feature1 14096d0] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
接下来,我们切换到master
分支,准备将feature1
分支的改动合并进来:
$ git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
在切换到master
分支时,Git提醒我们当前的master
分支比远程的master
分支超前了1个提交。这是因为我们之前在master
分支上做了修改并提交,而这些改动还没有推送到远程仓库。
现在,我们在master
分支上对readme.txt
文件的最后一行做了另一个修改,将其改为:“Creating a new branch is quick & simple.”。并提交这个改动:
$ git add readme.txt
$ git commit -m "& simple"
[master 5dc6824] & simple
1 file changed, 1 insertion(+), 1 deletion(-)
现在,master
分支和feature1
分支都有了各自的修改,并且这些修改涉及到相同的文件。如果我们尝试合并feature1
分支到master
分支,Git将会检测到冲突,因为两个分支对同一行文本做了不同的修改。
在这种情况下,由于feature1
分支和master
分支对readme.txt
文件的不同部分做了修改,Git无法自动执行“快速合并”。当尝试合并这两个分支时,Git会尝试合并各自的改动,但由于冲突的存在,合并过程失败了。
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
Git提示我们readme.txt
文件存在冲突,并建议我们手动解决冲突后再提交。为了查看冲突的具体内容,我们可以使用git status
命令:
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
查看readme.txt
文件的内容,我们可以看到Git用特殊的标记(<<<<<<<
, =======
, >>>>>>>
)标出了冲突的部分:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a Mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
为了解决这个问题,我们需要手动编辑readme.txt
文件,解决冲突的内容。在这个例子中,我们可以将冲突的部分修改为:
Creating a new branch is quick and simple.
保存文件后,我们使用git add
命令将解决冲突后的文件标记为已解决状态,并使用git commit
命令完成合并提交:
$ git add readme.txt
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed
这样,我们就成功解决了合并冲突,并将合并后的结果提交到了master
分支。在解决冲突时,重要的是要确保合并后的代码能够正常工作,并且符合团队的编码规范。
现在,master
分支和feature1
分支变成了下图所示:
使用带有参数的 git log
命令,我们可以更详细地查看分支的合并历史,包括分支的创建、合并以及提交的内容。--graph
参数会以图形化的方式展示分支和合并的历史,--pretty=oneline
参数会将每个提交的信息压缩成一行显示,而 --abbrev-commit
参数则会将提交哈希值缩短以便于阅读。
执行以下命令:
$ git log --graph --pretty=oneline --abbrev-commit
输出可能是这样的:
* cf810e4 (HEAD -> master) conflict fixed
|\
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file
这个输出展示了一个可视化的分支合并历史。在这个例子中,*
表示提交,|
表示分支,|
的数量表示分支的层级,而 (
和 )
则用来表示分支的指向和合并点。从输出中我们可以看到 feature1
分支在 master
分支上创建了一个新的提交 14096d0
,并且最终被合并到了 master
分支上,形成了一个合并提交 cf810e4
。
现在,既然我们已经完成了合并并且解决了所有的冲突,我们可以安全地删除 feature1
分支了。使用 git branch -d
命令并跟上分支名称可以删除一个分支:
$ git branch -d feature1
Deleted branch feature1 (was 14096d0)