同事将更改提交到错误的分支并推送到远程存储库。这怎么能解决?

A coworker commited changes to the wrong branch and pushed to the remote repository. How can this be fixed?

我们正在开发一个具有双分支系统 (default/stable) 的项目并使用远程存储库。一位同事在错误的稳定分支上实现了一项新功能,并将更改推送到远程存储库。应该对默认分支进行更改。

理想情况下,我希望最终将更改移至默认分支,而不指示在稳定分支上提交。我们是不是有点搞砸了,因为它已经被推送了?

我克隆了 repo 并尝试回滚本地副本,但这并没有达到我预期的效果。我尝试使用 rebase 扩展,但我没有看到将提交移动到另一个分支的方法。我尝试了退出选项,但留下了我不想要的历史记录。

我想我可以通过以下方式手动完成此操作:

  1. 制作更改文件的副本
  2. 从本地和远程副本中剥离变更集
  3. 更新到默认分支
  4. 将更改的文件带回项目
  5. 在本地提交更改
  6. 将更改推送回远程仓库

这是唯一的方法吗?

我首先 graft(参见 hg help graft)或 rebase --keep(参见 hg help rebase,您可能需要打开 rebase 扩展)稳定版的更改默认,然后退出(参见 hg help backout)来自稳定分支的更改。完成所有变基和退出后,推送到您的团队使用的远程存储库。

由于已经推送了错误的更改,并且无法修改远程仓库上的历史记录,因此您必须添加一个完全逆转错误更改的影响的更改集 (backout)。历史记录仍将包含错误提交及其在 stable 中的逆向提交,因此任何根据 stable 检查他们的回购协议的人都会看到他们需要拉取更新。除非您删除错误的变更集,否则无法避免这种情况。 只要错误提交中没有秘密(我不认为会有任何秘密,如果它属于 default),也许这没什么大不了的。

编辑: 正如 Mark Tolonen 指出的那样,如果更改已经推送(到 "publishing" 回购),则以下内容将不起作用。 所以对OP没用

如果您使用 commit --amend 提交回退变更集,您几乎可以不留痕迹;它会将撤销合并到错误的变更集中,留下一个没有文件更改的修改后的变更集:

hg update -r oops
hg backout oops
<exit the editor without creating a commit message; commit is aborted>
hg commit --amend -m "Nothing to see here, folks"

历史记录中将不再显示错误的变更集:

% hg log -l 1
changeset:   4:969068ca0049
tag:         tip
summary:     Nothing to see here, folks
% hg diff -r tip
%

如果我没记错的话,原始变更集对于使用 mercurial 客户端太旧以至于不支持修改后的提交的用户仍然可见。

上面没有涉及将变更集移动到正确的位置,但我相信你知道如何做到这一点(例如,graft)。

如果更改是 public,删除所有跟踪的唯一方法是删除 public 存储库和所有克隆的更改。那可能不切实际。

要撤消更改,您需要将变更集移植回默认值,并将变更集从稳定版中撤消:

示例,当前状态:

命令:

hg update default
hg graft 3
hg update stable
hg backout 3

结果: