之前写了rebase与merge的区别以及建议使用rebase,但实际用rebase的时候还是存在不少问题,此处记录一下。

rebase命令

rebase remote branch:

1
2
git pull --rebase <remote> <branch>
#remote 指的是远程仓库名,branch指的是远程仓库的分支名

因此pull过程是先checkout到需要pull的分支,然后fetch远程仓库的分支,然后rebase到远程仓库的分支。

rebase local branch:

1
2
git rebase <branch>
#branch指的是本地分支名

rebase执行的过程,以rebase远程分支为例

现在假设从主分支(origin)切出一条分支(mywork),进行功能开发,同时主分支上也合并了一下别人的修改,这时候两个分支开始‘分叉’了。

示意图1

假设现在功能开发完成,需要进行分支合并,用rebase操作。它会首先变基到目标分支最新提交C4上,然后依次比对mywork分支自C2以来的所有提交与C4的差异,然后将这些差异逐个应用到C4上,最终得到C5’,C6’ ,这样就完成了rebase操作。

image-20240429232802787 image-20240429232832955

rebase结束后将分支push到origin即可,push完整命令

1
2
git push <remote> <branch>
#remote 指的是远程仓库名,branch指的是远程仓库的分支名,命令即将当前仓库推送到特定远程仓库中

rebase时处理冲突

rebase时可能出现冲突,这时候需要手动解决冲突,解决完冲突后需要执行

1
git rebase --continue

注意,如果使用vs code处理冲突时,git插件有时可以在我们处理冲突结束后,直接点击继续即可。若显示的是提交,则我们不能点提交去继续执行rebase,因为这会在一个detached的临时分支上提交更改。相反,此时我们应该手动执行以上命令

杂谈

vs code的gitlens可以查看提交图,但当我们checkout到某次提交上时,gitlens显示的将会是那次提交的名称,即这是一个匿名分支,如果我们在这个匿名分支上进行更改提交,那么会在这个匿名分支上生成提交历史,而不是在现有分支中,因此容易导致分支混乱,最好的办法是针对这个匿名分支创建一个新的分支,然后再进行提交。

一点问题:

当我在做算法模型开发时,如果我想在一个文件中重复尝试多个配置参数,我可能想要每次提交保留一组配置参数,以便我可以回溯并查看之前的参数组合。但如果我发现之前参数组合可能存在一定不合理性,即我想更新那次提交的内容,并将更新的内容仍然保留在那次提交中,这时候我应该怎么做呢?

用图来简单表示我的想法:

image-20240429234710956

即我想在提交历史中更改B这个提交,但仍然保留提交C和D,即提交的历史变为A->B’->C->D。

以下是chatgpt回答,以后可以验证一下。

git 我有提交A->B->C->D,我现在想要回到提交B中,更改某些文件内容,并提交这个更改,但我不想这个更改影响后续C和D的提交,即我想更改B后的提交历史为A->B’->C->D,有什么办法能够实现

  1. 打开交互式重新基础
    运行以下命令,将您的提交历史从 B 开始进行交互式重新基础:
1
git rebase -i HEAD~3

这里的 HEAD~3 表示从当前分支的 HEAD 开始向前数三个提交(即包括 A、B 和 C)。

  1. 编辑提交历史
    执行上述命令后,Git 会打开一个文本编辑器,显示您要进行交互式 rebase 的提交历史。您将看到类似于以下内容的界面:
1
2
3
pick a1a1a1a Commit A
pick b2b2b2b Commit B
pick c3c3c3c Commit C
  1. 选择要编辑的提交
    将您想要修改的提交从 pick 改为 edit。在您的例子中,您想要编辑 Commit B,因此将 pick b2b2b2b Commit B 改为 edit b2b2b2b Commit B

  2. 应用更改并提交
    保存并关闭编辑器后,Git 将会从 Commit A 开始逐个应用提交。当 Git 应用到 Commit B 时,它将会停止并给出提示,告诉您您已经处于编辑状态,您可以进行更改。

  3. 进行更改并提交
    您可以在这个状态下更改文件。完成更改后,使用 git add 将更改的文件添加到暂存区,然后使用 git commit --amend 提交更改。

  4. 继续 rebase 操作
    当您完成更改并提交后,继续 rebase 操作:

1
git rebase --continue

Git 将会继续应用其余的提交(Commit C 和 Commit D)。

通过上述步骤,您可以在提交 B 之后进行更改,并保持提交历史的完整性,而不影响 Commit C 和 Commit D。