定义
rebase意味着将一系列提交移动或者组合到一个新的基础提交。
换句话说,它将当前分支的基础从一个提交更改为另一个提交,使其看起来像是从另一个提交创建的分支。
这是通过执行 git rebase 命令来完成的。
考虑到即使分支看起来相同,它也是由全新的提交构成的。
git rebase 命令的使用
首先,我们需要这个命令来维护线性项目(item)(item)历史。
例如,在我们开始在功能分支上工作后,主分支会继续前进。
我们需要在功能分支中更新 master 分支,但 master 分支的历史记录必须保持干净。
我们在执行 Git 操作时需要一个清晰的历史来探索回归的引入。
在下面找到有关 git rebase 用法的更多信息:
不允许重新建立公共历史
永远不要在公共历史中发布提交后重新调整提交。
和修改重置一样,会给团队协作带来问题。
如果你这样做,旧的提交将被一个新的替换,它会显示为你的项目(item)(item)的一部分已经消失了。
Git rebase standard 和 Git rebase interactive的区别。
git rebase 命令有两种模式:标准模式和交互模式。
在标准模式下 git rebase 会自动将当前工作分支中的提交应用到传递分支的头部。
当前分支将重新基于 <base> 。
这可以是不同类型的提交引用,如标签、ID、分支名称等。
git rebase <base>
在交互模式下,git rebase 使用 -i 标志执行,它代表“交互”。
在交互模式下 rebase 的优点是在过程中更改单个提交,而不必将所有提交移动到新的基础。
由于这种模式,我们可以通过删除和更改现有提交序列来清理历史记录。
运行以下命令将打开一个编辑器:
git rebase --interactive <base>
在这个编辑器中,为每个必须重新定位的提交输入下面给出的命令。
在确定每次提交的命令后,Git 将开始回放提交并应用 rebase 命令。
pick 11a1456 some old commit pick a23db19 Adds new feature # Rebase 31d332c..a23db19 onto 31d332c (9 commands)# Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit
其他rebase提交
git rebase 有一些命令选项,例如:
- git rebase -- d.使用此选项将在播放期间丢弃来自最终组合提交块的提交。
- git rebase -- p,它不编辑消息或者提交的内容,在分支历史记录中保留一个单独的提交。
- git rebase -- x,它允许在播放期间在每个标记的提交上运行命令行 shell 脚本。
Git recap
交互式 rebase 的优势之一是它允许开发人员不必担心项目(item)(item)历史的混乱,因为他们可以稍后返回并清理它。
因此,许多开发人员在将其合并到主分支之前使用此工具使功能分支历史记录更清晰。
清理分支意味着删除无意义的或者死掉的提交。
因此,开发人员拥有精心规划的历史记录,并且可以轻松了解已完成的提交。
配置选项
存在一些在 git config commit 的帮助下设置的 rebase 选项。
这些选项为 git rebase 提供了另一种外观和意义。
- rebase.stat:默认情况下是一个 false 布尔值,它切换视觉 diffstat 内容的显示,显示自上次降级以来的变化。
- rebase.autoSquash:切换 --autosquash 行为的布尔值。
- rebase.missingCommitsCheck:它可以设置为多个值,改变围绕丢失提交的变基行为。
warn | 警告输出以交互模式打印并警告删除的提交。 |
---|---|
error | rebase被停止并删除了打印警告消息。 |
ignore | 默认选项忽略任何丢失的提交警告。 |
- rebase.instructionFormat:用于格式化交互式 rebase 显示的 git log 格式的字符串。
高级rebase应用程序
git rebase 可以传递给 --onto 命令行参数,在这种情况下,命令扩展为以下内容:
git rebase --onto <newbase> <oldbase>
--onto 命令提供了高级的 rebase 应用程序,因为它允许传递特定的 refs 作为 rebase 提示。
让我们通过一个例子来看看它的行为:
o---o---o---o---o master \ o---o---o---o---o featureX \ o---o---o featureY
尽管 featureY 基于 featureX,但它独立于 featureX 中的任何更改,并且可以从 master 分支。
git rebase --onto master featureX featureY
FeatureX 是 <oldbase>。
master 是 <newbase> 并且 featureY 是 <newbase> HEAD 将指向的参考。
这是输出:
o---o---o featureY / o---o---o---o---o master \ o---o---o---o---o featureX
从上游 rebase 恢复
如果另一个用户已重新定位并强制推送到我们要提交的分支,则 git pull 将使用强制推送提示覆盖我们基于先前分支所做的任何提交。
Git rebase 允许我们获取远程分支。
在那里我们可以在重新定位之前找到参考。
然后,我们可以使用 --onto 选项将分支重新设置为针对该远程引用。
rebase的危险
使用 git rebase 命令的第一个危险是它会在变基过程中导致更多的合并冲突,特别是在我们有一个持久分支偏离 master 的情况下。
迟早你可能会决定对 master 进行 rebase,它可能包含一些新的提交,你的分支的更改可能会与之冲突。
解决上述情况的方法是更频繁地针对主分支重新建立分支,并进行更多的定期提交。
为了在有冲突的情况下进行复制时推进或者重置 rebase,我们可以在 git rebase 中使用 --continue 和 --abort 参数。
另一个更严重的警告是交互式历史重写可能会丢失一些提交。
以交互模式运行 rebase 并使用一些子命令,例如 squash 或者 drop 从分支的直接日志中删除提交。
看起来好像提交被永久删除了。
解决方案是通过 git reflog 可以恢复这些提交,并且我们可以撤消整个 rebase。