Git 如何绕过上游分支的推力?

Git 如何绕过上游分支的推力?,git,git-rebase,git-push,git-rewrite-history,Git,Git Rebase,Git Push,Git Rewrite History,我有一个功能分支branchX,它使用某个远程/基本分支作为其上游分支。我刚刚发现,某个远程/基本分支的历史记录被强制推写。所涉及的问题是什么?我如何解决它?这带来的最大问题是,您应该删除从旧上游分支重写的修订,以便在推送功能分支时,它们不再存在 如果您尝试在新分支上重新设置分支的基础(例如,git checkout branchX;git fetch some remote;git rebase some remote/base branch),git不仅会重新设置功能分支修订版的基础,还会重

我有一个功能分支
branchX
,它使用
某个远程/基本分支
作为其上游分支。我刚刚发现,
某个远程/基本分支
的历史记录被强制推写。所涉及的问题是什么?我如何解决它?

这带来的最大问题是,您应该删除从旧上游分支重写的修订,以便在推送功能分支时,它们不再存在

如果您尝试在新分支上重新设置分支的基础(例如,
git checkout branchX;git fetch some remote;git rebase some remote/base branch
),git不仅会重新设置功能分支修订版的基础,还会重新设置已经移出新重写分支的修订版的基础。。。这是一个禁忌。如果合并也是一样的。因此,一个简单的
git pull
(合并或重定基址)无法让您摆脱困境。。。实际上,你很可能会把自己陷得更深

如果您决定保留它们,就好像什么都没发生一样,那么您将进入新上游分支的历史记录,这些修订已经从中删除,而且很可能没有必要保留它们(因为……为什么分支机构的历史一开始就被重写了,对吗?如果它被重写了,那些旧的修订就再也看不见了)

这似乎是一件大事,但坦率地说,摆脱这种情况并不难。诀窍是只将功能分支的修订移到新重写的分支之上,而留下旧分支。因此,这是一个过程,假设功能分支是一条没有mer的直线ges:

誓言 在功能分支的历史记录中(例如,使用
git log
gitk
或任何其他必要的方法)查找功能分支中的old上游分支的最后一个修订。假设您获得了该修订的ID,我们将其称为
old base rev

从远程获取以获取上游分支的新重写历史记录

git fetch some-remote # adjust to the name of your remote, of course
转折点 这就是神奇发生的地方:

git rebase --onto some-remote/base-branch old-base-rev branchX
这样,git将只对实际上构成要素分支本身工作的修订进行重新基础化,而不是旧的上游分支

git fetch some-remote # adjust to the name of your remote, of course
威望 就这样,你可以继续在你的分支上工作,就好像什么都没发生一样

其他可能性 如果您处理的要素分支不是直的(它合并了上游分支,而不是重新定基),您可以使用我提供的相同方法,但是,如果您在合并上游分支时必须解决冲突,这将是一个棘手的问题。如果您希望避免再次处理冲突,那么您可以尝试的最好方法是将您对功能分支所做的更改合并到单个修订中,然后尝试魔术查找要素分支中旧基础分支的最后一个ID:

git reset --soft old-base-rev
git commit -m "Single revision for feature X"
现在,您的所有更改都已折叠为一个单独的修订版,位于
旧的基本修订版
之上。然后,您可以按照配方执行获取/重新设置基础步骤

git fetch some-remote
git rebase --onto some-remote/base-branch old-base-rev branchX

当您有一个构建在另一个功能分支之上的功能分支时,这种技巧也很有用。您用作基础的功能分支可能会被重定基础/重写/重生/诸如此类,因此在移动分支时,您不希望移动不属于您的功能分支的修订。