重新应用通过 Github 合并和撤消的更改

Posted

技术标签:

【中文标题】重新应用通过 Github 合并和撤消的更改【英文标题】:Re-applying changes that were merged and undo'd through Github 【发布时间】:2016-12-24 08:59:22 【问题描述】:

我不小心通过 Github PR 将一个分支合并到 master。我立即恢复了它(也通过 github)。几天后,当该代码经过测试并准备好合并时,合并和 PR 实际上不会将代码放入 master,因为提交已经存在于 github 中(但代码不存在,因为它已被还原。

所以现在我正试图让这些更改恢复到主控,经过一周的不相关提交。这大致是git log --oneline 在相关点上使用一些 cmets 输出的内容:

54c73ee (HEAD, origin/master, origin/HEAD, staging) Merge pull request #637 from leonsas/last-night-view-metric-ceiling
...
More unrelated changes that should stay in.
...
af602f0 Merge pull request #639 from leonsas/staging
67ded36 (origin/staging) Merge <-- Here's where I tried merging the changes again, but it doesn't make it into the codebase.
...
Bunch of unrelated commits that should stay.
...
a603d0b Merge pull request #633 from leonsas/revert-628-hr-hrv-audit
c3da670 (origin/revert-628-hr-hrv-audit) Revert "Hr hrv audit"
01f2fab Merge pull request #632 from leonsas/revert-629-always-get-hrvz
5824fc8 (origin/revert-629-always-get-hrvz) Revert "Always get hrvz"  <-- I reverted changes, because code wasn't tested
b75a537 First iteration at setting the max value on the chart
6939035 Merge pull request #631 from leonsas/is-valid-fix
87b53d5 Merge pull request #629 from leonsas/always-get-hrvz   <-- These changes I want in
5b9a848 Merge pull request #628 from leonsas/hr-hrv-audit

将这些更改重新应用回 master 的最佳方法是什么?

-- 更新 1

根据 Thomas 的建议,我再次尝试了 rebase 解决方案:

> git checkout -b hrv-almost-latest-changes e1d0d7b
> git rebase master-clone
First, rewinding head to replay your work on top of it...
Fast-forwarded hrv-almost-latest-changes to master-clone.
> git push --set-upstream origin hrv-almost-latest-changes

但是masterhrv-almost-latest-changes 完全是最新的,所以没有什么可以在 github PR 上合并。

-- 更新 2

一般来说,樱桃采摘效果很好。具体解决办法是:

git checkout master
git checkout -b hrv-merge-fix
git cherry-pick -m 1 87b53d5
(solve conflicts)
git add <files from solved conflicts>
git cherry-pick --continue
git cherry-pick -m 1 5b9a848
git push origin hrv-merge-fix

【问题讨论】:

【参考方案1】:

我不太熟悉 github 在“幕后”做了什么,所以我会在命令行的本地存储库中继续此操作。

您应该可以使用git checkout master ; git cherry-pick -m X 87b53d5X的值参考git help cherry-pick

   -m parent-number, --mainline parent-number
       Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the
       mainline. This option specifies the parent number (starting from 1) of the mainline and allows cherry-pick to
       replay the change relative to the specified parent.

【讨论】:

似乎这样就成功了,-m 1 在解决了一些冲突之后。现在手动检查代码以确保一切都符合预期。【参考方案2】:

问题在于 PR 包含的提交已经是当前 master 的祖先:

A-    ...   -F--G--H- ... -I
 \          /   |          
  B--C--D--E    revert PR  |
             |             current master
|            merge PR
old master |
           original PR

由于 B-E 是 I 的祖先,尝试将 E 合并到 I 不会改变任何事情。

但是,您可以将 PR 分支重新定位到当前 master 上,以创建一个新的提交字符串,这些提交不是 I 的祖先,并且仍然保留这些更改:

A-    ...   -F--G--H- ... -I
 \          /               \
  B--C--D--E                 B'--C'--D'--E'
                           |              |
                           master         new PR branch

现在,将 E' 合并到 I 将应用更改。

基本上,这样做:

$ git fetch
$ git checkout E
$ git checkout -b new-pr-branch
$ git rebase master
$ git push --set-upstream origin new-pr-branch

然后从new-pr-branch 提交新的 PR。

【讨论】:

我实际上已经尝试过,只是再次尝试,但没有成功。有关详细信息,请参阅问题更新。 @leonsas:我在你的历史上没有看到 e1d0d7b。您能否将git log --oneline --graph --all --decorate 的相关输出粘贴为gist? 对了,e1d0d7b 是合并提交之前的最新提交。我将再次尝试合并提交 (87b53d5)。 从 87b53d5 执行它有同样的问题(即使使用 master 也有分支)。有关git log 的输出,请参阅此要点:gist.github.com/leonsas/d57a9c832d2543089d5d7d518804ac06 试过这个,当比较Emaster时,它在GitHub上说There isn’t anything to compare.

以上是关于重新应用通过 Github 合并和撤消的更改的主要内容,如果未能解决你的问题,请参考以下文章

撤消 Git 分支提交和合并

通过拉取请求撤消合并?

如何撤消 git flow 功能完成?

撤消 git 自动合并

如何撤消放弃 GitHub Desktop 中的更改?

当我使用 Git 时,我应该在合并之前重新设置基准吗?