Rebasing remote branches in Git

我使用一个中间的 Git 存储库来镜像一个远程 SVN 存储库,人们可以从中克隆和处理这个存储库。中间存储库的主分支每晚都从上游 SVN 重新定位,我们正在处理特性分支。例如:

remote:
master


local:
master
feature

我可以成功地将我的特性分支推回到遥控器,并以我所期望的结果结束:

remote:
master
feature


local:
master
feature

然后,我重新设置分支来跟踪远程:

remote:
master
feature


local:
master
feature -> origin/feature

一切都很好。我想从这里做的是将特性分支重新基于远程的主分支,但是我想在本地机器上完成这项工作。我希望能够做到:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

使远程特性分支与远程主机保持最新。然而,这种方法导致 Git 抱怨:

To <remote>
! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pull可以做到这一点,但会导致合并提交,这是我希望避免的。我关心的是,消息指定的是 feature -> feature而不是 feature -> origin/feature,但这可能只是一个演示的事情。

我是不是错过了什么,或者我的方式完全错了?避免在远程服务器上执行 rebase 并不重要,但是这会使修复 rebase 中的任何合并冲突变得更加困难。

208452 次浏览

您可以通过使用 git push--force选项来禁用检查(如果您确实知道自己在做什么的话)。

因为您在新的 master上重新定位了 feature,所以您的本地 feature不再是 origin/feature的快进。因此,我认为,在这种情况下,通过执行 git push origin +feature来覆盖快进检查是完全可行的。您还可以在配置中指定此项

git config remote.origin.push +refs/heads/feature:refs/heads/feature

如果其他人在 origin/feature之上工作,他们将被这个强制更新所打扰。您可以通过将新的 master合并到 feature而不是重新定基来避免这种情况。结果确实是一个快进。

归根结底,这个特性是由一个人使用,还是由其他人使用。

如果只有你一个人的话,你可以在重新定位之后强制推动:

git push origin feature -f

但是,如果其他人正在处理它,则应该进行合并,而不要将 master 重新定位。

git merge master
git push origin feature

这将确保你与你的合作伙伴有一个共同的历史。

在另一个层面上,您不应该进行反向合并。您所做的是用其他不属于特性的提交来污染特性分支的历史记录,使得后续处理该分支的工作变得更加困难——重定基与否。

这是我关于 每个特征分支每个特征分支的文章。

希望这个能帮上忙。

很高兴你提起这个话题。

这是 Git 中的一个重要概念,很多 Git 用户都会从中受益。Git rebase 是一个非常强大的工具,可以让你压缩提交,删除提交等。但是就像任何强大的工具一样,你基本上需要知道你在做什么,否则可能会出大问题。

当您在本地工作并使用本地分支时,只要您没有将更改推送到中央存储库,就可以做任何您喜欢的事情。这意味着你可以改写自己的历史,而不是其他人的历史。只是随意处理本地的东西,什么都不会对其他存储库产生任何影响。

这就是为什么一定要记住,一旦你推送了提交,你就不应该在以后重新建立它们的基础。这一点之所以重要,是因为其他人可能会接受你的提交,并将他们的工作建立在你对代码库的贡献之上,如果你后来决定将内容从一个地方移动到另一个地方(重新建立基础)并推动这些更改,那么其他人就会遇到问题,不得不重新建立他们的代码基础。现在想象你有1000个开发人员:)这只会导致许多不必要的返工。

我不熟悉使用 GitBash,我在这里使用 TortoiseGit (新手用的 GUI)为那些使用 Windows 的开发者添加一个答案:

Force re-basing remote branch with local branch using TortoiseGit

像上面提到的许多方法一样,如果只使用您的“私有”回购分支,那就意味着没有人会因为您使用本地副本重建远程“开发”或“功能”分支的基础而向您扔椅子。其他已经承诺并推动他们一周(或更多)工作的开发人员将从分支的历史(日志)中删除。

没有办法恢复它们——当然,你的合作开发人员仍然有他们的更改,因为他们的 PULL 很可能抛出一个错误,因为他们将远远超过分支当前的历史或最新提交与他们的提交。好消息是 Git 是一个分布式版本控制系统。

因此,小心使用这个恢复远程分支的权力。特此警告。 ;)

如果你和其他人一起工作在一个特性分支上,那么很可能他们已经提交了一些东西。从那时起,您就不能简单地推送您的更改,因为它们与提交历史冲突。您可以调用 git pull,它是一个 git 提取 + git 合并命令。这将为合并创建另一个提交。

我会尽量避免不必要的合并提交在您的历史,并保持您的 git 提交历史干净,只需调用 git pull --rebase。这将把您的提交放在现有提交之后。

当然,您应该只添加本地分支的 git 历史记录,永远不要更改远程分支的 git 历史记录。