git-合并策略【git merge】、优雅合并【git rebase】、合并进阶【git rebase -i】
1、平行分支
1.1、什么是平行分支?
简单来说,当前出现两个分支,而每个分支上的commit次数都>=2,我们切回到feature-B分支继续开发代码和提交代码。
1.2、合并语法
# 切换到主分支 git checkout master # 合并分支 git merge v3.1.1
1.3、平行分支效果图
1.4、根据平行分支合并效果图-实践
# 创建主分支 touch version.txt && git add . && git commit -m "master version.txt" # 创建v1.0、v1.1、v1.2分支 git checkout -b v1.0 && echo "v1.0" >version.txt && git add . && git commit -m "v1.0" git checkout -b v1.1 && echo "v1.1" >>version.txt && git add . && git commit -m "v1.1" git checkout -b v1.2 && echo "v1.2" >>version.txt && git add . && git commit -m "v1.2" # 合并到master分支 git checkout master git merge v1.0 git merge v1.1 git merge v1.2 # 创建v1.2.1分支,此时head在此分支下面 git checkout -b v1.2.1 && echo "v1.2.1" >>version.txt && git add . && git commit -m "v1.2.1" git checkout master git merge v1.2.1 # 切换到v1.2分支,发展v1.3分支 git checkout v1.2 git checkout -b v1.3 && echo "v1.3" >>version.txt && git add . && git commit -m "v1.3" git checkout -b v1.3.1 && echo "v1.3.1" >>version.txt && git add . && git commit -m "v1.3.1" # 合并v1.3.1分支 git checkout master git merge v1.3.1 # 此时暂存区,还需要手动修改 # git status On branch master 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: version.txt # 查看文件 # cat version.txt v1.0 v1.1 v1.2 <<<<<<< HEAD # 当前的master在此分支 v1.3 ======= v1.3.1 >>>>>>> v1.3.1 # 差异内容 ,可以手动删除多余,再提交合并即可 # 修改如下: # cat version.txt v1.0 v1.1 v1.2 v1.2.1 v1.3 v1.3.1 git add . git commit -m "master & v1.3.1" # 查看日志 # git log --pretty=format:"%h - %an, %ar : %s" --graph * 634e1bc - 277667028@qq.com, 24 seconds ago : master & v1.3.1 |\ | * 5f02b11 - 277667028@qq.com, 3 minutes ago : v1.3.1 | * 47cdca8 - 277667028@qq.com, 3 minutes ago : v1.3 * | 3966745 - 277667028@qq.com, 3 minutes ago : v1.2.1 |/ * 796221d - 277667028@qq.com, 3 minutes ago : v1.2 * 17d84df - 277667028@qq.com, 3 minutes ago : v1.1 * 75be7db - 277667028@qq.com, 3 minutes ago : v1.0 * 0bc787c - 277667028@qq.com, 3 minutes ago : master version.txt
2、优雅合并
2.1、场景需求
到目前位置,我们学习了很多中分支合并的方法,但是每种分支的合并效果图,都是千奇百怪,到处都是分支,并不能让我们的 历史记录清晰明了,特别是出现大量分支合并的时候,有可能导致一个非常混乱的历史记录图谱,非常难以阅读,难以理解。
接下来我们学习一种优雅的代码合并,合并后的master分支就是一条线,这个命令就是rebase。
2.2、git rebase
2.2.1、语法格式
作用:该命令的效果就是,将其他分支的内容合并到当前分支,并形成一个新的提交。
命令格式:git rebase <基准分支> <分支> 注意: 可以将<基准分支> 理解为本地分支,将 <分支> 理解为其他分支,即将其他分支合并到本地分支上<分支> 如果不写,表示将本地分支合并到 <基准分支> 上
2.2.2、rebase合并效果图
2.2.3、对于rebase分支合并master分支来说
它会基于两分支的共同起始点(0b)进行分析,将开发分支的所有记录(1a+1b)都收集起来,生成一系列的文件补丁,然后基于master分支的最后一个commit记录(0c),将刚才收集的所有文件补丁,重新提交一 下,生成新的commit记录(1a'和1b'),即重写commit记录。
2.2.4、对于master分支rebase分支来说
它会基于两分支的共同起始点(0b)进行分析,将master分支的所有记录(0c)都收集起来,生成一系列的文件补丁,然后基于rebase分支的最后一个commit记录(1b),将刚才收集的所有文件补丁,重新提交一 下,生成新的commit记录(0c')
2.2.5、注意
rebase后的提交记录(1b'|0c')和merger后的提交记录(0d),内容是完全一样的。 rebase的提交记录看起来非常整齐,符合我们的一般习惯,分支过多的话,merge记录效果不甚理想。
2.3、rebase实践
2.3.1、基础环境
# 基于一个新的代码仓库,做两次提交记录 mkdir /data/rebase-test && cd /data/rebase-test git init echo 0a > a.txt; git add a.txt; git commit -m "0a" echo 0b > b.txt; git add b.txt; git commit -m "0b" # 切换到rebase分支,并进行两次提交记录 git checkout -b rebase echo 1a > c.txt; git add c.txt; git commit -m "1a" echo 1b > d.txt; git add d.txt; git commit -m "1b" # 回到master分支,并进行一次提交后,检查效果 git checkout master echo 0c > e.txt; git add e.txt; git commit -m "0c" git log --all --oneline --graph # git log --all --oneline --graph * 883c49e (HEAD -> master) 0c | * 76cc93f (rebase) 1b | * 30317d4 1a |/ * 2af9c31 0b * 4ee41ae 0a # 代码仓库完整备份 cd .. cp -a rebase-test rebase-test1
2.3.2、进入rebase-test项目,切换到master分支,将rebase分支合并到master分支
cd /data/rebase-test/ git checkout master git rebase rebase # 注意 这两条命令相当于 git rebase rebase master git log --all --oneline --graph # git log --all --oneline --graph * e9870dc (HEAD -> master) 0c * 76cc93f (rebase) 1b * 30317d4 1a * 2af9c31 0b * 4ee41ae 0a
2.3.3、进入rebase-test1项目,切换到rebase分支,将master分支合并到rebase分支
cd /data/rebase-test1/ git checkout rebase git rebase master # 注意 这两条命令相当于 git rebase master rebase git log --all --oneline --graph # git log --all --oneline --graph * 9bc3ab2 (HEAD -> rebase) 1b * c37a4b9 1a * 883c49e (master) 0c * 2af9c31 0b * 4ee41ae 0a
3、合并进阶
3.1、需求解析
我们在实践rebase的时候,被合并的分支的所有记录都被合并到一个分支上了,我们觉得这有些问题,原因是,因为开发分支上的工作随机、不确定性太大,过程中提交的很多记录对项目来说没有太大的含义,最
终要的就是最后一条记录,所以,能不能将开发分支上所有提交记录,合并为一个commit记录到主分支上呢?
rebase 的 -i 参数可以了解一下。
3.2、场景需求示意图
3.3、命令解析
命令格式:git rebase -i <startpoint> <endpoint> 注意: -i 交互式的界面让用户编辑完成合并操作 <startpoint>和<endpoint>用于指定了一个commit记录区间,若不指定<endpoint>则表示当前分 支HEAD所指向的commit记录。 <startpoint> 一般指的是checkout该分支的主分支的commit_id commit记录区间是一个前开后闭的效果,即不包含<startpoint>的内容。 rebase对于清理长旧分支的提交记录来说,是非常适用的 -i 参数的一般 动作 p, pick <提交> = 使用提交 r, reword <提交> = 使用提交,但修改提交说明 e, edit <提交> = 使用提交,进入 shell 以便进行提交修补 s, squash <提交> = 使用提交,但融合到前一个提交 f, fixup <提交> = 类似于 "squash",但丢弃提交说明日志 x, exec <命令> = 使用 shell 运行命令(此行剩余部分) b, break = 在此处停止(使用 'git rebase --continue' 继续变基) d, drop <提交> = 删除提交 l, label <label> = 为当前 HEAD 打上标记 t, reset <label> = 重置 HEAD 到该标记 m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] . 创建一个合并提交,并使用原始的合并提交说明(如果没有指定 . 原始提交,使用注释部分的 oneline 作为提交说明)。使用 . -c <提交> 可以编辑提交说明。
3.4、实践
3.4.1、准备版本数据
# 在一个初始环境中,做5次提交 mkdir /data/rebase-i && cd /data/rebase-i git init for i in {1..5} do echo "${i}" >> a.txt; git add a.txt; git commit -m "v1.${i}" done # 查看效果 # git log --all --graph --oneline * dab73f6 (HEAD -> master) v1.5 * a8d58a4 v1.4 * 4f16e30 v1.3 * f3c9c53 v1.2 * 15104d5 v1.1
3.4.2、合并实践
# 合并1.2-1.5,所以-i 应该指向1.1的commit_id 15104d5 # git rebase -i 15104d5 hint: Waiting for your editor to close the file... pick f3c9c53 v1.2 # pick 表示留存commit记录,第一个的操作指令必须是pick s 4f16e30 v1.3 # s的指令表示我要与父提交记录合并到一起 s a8d58a4 v1.4 s dab73f6 v1.5 # 提示:等待您的编辑器关闭文件... # 注意:这个文件中的所有# 开头的信息都不会在git log中显示 # This is a combination of 4 commits. # This is the 1st commit message: v1.2 # This is the commit message #2: v1.3 # This is the commit message #3: v1.4 # This is the commit message #4: v1.5 ... # 合并好,查看日志 # git log --all --graph --oneline * f246b58 (HEAD -> master) v1.2 * 15104d5 v1.1 # 查看合并的日志 # git log commit f246b5898d1ba6331cdc760df4ecf91b0b8d0867 (HEAD -> master) Author: 277667028@qq.com <277668028@qq.com> Date: Mon Jun 12 07:11:29 2023 +0000 v1.2 v1.3 v1.4 v1.5 commit 15104d5959ea6c229e3e70513b0f6bee0a8bd8df Author: 277667028@qq.com <277668028@qq.com> Date: Mon Jun 12 07:11:29 2023 +0000 v1.1 # 查询文件 # cat a.txt 1 2 3 4 5 # 结果显示:1.2-1.5四条commit_id记录全部整合到一个新的commit记录里了,而且最终的代码效果和1.5版本的内容一致