是否有某种'git rebase --dry-run',可以提前通知我冲突?

Is there some kind of 'git rebase --dry-run', which would notify me of conflicts in advance?

我正在尝试编写变基脚本,我的脚本将采用不同的路径,具体取决于变基是否会导致任何冲突。

有没有办法在执行变基之前确定变基是否会导致冲突?

在撰写本文时(Git v2.6.1 v2.10.0),git rebase 命令不提供 --dry-run 选项。在实际尝试变基之前,无法知道您是否会 运行 陷入冲突。

但是,如果您 运行 git rebase 遇到冲突,进程将停止并以非零状态退出。你可以做的是检查变基操作的退出状态,如果它是非零的,运行 git rebase --abort 取消变基:

git rebase ... || git rebase --abort

如果 rebase 成功但您意识到要撤消它怎么办,您可以 运行

git reset --hard ORIG_HEAD

我怀疑 git rebase ... --dry-run 不可能,原因如下。

当您执行 git rebase 时,git 将回滚到起点,然后为每个提交增量应用补丁以使分支保持最新。如果遇到冲突,它将停止并等待您解决冲突,然后再继续。冲突后 rebase 采取的路径取决于您如何解决冲突 - 如果您以某种方式解决它,那可能会引入(或消除)以后的冲突。

因此,git rebase ... --dry-run 只能为您提供 第一个 冲突 - 后续冲突的报告将取决于第一个冲突的解决方式。

我能想到的唯一方法是通过 git diff 在当前位置和您要变基到的分支中的最后一次提交之间。但这并不能真正为您提供所需的东西 - 您实际上只需要两点之间的 冲突 更改列表。 可能 可以用 git diff 来实现,但这不是一个普通的补丁。

你仍然可以做 git rebase,随心所欲地使用它,而不是恢复之前的所有更改。 假设您已经将某个分支的 rebase 变基到 master,但您不喜欢它:

  1. git reflog -20 - 为您提供 HEAD 的最后 20 个位置以及一些描述
  2. git checkout <the_branch_name> - 把你的头放在树枝上
  3. git reset --hard <old_sha1_found_in_reflog> - 将你的 HEAD 和分支放在旧的 ref 上,这样你就可以恢复旧的分支。

这里有一些机制需要理解:

  1. 您永远不会删除 git 中的任何内容,无论如何都不能使用命令。它的垃圾收集器通过并删除未引用的分支(默认 3 个月)。所以你的分支,在 rebase 之前,仍然存在。
  2. 同一个分支上的 rebase 也是如此,它只是在旧树旁边重写的新树。
  3. 所有 rebase 和你的其他关于 HEAD 操作的历史都写在 reflog
  4. 您可以使用来自 reflog
  5. @{N} 注释

所以,rebase 之后什么都不会丢失,您只需要知道如何找到并恢复它。

例如,您可以在 rebase 之前放置一个标签,而不是还原或删除它。它避开了所有 SHA1 研究步骤。

如果你只是想看看变基 是否会 成功,但你又想 "roll back," 你总是可以 reposition the branch tip回到原始提交。 只需标记或记下原始 SHA。

或者可能更简单,创建一个新的临时分支,在其中 "stage" 变基:

git checkout your-branch
git checkout -b tmp
git rebase other-branch

如果成功了但是你想"roll back," your-branch保持不变。只需 git branch -D tmp 即可回到起点。

如果存在冲突并且您做了一些工作来解决它们并且您现在想要保留变基,只需将您的分支提示重新定位到 tmp(然后是 git branch -D tmp)。

基于的解决方案:

your-branch 创建一个新的 temp 分支并尝试将该临时分支变基到 new-base:

git checkout -b temp <your-branch> && git rebase <new-base>

例如测试分支 feature1 是否可以变基到 master:

git checkout -b temp feature1 && git rebase master