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版本的内容一致

 

posted @ 2023-06-12 15:39  小粉优化大师  阅读(308)  评论(0编辑  收藏  举报