是否存在某种"git rebase --dry-run",它会提前通知我冲突?

Jon*_*ink 61 git git-rebase git-merge-conflict

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

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

jub*_*0bs 38

在撰写本文时(Git V2.6.1v2.10.0),该git rebase命令不提供任何--dry-run选项.在实际尝试改变之前,无法知道你是否会遇到冲突.

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

git rebase ... || git rebase --abort
Run Code Online (Sandbox Code Playgroud)

  • 如果rebase成功了怎么办,但我意识到我想回去?例如,因为我不想强迫推. (8认同)
  • 您还可以使用“git reset --hard ORIG_HEAD”将分支移回变基之前的位置。 (3认同)
  • @ bluenote10您可以使用分支的[reflog](https://git-scm.com/docs/git-reflog)将其重置为用于指向rebase之前的提交. (2认同)
  • @bluenote10 或者,如果你知道无论如何你都想丢弃 rebase 结果,你可以从一个分离的头开始:`git checkout --detach foo`。 (2认同)
  • 请注意,有时,“ORIG_HEAD”不会指向变基之前分支尖端的位置。如果您在 rebase 期间使用 ` git reset` ,例如分割提交(从 Git 2.39 开始),则可能会发生这种情况([请参阅错误报告](https://lore.kernel.org/git/ef389a14-8513- 4650-21e4-89421a24df2d@gmail.com/T/#t))。更安全的选择是` git reset --hard @{1}` (2认同)

小智 25

如果你只是想看看rebase 是否会成功但是你想要"回滚",你可以将分支提示重新定位回原始提交.只需标记或记下原始SHA.

或者更简单,创建一个新的临时分支,在其中"分阶段"rebase:

git checkout your-branch
git checkout -b tmp
git rebase other-branch
Run Code Online (Sandbox Code Playgroud)

如果它成功但你想"回滚",your-branch则不受影响.只是git branch -D tmp,你回到了你的起点.

如果存在冲突并且你做了一些工作来解决它们,你现在想要保留rebase,只需将你的分支尖端重新定位到tmp(然后git branch -D tmp).

  • 用一个命令代替前两个:`git checkout -b tmp your-branch` (7认同)

Kry*_*ten 7

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

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

因此,git rebase ... --dry-run只能给你第一次冲突 - 后来冲突的报告将取决于第一次冲突的解决方式.

我能想到这样做的唯一方法是git diff在当前位置和你要重新定位的分支中的最后一次提交之间.但这并不能真正满足您的需求 - 您真的需要一个两点之间相互冲突的变化列表.有可能是一个办法做到这一点的git diff,但它不是一个正常的补丁.


小智 5

您仍然可以执行 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. 您可以使用@{N}注释来自reflog

因此,在 之后不会丢失任何东西rebase,您只需要知道如何找到并恢复它。

例如,您可以在 之前放置一个标签,然后rebase恢复或删除它。它避开了您所有的 SHA1 研究步骤。


isa*_*pir 5

基于@joneit的解决方案:

创建一个新temp分支your-branch并尝试将该临时分支重新设置为new-base

git checkout -b temp <your-branch> && git rebase <new-base>
Run Code Online (Sandbox Code Playgroud)

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

git checkout -b temp feature1 && git rebase master
Run Code Online (Sandbox Code Playgroud)