(三)分支与标签 - git merge 命令的使用
git merge 是 Git 中用于的核心命令,可以将其他分支的修改合并到当前分支。
文章目录
1. 命令概述
git merge 命令的主要作用是将两个或多个开发历史(分支)合并在一起。它可以将指定分支的修改集成到当前分支(HEAD 所指向的分支)。
它的核心逻辑是:
1.找到当前分支与目标分支的最近共同祖先。
2.将当前分支和目标分支自共同祖先之后的所有更改进行合并。
3.创建一个新的 “合并提交” 来记录这次合并(除非是快进合并)。
2. 命令格式
基本的命令格式非常简单:
git merge [选项] <commit或分支名>
<commit或分支名>:通常是一个分支名(如feature/login),表示你想将那个分支的更改合并过来。它也可以是一个具体的提交 ID。[选项]:常用的选项我们会在下面详细介绍。
3. 基本用法
假设我们有一个典型的仓库,其提交历史如下所示:
A---B---C feature/login
/
D---E---F---G main
你当前在 main 分支(即 HEAD -> main),现在想要将 feature/login 分支的工作成果合并进来。
3.1 执行合并
# 1. 首先,确保你当前在目标分支上(main)
git checkout main
# 2. 然后,执行合并命令,将 feature/login 合并到 main
git merge feature/login
3.2 合并的三种结果
执行上述命令后,根据分支历史的不同,会产生三种主要结果:
3.2.1 快进合并
如果目标分支(main)的尖端是待合并分支(feature/login)的直接祖先,Git 会简单地将指针向前移动。因为这种合并没有需要解决的分歧,所以被称为“快进”。
合并后的历史会变成一条直线:
A---B---C feature/login, main
/
D---E---F---G
(实际上,main 指针直接移动到了 C 提交的位置)
3.2.2 三方合并
如果自两个分支分叉以来,当前分支(main)也有新的提交,Git 无法进行快进。这时,它会进行一次三方合并,使用共同祖先(E)、当前分支的尖端(G)和待合并分支的尖端(C)来创建一个新的合并提交。
合并后的历史会有一个分叉和汇合:
A---B---C feature/login
/ \
D---E---F---G---H main
这个新的 H 提交有两个父提交(G 和 C),它记录了这次合并行为。
3.2.3 合并冲突
如果在同一文件的同一行,两个分支都有修改,Git 无法自动决定使用哪个版本,就会产生合并冲突。
Git 会暂停合并过程,并标记出文件中的冲突区域,等待你手动解决。
<<<<<<< HEAD
这是当前分支(main)的内容
=======
这是 feature/login 分支的内容
>>>>>>> feature/login
解决冲突的步骤:
1.编辑文件:手动选择要保留的内容,或者进行重构,然后删除 Git 添加的冲突标记(<<<<<<<, =======, >>>>>>>)。
2.标记为已解决:使用 git add <文件名> 将解决后的文件暂存。这告诉 Git 冲突已经解决。
3.完成合并:所有冲突都解决并 add 后,执行 git commit 来最终完成合并提交。
4. 高级用法
4.1 --no-ff (禁用快进合并)
强制 Git 总是创建一个新的合并提交,即使可以进行快进合并。
git merge --no-ff feature/login
为什么要用它?
- 保留历史信息:在历史记录中明确能看到一个合并事件和特性的引入,避免了快进合并导致特性分支的历史被淹没在主线中。
- 便于回溯:如果出了问题,更容易找到是哪个合并引入的。
- 这是很多团队推荐的工作流实践。
4.2 --squash (压缩合并)
将待合并分支上的所有提交的更改“压缩”成一次新的提交,然后应用到当前分支。它不会真正地合并历史,也不会创建合并提交。
git merge --squash feature/login
执行此命令后,更改会被应用到工作区和暂存区,但不会自动提交。你需要手动执行一次提交。
git commit -m "Squashed all commits from feature/login"
为什么要用它?
- 保持主线整洁:对于一个开发过程中有很多琐碎提交的特性分支,在合并到主分支时,可以将其压缩成一个清晰的、有意义的提交。
- 注意:使用
--squash后,原始分支的历史会丢失,它不再是真正的“合并”。
4.3 -m (添加提交信息)
如果合并是自动创建的(非快进且无冲突),Git 会为你生成一个默认的提交信息,如 “Merge branch ‘feature/login’”。你可以使用 -m 选项来自定义这个信息。
git merge -m "Integrate user authentication feature" feature/login
4.4 --abort (中止合并)
如果在合并过程中遇到冲突,而你决定放弃这次合并,想回到合并前的状态,可以使用这个命令。
git merge --abort
你的仓库会恢复到 git merge 命令执行之前的状态。
5. 注意事项
5.1 确保工作区清洁
在执行 git merge 前,最好使用 git status 检查工作区是否干净。如果有未提交的更改,可能会与合并内容冲突,导致合并失败
5.2 先拉取再合并
如果你的当前分支有远程跟踪分支(如 main 跟踪 origin/main),在合并其他分支前,最好先执行 git pull 来同步最新的远程更改,避免潜在的复杂冲突。
5.3 理解合并策略
Git 有多种合并策略(如 recursive, resolve, octopus 等),默认情况下使用 recursive。对于大多数用户,知道默认策略就足够了
5.4 合并 vs. 变基
git merge 和 git rebase 都是集成更改的工具,但哲学不同。合并保留了历史的完整性,而变基通过重写历史来创造一条线性的历史。在公共分支上,通常建议使用合并;在个人特性分支上,可以使用变基来保持清晰。
6. 补充信息
一个典型的 Git Flow 或 GitHub Flow 中,git merge 的使用场景:
1.特性开发:你在 feature/my-feature 分支上开发新功能。
2.准备合并:功能完成后,你切换回主分支 main 或 develop。
3.获取最新代码:git pull origin main (这本身也是一次合并)。
4.合并特性:git merge --no-ff feature/my-feature。
5.解决冲突:如果存在,则手动解决。
6.推送:git push origin main。
更多推荐
所有评论(0)