GIT 合并基本原理

GIT 合并基本原理

二路合并

二路合并就是逐行对比,如果行内容不同这报冲突。

本地提交

console.log('hello world')

其他提交

console.log('world hello')

假设这是修改了同一个文件,进行合并时,发现这一行不一致,git 没有理由去丢弃本地提交或者其他提交,只能人为处理

三路合并

三路合并就是先找一个 base,如果两个文件相对于 base 都有修改,那就会报冲突,则需要人工修改,否则,git 将相当于 base 变化来决定最终结果

// base
console.log('hello world')

// mine
console.log('hello world')

// theirs
console.log('world hello')

base: 代表 mine 和 theirs 的公共祖先 mine: 代表本地修改 theirs: 代表合并其他人修改

当前的情况表示代码其他人有修改,但是本地没有修改,则 git 会自动把结果合并为 theirs 的代码

console.log('world hello')

如果本地文件被修改,合并的分支也有修改

// base
console.log('hello world')

// mine
console.log('hello world 1111')

// theirs
console.log('world hello')

git 无法合并,需要人为进行合并

<<<<<<< Mine
console.log('hello world 1111')
=======
console.log('world hello')
>>>>>>> Theirs

简单示例

1-9 表示每个修改后的 commit 以及一个唯一的 hash 值。

2 开始分出了一个 dev 分支, 4 7 是 master 上的提交,3 5 8 是 dev 上的提交

现在要合并 7 和 8,可以把 git 提交记录看成一个有向无环图,这样就可以找到 2 为他们的 base 节点,就可以用来对比文件是否有修改

递归三路合并原理

  • 0: 的位置创建了 a.js
console.log('a')
git add .
git commit -m "0"
  • 1: 的位置从 master 上创建了一个新的分支 test1,并且创建了一个提交,没有修改 a.js
git checkout -b test1
# 用于创建提交
touch test1.js
git add .
git commit -m "1"
  • 2: 的位置在 master 中创建了一个提交,没有修改 a.js
git checkout master
# 用于创建提交
git touch test2.js
git add .
git commit -m "2"
  • 3: 的位置在 test1 中创建了一个提交,没有修改 a.js
git checkout test1
git touch test3.js
git add .
git commit -m "3"
  • 4: 的位置在 master 中修改了 a.js,并且创建了一个提交
console.log('b')
git checkout master
git add .
git commit -m "4"
  • 5: 的位置从 master 上创建了一个新的分支 test2,并且合并了 test1 的代码,即合并 4 和 3 的代码,从前面可知,4 修改了 a.js 的代码,test1 分支中没有修改 a.js,他们的公共祖先是 0
git checkout -b test2
git merge test1
// 0
console.log('a')

// 3
console.log('a')

// 4
console.log('b')

由此对比出,合并后的为 4 中的内容,因为 3 没有修改该文件

console.log('b')
  • 6: 的位置切换到了 master 分支,并且合并了 test1 的代码,即合并 3 和 4 的代码,原理和 5 一致
git checkout master
git merge test1
  • 7: 的位置切换到了 test2 分支,并且修改 a.js 的代码,创建了一个提交
console.log('c')
git checkout test2
git add .
git commit -m "7"
  • 8: 的位置切换到了 master ,合并 test2 的代码,即合并6 和 7 此时,
git checkout master
git merge test2

6 和 7 有两个公共的祖先,4 和 3, 这时候会递归的去找 4 和 3 的祖先,则是 0,先合并 4 和 3,生成临时的节点,假设为 x ,根据上面的结论,x 中 a.js 为

console.log('b')

然后把 x 当作 6 和 7 的祖先,进行合并

// x
console.log('b')

// 6
console.log('b')

// 7 
console.log('c')

所以合并结果为

console.log('c')
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值