git相关
冲突=两边改了同一处代码(不只是新增行),Git 无法自动判断。解决冲突时,你需要手动决定最终保留main的改动、feature的改动,或两者结合。
·
这里合并,我一直太理解,可能是没有实际的例子,比如有两个部门开发同一个项目的不同部分,单独开发完了,一起合并到main分支上,这种就是合并吗?
完全正确!你这个例子就是典型的 merge 场景,我用一个更生活化的例子帮你彻底理解“合并”的意思。
🔹类比:多人写同一本书
- 部门A:负责第1-5章
- 部门B:负责第6-10章
- 开始时,两部门都从
main
分支(书的初稿)复制了一份。 - 部门A在自己的分支
feature-A
上写,部门B在feature-B
上写。
图示:
main: A---B---C (初始main)
feature-A: \--D---E---F
feature-B: \--G---H
- 当两边开发完了,就需要把两条线都“汇总”回
main
。 - merge 就是做这个“汇总”的操作:
git checkout main
git merge feature-A
git merge feature-B
合并后:
A---B---C----M1------M2 (main)
\ / \
D--E--F G--H
M1
,M2
是合并提交(merge commit),它把不同分支的修改糅合在一起。- 最终
main
就包含了部门A和部门B所有的修改。
🔹merge 本质
- 保留历史:你能看到谁在什么时候从哪条分支合并过来。
- 不改写提交:各自分支上的提交(D, E, F, G, H)保持原样。
- 结果是一个新提交:这个提交是合并操作产生的。
🔹现实应用场景
-
多人并行开发
- 各部门/小组/功能团队在各自分支上开发。
- 开发完后,用
merge
把它们合到主分支main
。 - 这样大家的贡献历史完整保留。
-
稳定发布流程
- 一般主分支
main
或release
只通过merge
集成,不直接开发。 - 这样你可以随时知道每次上线是合了哪些功能分支。
- 一般主分支
🔹和 rebase 的区别再捋一下
- merge:大家提交都原封不动地“接”在一起,保留分支合流点。
- rebase:像“剪切粘贴”,把你的提交“搬”到最新主分支上去,让历史像直线一样,但提交 ID 会变。
💡总结一句:
你说的“两个部门各自完成开发,最后把成果放在一起”,就是 Git
merge
的核心用法:整合不同开发分支到一个公共分支(比如main
)。
那在合并的时候,起冲突了,是和main的原始代码起了冲突是不是,就是比如同一行,分支进行了修改而不是新增,此时需要人为决定这行代码需要保留main的还是分支合并过来的,是不是这样?
完全对!你抓住了冲突的核心:
冲突=Git 无法自动判断要保留哪一方修改,需要你人工决定。
🔹为什么会冲突?
-
同一文件的同一行在不同分支上都被修改了:
main
上某一行被改成 A- 你的
feature
分支把同一行改成 B
→ Git 不知道该选 A 还是 B,就抛出冲突。
-
文件被删/被改:
- 一边改文件内容,另一边把文件删了
→ Git 不知道到底保留还是删除。
- 一边改文件内容,另一边把文件删了
-
复杂改动:
- 比如一边文件被重命名,另一边也修改了这个文件内容
→ 无法自动合并。
- 比如一边文件被重命名,另一边也修改了这个文件内容
🔹冲突发生的本质
-
当你执行
git merge feature
时:- Git 会找到
main
和feature
的最近公共祖先提交。 - 把
main
上的改动和feature
上的改动“套”在一起。 - 如果某个地方无法自动套上,就产生冲突。
- Git 会找到
图解:
common ancestor
|
v
main: A---B
\
feature: C---D
如果 B
和 D
对同一行改动 → 冲突。
🔹冲突解决的过程
- Git 会标记冲突的文件,插入冲突标记:
<<<<<<< HEAD
这里是 main 分支的版本
=======
这里是 feature 分支的版本
>>>>>>> feature
-
你手动编辑:
- 决定保留哪一方,或者融合两者改动。
-
标记解决冲突:
git add <file>
- 继续合并:
git merge --continue
🔹总结一句话:
冲突=两边改了同一处代码(不只是新增行),Git 无法自动判断。解决冲突时,你需要手动决定最终保留
main
的改动、feature
的改动,或两者结合。
更多推荐
所有评论(0)