如何将分支与部分重新定位并强制推送的主分支合并?
How to merge a branch with a master which was partially rebased and force pushed?
最初,我需要从 master 恢复一些提交,包括合并的拉取请求。我们称它为 'unwanted refactoring'.
但将来需要进行这些更改。
我根据 master 的当前状态创建了一个新分支 develop 以在那里进行这些更改。
我决定将 master 硬重置为拉取请求合并的父提交(这是 repo 的稳定状态):
git reset --hard ad23b887
然后,选择其他不是 'unwanted refactoring':
的提交
git cherry-pick
现在我想执行强制推送命令,它应该覆盖 origin/master 分支历史记录。
以后需要从develop合并'unwanted refactoring'到master,到时候100%测试。但是,如果实际上这两个分支有不同的历史(因为挑选和重置 HEAD),我应该如何合并这两个分支?
通过重置 HEAD 并在我的情况下只挑选我需要的那些来恢复提交是正确的方法吗?
P.s。我的团队由两个人组成,我认为进行此类操作没有任何问题。
让我们想象一下。
Initially, I needed to revert some commits from master including merged pull request...
A - B - C --------- M [master]
\ /
F - G - H - I
I created a new branch develop based on the current state of master to have these changes there.
[develop]
A - B - C --------- M [master]
\ /
F - G - H - I
I decided to do a hard reset of master to the parent commit of pull request merge (It was stable state of repo): git reset --hard ad23b887
假设 ad23b887 是提交 B。
A - B [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
这是同一张图,只是稍微移动了一点,以便我们可以与 master 一起工作。
And then, to pick other commits which are not 'unwanted refactoring': git cherry-pick
假设是 G 和 I。
A - B - G1 - I1 [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
Now I want to do a force push command, which should overwrite the origin/master branch history.
是的,但使用 git push --force-with-lease
。这样更安全。我有它的别名 repush。
In the future, I will need to merge 'unwanted refactoring' back to master from develop when it will be 100% tested. But how, then, should I merge these two branches, if, in fact, they have different histories (because of cherry-picks and resetting a HEAD) ?
Rebase 在 master 之上开发。这将在 master 之上重放 develop 的提交。合并将消失。您从中挑选的现在冗余的提交也是如此,因为 develop 现在已经有了来自 master 的那些更改。
A - B - G1 - I1 [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
$ git checkout develop
$ git rebase master
A - B - G1 - I1 [master]
\
C - F - H [develop]
现在您可以通过正常的 PR 流程合并开发。
A - B - G1 - I1 -------- M1 [master]
\ /
C - F - H
Is it the right way to revert commits with resetting a HEAD and cherry-picking only ones I need in my situation?
让我们回到你摘樱桃之前。
避免像 develop 这样的通用分支。给它起一个与你正在做的事情相关的名字。一个不错的选择是在您的问题跟踪器中使用 ID,这会鼓励每个分支机构都提出问题。
A - B [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
我建议永远不要直接提交到 master,而是总是使用 feature branches。这确保每个更改都经过审查、QA 等 PR 过程。这意味着 master 在上面工作总是稳定的。
为此,创建一个新分支以合并 cherry picks。
$ git checkout -b issue/#abcd
$ git cherry-pick G I
G1 - I1 [issue/#abcd]
/
A - B [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
他们通过正常的 PR 流程将其合并。
G1 - I1
/ \
A - B ------- N [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
现在 rebase issue/#1234 在 master 之上。
G1 - I1
/ \
A - B ------- N [master]
\
C - F - H [issue/#1234]
并通过正常的 PR 流程合并 issue/#1234。
G1 - I1
/ \
A - B ------- N --------- M1 [master]
\ /
C - F - H
历史上的那些颠簸被称为“功能泡沫”,它们就是您想要看到的。它们有助于使历史易于遵循,并使掌握稳定。
最初,我需要从 master 恢复一些提交,包括合并的拉取请求。我们称它为 'unwanted refactoring'.
但将来需要进行这些更改。
我根据 master 的当前状态创建了一个新分支 develop 以在那里进行这些更改。
我决定将 master 硬重置为拉取请求合并的父提交(这是 repo 的稳定状态):
git reset --hard ad23b887
然后,选择其他不是 'unwanted refactoring':
的提交git cherry-pick
现在我想执行强制推送命令,它应该覆盖 origin/master 分支历史记录。
以后需要从develop合并'unwanted refactoring'到master,到时候100%测试。但是,如果实际上这两个分支有不同的历史(因为挑选和重置 HEAD),我应该如何合并这两个分支?
通过重置 HEAD 并在我的情况下只挑选我需要的那些来恢复提交是正确的方法吗?
P.s。我的团队由两个人组成,我认为进行此类操作没有任何问题。
让我们想象一下。
Initially, I needed to revert some commits from master including merged pull request...
A - B - C --------- M [master]
\ /
F - G - H - I
I created a new branch develop based on the current state of master to have these changes there.
[develop]
A - B - C --------- M [master]
\ /
F - G - H - I
I decided to do a hard reset of master to the parent commit of pull request merge (It was stable state of repo):
git reset --hard ad23b887
假设 ad23b887 是提交 B。
A - B [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
这是同一张图,只是稍微移动了一点,以便我们可以与 master 一起工作。
And then, to pick other commits which are not 'unwanted refactoring':
git cherry-pick
假设是 G 和 I。
A - B - G1 - I1 [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
Now I want to do a force push command, which should overwrite the origin/master branch history.
是的,但使用 git push --force-with-lease
。这样更安全。我有它的别名 repush。
In the future, I will need to merge 'unwanted refactoring' back to master from develop when it will be 100% tested. But how, then, should I merge these two branches, if, in fact, they have different histories (because of cherry-picks and resetting a HEAD) ?
Rebase 在 master 之上开发。这将在 master 之上重放 develop 的提交。合并将消失。您从中挑选的现在冗余的提交也是如此,因为 develop 现在已经有了来自 master 的那些更改。
A - B - G1 - I1 [master]
|\
| C ----------- M [develop]
\ /
F - G - H - I
$ git checkout develop
$ git rebase master
A - B - G1 - I1 [master]
\
C - F - H [develop]
现在您可以通过正常的 PR 流程合并开发。
A - B - G1 - I1 -------- M1 [master]
\ /
C - F - H
Is it the right way to revert commits with resetting a HEAD and cherry-picking only ones I need in my situation?
让我们回到你摘樱桃之前。
避免像 develop 这样的通用分支。给它起一个与你正在做的事情相关的名字。一个不错的选择是在您的问题跟踪器中使用 ID,这会鼓励每个分支机构都提出问题。
A - B [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
我建议永远不要直接提交到 master,而是总是使用 feature branches。这确保每个更改都经过审查、QA 等 PR 过程。这意味着 master 在上面工作总是稳定的。
为此,创建一个新分支以合并 cherry picks。
$ git checkout -b issue/#abcd
$ git cherry-pick G I
G1 - I1 [issue/#abcd]
/
A - B [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
他们通过正常的 PR 流程将其合并。
G1 - I1
/ \
A - B ------- N [master]
|\
| C ----------- M [issue/#1234]
\ /
F - G - H - I
现在 rebase issue/#1234 在 master 之上。
G1 - I1
/ \
A - B ------- N [master]
\
C - F - H [issue/#1234]
并通过正常的 PR 流程合并 issue/#1234。
G1 - I1
/ \
A - B ------- N --------- M1 [master]
\ /
C - F - H
历史上的那些颠簸被称为“功能泡沫”,它们就是您想要看到的。它们有助于使历史易于遵循,并使掌握稳定。