git 可以告诉我在没有实际变基的情况下变基是否会发生冲突吗?

Can git tell me if a rebase will conflict without actually rebasing?

我想以编程方式确定如果我尝试对它们进行变基,我的功能分支会发生变基冲突。有没有办法让我 git 在不实际执行变基的情况下告诉我这些信息?

否则,在 git rebase --aborting 之前检测变基是否失败的最简单方法是什么?

我的问题与这两个类似,它们是相同的,但用于合并而不是 rebase

您可以使用自定义预变基挂钩在变基开始之前执行您需要的任何检查。这里有一个示例 pre-rebase 挂钩:https://github.com/git/git/blob/master/templates/hooks--pre-rebase.sample

在 pre-rebase 钩子代码中,您可以 diff 更改的文件并检查冲突并停止 rebase。

Is there a way I can get git to tell me this information without actually performing the rebase?

简短的回答是 "no"。长答案更长,但以 "no" 结尾 :-) ...您可以通过编写大量代码来获得非常接近的答案,但要获得完整的正确答案,您必须执行 rebase 的所有提交复制步骤,在这一点上你还不如 ​​运行 变基。

Failing that, what is the simplest way to detect if a rebase failed before git rebase --aborting it?

git rebase 命令 returns 如果 rebase 成功完成则为成功(零)退出代码,否则为失败(非零)退出代码。在 shell 脚本中,您可以只使用 git rebase $args || git rebase --abort.

Failing that, what is the simplest way to detect if a rebase failed before git rebase --aborting it?

git rebase returns 失败时的虚假状态,所以你可以做类似

git rebase feature && echo "Success" || echo "fail" && git rebase --abort

但是,这将在成功时执行实际的变基。 如果你想 test 如果 rebase would 成功而不实际执行它,恐怕我唯一的想法是检查另一个分支,检查如果变基成功并切换回来,例如:

branch=$(git branch | grep '* .*' | sed s/..//); git checkout -b $branch-rebase > /dev/null ; git rebase test-2 > /dev/null && result="Success" || result="fail" ; git rebase --abort ; git checkout $branch ; git branch -D $branch-rebase ; echo $result

我先把当前分支记在一个变量里(如果谁有更好的判断当前分支的方案告诉我),切换到branchname-rebase,执行在回显结果之前,重新设置基准,检查原始分支并删除测试分支。 Hacky,但根据您的用例,这可能有效。

最接近 "dry run" 变基的是 运行 从分离的 HEAD 状态变基(因此实际上没有修改任何引用)。所以而不是

git rebase develop feature_X

你可能会

git rebase develop `git rev-parse feature_x`

并检查退出状态。这种方法的问题是:

1) 很费时间。基本上对于 冲突的任何分支,整个变基将 运行。 (而且很难想象你怎么能做更少的工作并且仍然准确地知道 rebase 是否会成功。)

2) 它会创建冗余对象(悬空提交及其依赖项),这些对象不会 可见 但仍然会在本地占用 space回购,直到您将悬空提交从 reflog 和 运行 gc 中删除,或者创建一个新的克隆。如果你经常这样做,浪费的 space 真的会加起来。

我也不确定这有多少实用性。仅仅因为 feature_Xfeature_Y 都会完全变基到 develop,并不意味着 "rebase featureX then rebase featureY" 的序列一定会完全完成。虽然看起来不应该是这种情况,但在我最近看到的一些事情之后,我不会惊讶地了解到一些边缘情况,其中 rebases 的顺序决定是否存在冲突。

所以您最多只能得到 "low hanging fruit" - "I know for a fact these have conflicts"。但是,嘿,你知道,如果那是你需要的代码,那就是你需要的代码。

基于,您可以扩展他的第一个命令以在成功的情况下恢复:

git rebase master && (echo "Success" && git reset --hard ORIG_HEAD) || (echo "Fail" && git rebase --abort)

这仍将 运行 变基,但是如果成功,将您的 HEAD 重置为变基前的旧 HEAD。生成的提交和 reflog 的更改将保留,只有您的分支的引用被重置。

您可能想要为命令的输出添加重定向以避免不需要的输出。这样做时请记住,由于合并冲突以外的其他情况,变基可能会失败,例如工作目录中未暂存的更改。