git分支的合并

http://gitbook.liuhui998.com/3_3.html

http://gitbook.liuhui998.com/5_3.html

一、如何分支的合并

在git中,可以使用git merge 和git rebase两个命令来进行分支的合并。

git merge 和git rebase在大体上都差不多,下文主要以git merge来例来讲解分支的合并流程。

如果你想了解分支合并的更多内容,请阅读《git merge简介》,《git rebase简介(基本篇)》和《git rebase简介(高级篇)》。

git merge命令示例:

$ git merge branchname

这个命令把分支"branchname"合并到了当前分支里面。

如有冲突(冲突--同一个文件在远程分支和本地分支里按不同的方式被修改了);那么命令的执行输出就像下面一样

$ git merge next

100% (4/4) done

Auto-merged file.txt

CONFLICT (content): Merge conflict in file.txt

Automatic merge failed; fix conflicts and then commit the result.

在有问题的文件上会有冲突标记,在你手动解决完冲突后就可以把此文件添 加到索引(index)中去,用git commit命令来提交,就像平时修改了一个文件 一样。

如果你用gitk来查看commit的结果,你会看到它有两个父分支:一个指向当前的分支,另外一个指向刚才合并进来的分支。

二、解决合并中的冲突

如果执行自动合并没有成功的话,git会在索引和工作树里设置一个特殊的状态, 提示你如何解决合并中出现的冲突。

有冲突(conflicts)的文件会保存在索引中,除非你解决了问题了并且更新了索引,否则执行 git commit都会失败:

$ git commit

file.txt: needs merge

如果执行 git status 会显示这些文件没有合并(unmerged),这些有冲突的文件里面会添加像下面的冲突标识符:

<<<<<<< HEAD:file.txt

Hello world

=======

Goodbye

>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt

你所需要的做是就是编辑解决冲突,(接着把冲突标识符删掉),再执行下面的命令:

$ git add file.txt

$ git commit

注意:提交注释里已经有一些关于合并的信息了,通常是用这些默认信息,但是你可以添加一些你想要的注释。

上面这些就是你要做一个简单合并所要知道的,但是git提供更多的一些信息来 帮助解决冲突。

三、撒销一个合并

如果你觉得你合并后的状态是一团乱麻,想把当前的修改都放弃,你可以用下面的命令回到合并之前的状态:

$ git reset --hard HEAD

或者你已经把合并后的代码提交,但还是想把它们撒销:

$ git reset --hard ORIG_HEAD

但是刚才这条命令在某些情况会很危险,如果你把一个已经被另一个分支合并的分支给删了,那么 以后在合并相关的分支时会出错。

关于撤销的更多内容请参考《git reset简介

四、快速向前合并

还有一种需要特殊对待的情况,在前面没有提到。通常,一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。

但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交 (commit)都已经存在另一个分支里了,git 就会执行一个“快速向前"(fast forward)操作;git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。

五、在合并过程中得到解决冲突的协助

git会把所有可以自动合并的修改加入到索引中去, 所以git diff只会显示有冲突的部分. 它使用了一种不常见的语法:

$ git diff

diff --cc file.txt

index 802992c,2b60207..0000000

--- a/file.txt

+++ b/file.txt

@@@ -1,1 -1,1 +1,5 @@@

++<<<<<<< HEAD:file.txt

+Hello world

++=======

+ Goodbye

++>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086:file.txt

回忆一下, 在我们解决冲突之后, 得到的提交会有两个而不是一个父提交: 一个父提交是当前分支提交前的HEAD,; 另外一个父提交是被合并分支的HEAD, 被暂时存在MERGE_HEAD.

在合并过程中, 索引中保存着每个文件的三个版本. 三个"文件暂存(file stage)"中的每一个都代表了文件的不同版本:

$ git show :1:file.txt  # 两个分支共同祖先中的版本.

$ git show :2:file.txt  # HEAD中的版本.

$ git show :3:file.txt  # MERGE_HEAD中的版本.

当你使用git diff去显示冲突时, 它在工作树(work tree), 暂存2(stage 2)和暂存3(stage 3)之间执行三路diff操作, 只显示那些两方都有的块(换句话说, 当一个块的合并结果只从暂存2中得到时, 是不会被显示出来的; 对于暂存3来说也是一样).

上面的diff结果显示了file.txt在工作树, 暂存2和暂存3中的差异. git不在每行前面加上单个‘+‘或者‘-‘, 相反地, 它使用两栏去显示差异: 第一栏用于显示第一个父提交与工作目录文件拷贝的差异, 第二栏用于显示第二个父提交与工作文件拷贝的差异. (参见git diff-files中的"COMBINED DIFF FORMAT"取得此格式详细信息.)

在用直观的方法解决冲突之后(但是在更新索引之前), diff输出会变成下面的样子:

$ git diff

diff --cc file.txt

index 802992c,2b60207..0000000

--- a/file.txt

+++ b/file.txt

@@@ -1,1 -1,1 +1,1 @@@

- Hello world

-Goodbye

++Goodbye world

上面的输出显示了解决冲突后的版本删除了第一个父版本提供的"Hello world"和第二个父版本提供的"Goodbye", 然后加入了两个父版本中都没有的"Goodbye world".

一些特别diff选项允许你对比工作目录和三个暂存中任何一个的差异:

$ git diff -1 file.txt      # 与暂存1进行比较

$ git diff --base file.txt          # 与上相同

$ git diff -2 file.txt      # 与暂存2进行比较

$ git diff --ours file.txt          # 与上相同

$ git diff -3 file.txt      # 与暂存3进行比较

$ git diff --theirs file.txt    # 与上相同.

还有,git log和gitk命令也为合并操作提供了特别的协助:

$ git log --merge

$ gitk --merge

这会显示所有那些只在HEAD或者只在MERGE_HEAD中存在的提交, 还有那些更新(touch)了未合并文件的提交.

你也可以使用git mergetool, 它允许你使用外部工具如emacs或kdiff3去合并文件.

每次你解决冲突之后, 应该更新索引:

$ git add file.txt

完成索引更新之后, git-diff(缺省地)不再显示那个文件的差异, 所以那个文件的不同暂存版本会被"折叠"起来.

六、多路合并

你可以一次合并多个头, 只需简单地把它们作为git merge的参数列出. 例如,

$ git merge scott/master rick/master tom/master

相当于:

$ git merge scott/master

$ git merge rick/master

$ git merge tom/master

七、子树

有时会出现你想在自己项目中引入其他独立开发项目的内容的情况. 在没有路径冲突的前提下, 你只需要简单地从其他项目拉取内容即可.

如果有冲突的文件, 那么就会出现问题. 可能的例子包括Makefile和其他一些标准文件名. 你可以选择合并这些冲突的文件, 但是更多的情况是你不愿意把它们合并. 一个更好解决方案是把外部项目作为一个子目录进行合并. 这种情况不被递归合并策略所支持, 所以简单的拉取是无用的.

在这种情况下, 你需要的是子树合并策略.

这下面例子中, 我们设定你有一个仓库位于/path/to/B (如果你需要的话, 也可以是一个URL). 你想要合并那个仓库的master分支到你当前仓库的dir-B子目录下.

下面就是你所需要的命令序列:

$ git remote add -f Bproject /path/to/B (1)

$ git merge -s ours --no-commit Bproject/master (2)

$ git read-tree --prefix=dir-B/ -u Bproject/master (3)

$ git commit -m "Merge B project as our subdirectory" (4)

$ git pull -s subtree Bproject master (5)

子树合并的好处就是它并没有给你仓库的用户增加太多的管理负担. 它兼容于较老(版本号小于1.5.2)的客户端, 克隆完成之后马上可以得到代码.

然而, 如果你使用子模块(submodule), 你可以选择不传输这些子模块对象. 这可能在子树合并过程中造成问题.

译者注: submodule是Git的另一种将别的仓库嵌入到本地仓库方法.

另外, 若你需要修改内嵌外部项目的内容, 使用子模块方式可以更容易地提交你的修改.

时间: 2024-10-13 03:16:53

git分支的合并的相关文章

【原创】Git 分支的合并【Learn Git Branching】

merge   git merge是我们要学习的合并工作的第一个方法.合并产生一个特殊的提交记录,它包含两个唯一父提交.有两个父提交的提交记录本质上是:“我想把这两个父提交本身及它们的父提交集合都包含进来.” 1. 有共同祖先,但非直接上下游关系的分支 根据C1.C2.C3这三个提交对象(C1是C2.C3的共同祖先),合并之后,生成了一个新的提交对象,包含了两个父提交.假如从合并后的master出发,开始沿着箭头向上游走,在到达起点的路上会经过所有的提交记录,这说明master包含了所有代码库的

idea中git分支、合并与使用

1.分支的新建与合并使用场景介绍 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流. 你将经历如下步骤: 开发某个网站. 为实现某个新的需求.问题(#53问题),创建一个分支(名为:iss53). 在这个分支上开展工作. 正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补. 你将按照如下方式来处理: 切换到你的线上分支(production branch). 为这个紧急任务新建一个分支(名为:hotfix),并在其中修复它. 在测试通过之后,切换回线上分支

git 分支的创建、合并、删除

      基本概念与命令 分支(branch):每次提交,Git都把提交的内容串成一条时间线,这条时间线就是一个分支 .   git 分支的创建 git checkout -b gt 分支的合并 git merge git分支的删除  git branch -d git分支的查看  git branch      具体步骤 创建新的分支dev (以前的主分支是master) 查看git分支 在dev分支下添加并提交readme.txt 从dev分支切换到master分支 合并dev分支到mas

3.2 Git 分支 - 分支的新建与合并

分支的新建与合并 现在让我们来看一个简单的分支与合并的例子,实际工作中大体也会用到这样的工作流程: 开发某个网站. 为实现某个新的需求,创建一个分支. 在这个分支上开展工作. 假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照下面的方式处理: 返回到原先已经发布到生产服务器上的分支. 为这次紧急修补建立一个新分支,并在其中修复问题. 通过测试后,回到生产服务器所在的分支,将修补分支合并进来,然后再推送到生产服务器上. 切换到之前实现新需求的分支,继续工作. 分支的新建与切换

git使用笔记(二)分支与合并

By francis_hao    Nov 18,2016 查看分支,* 表示当前所在分支 $ git branch 查看分支和最后一次提交记录 $ git branch -v 新建分支 $ git branch alphabet 切换分支 $ git checkout alphabet 新建和切换可以合并为一步操作 $ git checkout -b digital 删除一个分支,注意:不能删除当前所在分支 $ git branch -d for_delete 查看所有分支的提交记录 $ gi

Git 分支合并

理解核心 Git最初只有一个分支,所有后续分支都是直接或间接的从这个分支切出来的. 在任意两个分支上,向前追溯提交记录,都能找到一个最近的提交同时属于这两个分支,这个提交就是两个分支的分叉节点 分支合并,就是把其它分支相对于分叉节点发生的变化合并到当前分支中. Git合并(merge)的是变化! 假设情景 时间点1:两个分支master和dev,现在这两个分支完全一样,处在同一个提交(commit)上,内容含A.B.C.D四部分. 时间点2:dev上开发新内容,不断修改提交,最后dev分支的内容

git分支创建分支删除分支合并

本文git版本1.9.6 一.创建分支,删除分支 二.创建分支,合并分支,删除分支 三.创建分支,git 3-way merge,删除分支 git branch 相关命令 git branch # 列出目前有多少branch git branch new-branch # 产生新的branch (名称: new-branch), 若没有特别指定, 会由目前所在的branch / master 直接复制一份. git branch new-branch master # 由master 产生新的b

eclipse中解决git分支合并冲突

冲突场景: 在master分支上有文件student.py. 在master上增新一个dev分支 在dev分支上修改文件student.py.增加函数def d():,并commit; 在master分支上修改文件student.py.删除函数def a():,并commit; 在master分支上合并dev分支,git提示冲突,如下图: 原因分析: 在master和dev分支上均对文件student.py进行了修改,导致合并是出现错误,具体原因可以见 http://www.liaoxuefen

Git分支合并选择

用Git进行多人协作开发时,必然会合并代码,解决冲突.然而合并代码也是需要点技巧的,如果对一些关键命令没有理解去使用的话,git的版本演进路线就会变得很乱,从而造成了日后维护的一些麻烦. Git上合并代码有git merge 以及 git rebase 两种方式.下面将深入两者的用法以及对两者的适用场景作个总结. 前置知识点 Master分支:首先,代码库应该有一个.且仅有一个主分支.所有提供给用户使用的正式版本,都在这个主分支上发布.这个分支被称为Master分支: Develop分支:主分支