git rebase --strategy=我们的用例澄清

标签 git rebase

我维护一个分支,其中所有更改都位于我编写的上游存储库之上,以便可以任意重新应用它们。为了引入上游存储库的更改,我想重新设置基准,并且在发生任何冲突的情况下,完全丢弃我的文件并使用上游的版本,因为我可以重新应用任何必要的内容。

根据git文档,我想我想要 git rebase -s ours upstream/master

如果我查看 strategy-option 的文档对于 ours

This should not be confused with the ours merge strategy, which does not even look at what the other tree contains at all. It discards everything the other tree did, declaring our history contains all that happened in it.

这听起来正是我想要的,假设 ours/theirs翻转在这里仍然适用。

ours 的文档策略似乎证实了:

This resolves any number of heads, but the resulting tree of the merge is always that of the current branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede old development history of side branches

但是,当我查看文档 --strategy 时:

Because git rebase replays each commit from the working branch on top of the <upstream> branch using the given strategy, using the ours strategy simply empties all patches from the <branch>, which makes little sense.

我不确定我是否完全理解它的含义 empties all patches

这只是说这对大多数人来说毫无意义,只是因为它会放弃他们自己所做的更改?

当使用git rebase -s ours时,ours还是引用上游分支?

最佳答案

tl;dr:没有一种内置方法可以完全执行您想要的操作,并且 git rebase -s ours是一个毫无意义的选择。

长篇故事

merge 策略-s ours基本上 merge 到提交中,而不进行任何更改。如果您想让旧的历史分支可以从另一个分支访问,而不实际引入更改,则可以使用它。一个可能的用例是,当您希望部分 merge 分支的较新部分,而不 merge 同一分支历史记录中的一些较旧提交时。您可以使用git merge -s ours <top-commit-to-ignore> ,然后 merge 到分支中,以便仅在忽略的提交之后为后面的一组提交引入更改。 (不过,这很可能会发生冲突,除非较新的提交与被忽略的提交很好地隔离。)

使用 -s ours 没有意义的原因进行 rebase ,是因为-s ours基本上只是 merge 提交 ID 本身,并且使用 rebase 重写提交 ID,因此没有要保留的提交 ID。本质上,您将对目标提交进行硬重置,然后跳过所有提交的 rebase ,这意味着最终结果相当于首先进行硬重置。例如:

git rebase -s ours main

# is the same as
git reset --hard main

唯一的区别是 rebase 将比重置花费更长的时间,并且当它迭代将删除的所有提交时,您会看到一堆消息说“正在删除...”。 (顺便说一句,这就是“清空所有补丁”的含义。)这就是文档声明使用 -s ours 的原因。与 rebase “没有什么意义”。

文档怎么样?

恕我直言,您偶然发现了 Git 文档中最令人困惑的部分之一,原因是(我认为)因为很难注意到“我们的”和“他们的”选项与“ort” merge 策略。这是因为“我们的”和“他们的”是 -s ort 的附加选项。策略,如果不指定则为默认策略。这些选项实际上是通过 -X ours 传递的。或-X theirsours下的文字:

This should not be confused with the ours merge strategy...

另一种说法是:

Right now you are currently reading about the -X ours strategy, which should not be confused with the -s ours merge strategy which is something completely different.

旁注:没有等效的-s theirs merge 策略。

你能做什么?

不幸的是,你不能完全做你想做的事:

In order to pull in the upstream repo's changes, I want to rebase, and in the case of any conflict, completely discard my file and use the upstream's version since I can just re-apply whatever necessary.

但可能与-X ours有冲突解决会让你接近吗?这里最大的区别是-X冲突解决方案仅在发生冲突的 block 上选择“我们的”(上游)或“他们的”(您的分支),而不是整个文件。所以当你使用git rebase -Xours时,如果您在文件中的某些更改可以干净地 merge ,但同一个文件在文件的不同部分存在冲突,则您的更改将在可能的情况下被 merge ,并且上游的更改将在冲突的 block 中被选择。你说你的愿望是“完全丢弃我的文件”,但事实并非如此。话虽这么说,如果您计划“重新应用必要的内容”,这将使您更接近该目标。

旁注:如果阅读完上面的段落后,您想知道为什么“我们的”和“他们的”在 rebase 时会出现翻转,see this question .

关于git rebase --strategy=我们的用例澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76102813/

相关文章:

git - 间歇性 git 错误 : "Cannot rebase: You have unstaged changes."

git - 如何向后 rebase ,最好不使用 diff/apply?

eclipse - 如何使用 GitHub 设置 Eclipse/EGit?

git - 如何防止 merge 的更改显示为 'changes to be committed'

git pull --rebase : passing --rebase-merges

git - ssh -vT git@github.com kex_exchange_identification : Connection closed by remote host

git - 如何 git backport (rebase/cherry-pick) 一个已经 merge 的分支

git - 如何绕过 : remote: GitLab: Author <non-member-email-here> is not a member of team?

git - 如何选择包含端点的 git commit 范围

git - 为什么我不能将镜像推送到 github?