【问题标题】:Is there some kind of 'git rebase --dry-run', which would notify me of conflicts in advance?是否有某种“git rebase --dry-run”可以提前通知我冲突?
【发布时间】:2015-06-13 13:49:12
【问题描述】:

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

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

【问题讨论】:

  • 您使用的git rebase 命令的确切形式是什么?您是否使用任何可选标志?您使用的是什么脚本语言?壳牌?
  • 如果您运行git rebase 并遇到合并冲突,该进程将停止并以非零状态退出。您可以检查 rebase 操作的退出状态,如果它不为零,则运行 git rebase --abort 以取消操作。
  • 你找到方法了吗?
  • @crmpicco 我基本上按照 Jubobs 的建议进行了 rebase,检查冲突,并在需要时中止。但我希望有一种更优雅的方式......
  • 对于杂乱无章的rebase,我经常创建一个新分支并先在那里进行试运行。如果一切顺利,试运行成为rebase,否则直接切换回原来的分支。

标签: git git-rebase git-merge-conflict


【解决方案1】:

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

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

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

如果变基成功但你意识到你想撤销它,你可以运行

git reset --hard ORIG_HEAD

【讨论】:

  • 如果rebase成功了,但我意识到我想回去怎么办?例如,因为我不想强制推送。
  • @bluenote10 您可以使用分支的reflog 将其重置为用于指向rebase 之前的提交。
  • @bluenote10 或者如果你知道无论如何你都想丢弃 rebase 结果,你可以从一个分离的头开始:git checkout --detach foo。
  • 您也可以使用git reset --hard ORIG_HEAD 将分支移回变基之前的位置。
【解决方案2】:

如果您只是想看看变基是否会成功,但又想“回滚”,您总是可以reposition the branch tip 回到原来的提交。 只需标记或记下原始 SHA。

或者更简单,创建一个新的临时分支来“暂存”rebase:

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

如果它成功但你想“回滚”,your-branch 是不变的。只需git branch -D tmp,您就会回到起点。

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

【讨论】:

  • 一个命令代替前两个:git checkout -b tmp your-branch
【解决方案3】:

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

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

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

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

【讨论】:

    【解决方案4】:

    您仍然可以执行 git rebase,随心所欲地使用它,而不是恢复之前的所有更改。 假设您已将某个分支重新设置为 master,但您不喜欢它:

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

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

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

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

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

    【讨论】:

      【解决方案5】:

      以@joneit 的解决方案为基础:

      从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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-16
        • 1970-01-01
        相关资源
        最近更新 更多