# rebase分支合并
# 说明
以下 v2
是某个需求的开发分支, dev
是总的开发分支,v2
是基于dev
分支签出的。
当完成v2
的开发后,需要把代码合并到dev
,我们可以使用rebase
进行合并:
# 首先将 v2 push到远程仓库
git add .
git commit -m 'xxx'
git push origin v2
# 切换到 dev 拉取最新代码
git checkout dev
git pull origin dev
# 切换到 v2
git checkout v2
git rebase dev # 将 v2 的所有[commit] 变基到(应用到) dev
git rebase --abort # 取消变基
# 切换到 dev
git checkout dev
git merge v2 # 将 dev分支 快进合并 (此时 (HEAD -> dev, v2) [commit] 两个分支指向同一个提交)
# 查看 原v2的[commit]记录 是否在dev分支的最前面(变基成功会把v2的提交记录应用到dev分支的最前面)
git log
# 如果到这一步发现有问题,尝试使用 git --abort中止变基,如果还是有问题的可以在dev分支上使用《后悔药》操作, 再到v2分支上使用《后悔药》操作,即可使两个分支都回退到 rebase变基 之前的状态
# 试运行项目是否有问题
yarn start
git status # 查看状态是否有问题
git push origin dev # 推送到远程仓库的 dev
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 变基要遵守的准则
几个人同时在一个分支上进行开发和提交时,你不要中途执行变基,只有在大家都完成工作之后才可以执行变基。
不要基于rebase的分支 切新分支。
不要对已经合并到主分支的本地修改进行变基。
不要在预发布/正式分支上使用rebase -i。
# 变基的实质
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 因此,变基操作过后的分支将不要再使用。
# 后悔药
# 查看HEAD指针变动记录
git reflog
# 记录示例(当前分支是v2):
07c398f (HEAD -> v2, master) HEAD@{0}: checkout: moving from master to v2
07c398f (HEAD -> v2, master) HEAD@{1}: rebase (finish): returning to refs/heads/master
07c398f (HEAD -> v2, master) HEAD@{2}: rebase (start): checkout v2
15a97d8 HEAD@{3}: reset: moving to 15a97d8
07c398f (HEAD -> v2, master) HEAD@{4}: merge v2: Fast-forward
15a97d8 HEAD@{5}: checkout: moving from v2 to master
07c398f (HEAD -> v2, master) HEAD@{6}: rebase (finish): returning to refs/heads/v2
07c398f (HEAD -> v2, master) HEAD@{7}: rebase (pick): C
15a97d8 HEAD@{8}: rebase (start): checkout master # 首次rebase
d278ecd HEAD@{9}: checkout: moving from master to v2 # rebase前的状态
15a97d8 HEAD@{10}: commit: D
# 可见,示例中最初的 rebase 操作是 HEAD@{8},想回退到变基前的状态需让指针指向 HEAD@{9}
git reset --hard d278ecd # 重置当前分支的HEAD为指定[commit],同时重置暂存区和工作区,与指定[commit]一致
# 此时打印 log 查看是否回到之前的状态
git log
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注意:此操作只能回退当前的分支,如其他分支也要回退,需要切换到该分支并执行上面操作。
# 开发期间的rebase操作
# 背景
有两个分支:
dev
*v2
2
2.4-dev
是基于dev
切出来的。
提交记录如下:
dev
a - b - c
v2
2
3
开发期间,两个分支同时有新的commit :
dev
a - b - c - d - e
\ - f - g
v2
2
3
4
当前你正在v2
进行开发,dev
也同时进行开发,并有重大的改变,你需要把dev
的提交同步到v2
。
需求: 把dev
中新的提交同步到v2
,且不能影响dev
分支。
# 操作步骤
基于最新的
dev
切一个新的分支dev-copy
dev-copy
和dev
两者的 commit ID 一致。在
dev-copy
中执行rebase,将dev-copy
的提交变基到v2
git rebase v2 # 将 dev-copy 的提交[commit] 变基到(应用到) v2,此时的 dev-copy 分支为变基后的分支 # 等同于 git rebase v2 dev-copy
1
2
3删除原
v2
分支,将dev-copy
分支名改为v2
# 当前在 dev-copy 分支 git branch -d v2 # 删除分支 git branch -m dev-copy v2 # 重命名
1
2
3
# git cherry-pick
来源:《git cherry-pick 教程》 (opens new window)
用于将单个或几个[commit]
复制到另一个分支。
# 基本应用
git cherry-pick <commitHash> # 将commitHash应用于当前分支
上面命令就会将指定的提交commitHash
,应用于当前分支。这会在当前分支产生一个新的提交,当然它们的哈希值会不一样。
git cherry-pick命令的参数,不一定是提交的哈希值,分支名也是可以的,表示转移该分支的最新提交。
# 转移多个提交
Cherry pick 支持一次转移多个提交。
git cherry-pick <HashA> <HashB> # A和B提交
上面的命令将 A 和 B 两个提交应用到当前分支。这会在当前分支生成两个对应的新提交。
如果想要转移一系列的连续提交,可以使用下面的简便语法。
git cherry-pick A..B # A到B提交,不包含A
上面的命令可以转移从 A 到 B 的所有提交。它们必须按照正确的顺序放置:提交 A 必须早于提交 B,否则命令将失败,但不会报错。
注意,使用上面的命令,提交 A 将不会包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的语法。
git cherry-pick A^..B # A到B提交,包含A
# git rebase -i
主要命令:
git rebase -i master~1 #最后一次
git rebase -i master~5 #最后五次
git rebase -i HEAD~3 #当前版本的倒数第三次状态
git rebase -i commit id #指定的提交位置
2
3
4
开发过程中,我们可能遇到一次merge多个commit的情况,在merge之前我们做测试的时候发现某次提交有问题,这时候我们又不想新提一个commit来解决这个问题,这时候该怎么办?
解决方法 git log 查看历史提交
A---B(有bug)----C----D---E 发现 B 提交有bug,我们想要直接修改B,但是又不想多增加F提交;或者我们想修改B提交的commit信息。
git rebase 修改历史提交
1. git rebase -i HEAD~5 # rebase HEAD之前的5次提交
2. 将需要修改的commit所在的行前面的 pick 修改为edit或者e
利用命令行修改文本,将光标移动至B提交前面pick,然后输入i进入修改模式,将pick改为e,然后输入wq保存
pick b4ba123435 A
e 0ae807b99c B
pick 70890e2e86 C
pick aa0778f109 D
pick 630cc16edb E
3. 之后会发现git的分支信息变为 master|REBASE-i 2/5
4. 修改bug代码,如果只需要修改commit信息可以跳过此步
5. git commit --amend # 以当前代码重新覆盖本次提交
6. 修改commit信息,若不需要修改commit信息则可以直接wq保存结束
7. git rebase --continue # 继续rebase,如果有冲突则解决冲突
2
3
4
5
6
7
8
9
10
11
12
13
14
注意 如果rebase过程中不想rebase了,可以使用
git rebase --abort # 终止rebase
rebase结束后,会修改所有rebase的commitID,如果想要push到远程仓库可能需要强制push
git push [仓库名] [分支] -f
当你运行 git rebase -i
时,你会进入一个编辑器会话,其中列出了所有正在被变基的提交,以及可以对其执行的操作的多个选项。默认的选择是选择(Pick
)。
Pick
:会在你的历史记录中保留该提交。Reword
:允许你修改提交信息,可能是修复一个错别字或添加其它注释。Edit
:允许你在重放分支的过程中对提交进行修改。Squash
:可以将多个提交合并为一个。- 你可以通过在文件中移动来重新排序提交。