Git 的 rebase 操作(commit 回放)
rebase 命令将另一个分支上的修改同步到当前分支,但是和 merge 不同,rebase 修改的当前分支的 commit 之前的内容。
举例说明:
- 原始分支 A
- 基于 A 创建了分支 B
- 分支 A 作了一次提交 c1,分支 B 作了一次提交 c2
- 基于 A 对于 B 分支进行 rebase 后,分支 B 中的提交记录变成 c1 c2
执行 rebase 后,B 分支的内容等同于将 B 分支上的修改在 A 分支上重放。
rebase 会改变当前分支中的 commit id,通常在 push 之前执行 rebase 操作
rebase 的命令参数
rebase 的命令参数如下:
NAME
git-rebase - Reapply commits on top of another base tip
SYNOPSIS
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
[<upstream> [<branch>]]
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
git rebase --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch
如果不指定 branch,默认对当前分支进行 rebase,如果指定了 branch,先切换到指定分支,再 rebase。
基于 tag 进行 rebase
--onto
指定 rebase 回放操作的开始位置,譬如 A 分支上有 b1 b2 c1 三个 commit,--onto b2
指定在 A 分支的 b2 位置回放当前分支的 commit。我们可以用这个参数进行基于 tag 进行回放。
如果不使用 --onto,默认在 A 分支最新的 commit 上进行回放,最常遇到的情况是 A 分支上既有 release tag 之前的 commit,也有之后的 commit,我们通常需要在 release tag 的基础上回放,暂时不引用未 release 的 commit。
git rebase upstream/master --onto nginx-0.25.1
upstream/master 中的 upstream 是远程仓库,上面的命令表示在 upstream 中的 master 分支的 nginx-0.25.1 tag 上回放当前分支中的 commit。查看远程仓库的方法:
git remote -v
origin http://gitlab.XXXXX.cn/infrastructure/ingress-nginx.git (fetch)
origin http://gitlab.XXXXX.cn/infrastructure/ingress-nginx.git (push)
upstream https://github.com/kubernetes/ingress-nginx.git (fetch)
upstream https://github.com/kubernetes/ingress-nginx.git (push)
Git rebase onto a tag when master and a branch is ahead of the current commits 中讨论了这个问题。
如果 rebase 过程出现冲突
用 git status 查看冲突文件:
$ git status
rebase in progress; onto 5179893a9
You are currently rebasing branch 'nginx-0.25.0-fp' on '5179893a9'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: Makefile
no changes added to commit (use "git add" and/or "git commit -a")
修改冲突文件,并提交,然后继续 rebase (git rebase --continue):
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".