如何 "force" 来自特定提交的拉取请求?
How to "force" a pull request from a specific commit?
场景如下:
- 我们有大约 10 个提交要从我们的 master 分支中恢复。它们引起了某种问题,我需要恢复到特定的提交
123abc
;
我们在这里尝试了一些东西:
我们创建了一个名为 feature/something
的新分支,以便还原提交并对主分支执行 pull request
。但是,VSTS 抱怨我们没有新的更改。
当我们 git reset --hard 123abc
进入 master
分支时,我的本地 space 恢复为给定的提交,到目前为止没问题。但是,我没有权限 force 推送到 master 分支。
所以,我的问题是:
关于第一次尝试,如何让git理解我想将这些更改拉到主分支并且不抱怨?
关于第二次尝试,如何强制来自给定提交的主分支的拉取请求?
谢谢大家!
选项 1:revert
在第一次尝试中,您似乎想向 master
添加一个提交以撤消 10 次提交的更改。您将此设想为 master
的当前 ip 与您要撤消的 10 次提交之前的提交之间的合并。
当然,如果这符合您当前的要求,那么这将意味着正常合并将不断撤消合并一侧或另一侧的更改 - 这正是合并应该做的 不做。
在 git 中,表示您要执行的操作的词是 revert
。如果你有
x -- x -- x -- A -- B -- ... -- I -- J -- o <--(master)
并且您想撤消 A
至 J
,您可以这样说
git revert -n A^..J
(用 ID 或解析为相应提交的其他表达式替换 A
和 J
;在本例中,一种拼写方式是
git revert -n master~11..master^
记住第一个表达式将指向 A
的 父级 而不是 A
本身)。
这将更新您的索引和工作树以撤消指定范围内的提交的更改。那么
git commit -m "Revert commits A through J"
如果您不想显式提交,可以不使用 -n
选项,但随后您将获得 10 次新提交(一次用于撤消每个原始提交)。
提交不一定是连续的;您可以单独命名每个提交,而不是指定范围。无论分支拓扑如何,这都应该有效。请注意,还原操作可能会发生冲突,并且在您要还原的提交之后发生的更改越多,冲突的可能性就越大。
作为一种特殊情况,如果 10 次提交构成了一个功能分支的全部,如
x -- x -- x -- x -- x -- x -- y --- M -- o <--(master)
\ /
A -- B -- ... -- I -- J <--(feature_branch)
你可以说
git revert -m1 M
(其中 M
又是一些表达式,例如 M
的提交 ID,或本例中的 master^
等)
这意味着您要应用对第一个父级 (y
) 所做的更改 M
的逆向。但是请注意,一旦你恢复合并,你就不能稍后重做合并(因为从 git 的角度来看,这些更改已经合并,即使你后来碰巧撤消了它们) .您可以稍后 "revert the revert",或者您可以进行变基以使用新提交重新创建分支并从中重新合并。
选项 2:重写历史记录
另一方面,您可以从 master
分支的历史记录中删除原始提交。您的第二次尝试是一种方法。正如您所注意到的,并非每个遥控器都允许您进行强制推送 - 这是有充分理由的(有副作用)。每一种重写历史的方法最终都需要强制推送,所以如果你没有权限那么这根本不是一个选择。
无法通过拉取请求对旧提交创建分支。
如果你没有强制推送权限,你应该在一个新分支上恢复更改并创建 PR 将新分支合并到 master
,或者你可以要求团队项目管理员将 master 分支重置为一个旧提交。
选项 1:还原 master
分支上的更改
假设 master 分支上的提交历史如下,提交 C1
到 C10
是您要还原的提交:
…---A---C1---C2---…---C10 master
如果 master
分支没有分支策略,您可以直接在 master
分支上恢复并推送到远程。
# On local master branch
git revert C1^..
git push origin master
还原更改后,master
分支上的提交历史应该是:
…---A---C1---C2---…---C10---C10'---C9'---…---C1' master
如果master
分支有分支策略,你可以从master
分支创建一个新分支(例如feature/something
分支),然后恢复feature/something
分支并创建一个 PR 以将 feature/something
分支合并到 master
:
# On local master branch
git checkout -b feature/something
git revert C1^..
git push -u origin feature/something
那么提交历史将是:
…---A---C1---C2---…---C10 master
\
C10'---C9'---…---C1' fearure/something
您可以创建一个 PR 将 feature/something
合并到 master
。它不应该抱怨没有新的变化,除非你revert/merge相反。
选项 2:要求团队项目管理员重置并强制推送到 master
分支
如果master
分支上没有分支策略,你可以要求团队项目管理员重置master
分支然后强制推送(作为你尝试的第二次尝试)。或者你可以让管理员允许你强制推送。
场景如下:
- 我们有大约 10 个提交要从我们的 master 分支中恢复。它们引起了某种问题,我需要恢复到特定的提交
123abc
;
我们在这里尝试了一些东西:
我们创建了一个名为
feature/something
的新分支,以便还原提交并对主分支执行pull request
。但是,VSTS 抱怨我们没有新的更改。当我们
git reset --hard 123abc
进入master
分支时,我的本地 space 恢复为给定的提交,到目前为止没问题。但是,我没有权限 force 推送到 master 分支。
所以,我的问题是:
关于第一次尝试,如何让git理解我想将这些更改拉到主分支并且不抱怨?
关于第二次尝试,如何强制来自给定提交的主分支的拉取请求?
谢谢大家!
选项 1:revert
在第一次尝试中,您似乎想向 master
添加一个提交以撤消 10 次提交的更改。您将此设想为 master
的当前 ip 与您要撤消的 10 次提交之前的提交之间的合并。
当然,如果这符合您当前的要求,那么这将意味着正常合并将不断撤消合并一侧或另一侧的更改 - 这正是合并应该做的 不做。
在 git 中,表示您要执行的操作的词是 revert
。如果你有
x -- x -- x -- A -- B -- ... -- I -- J -- o <--(master)
并且您想撤消 A
至 J
,您可以这样说
git revert -n A^..J
(用 ID 或解析为相应提交的其他表达式替换 A
和 J
;在本例中,一种拼写方式是
git revert -n master~11..master^
记住第一个表达式将指向 A
的 父级 而不是 A
本身)。
这将更新您的索引和工作树以撤消指定范围内的提交的更改。那么
git commit -m "Revert commits A through J"
如果您不想显式提交,可以不使用 -n
选项,但随后您将获得 10 次新提交(一次用于撤消每个原始提交)。
提交不一定是连续的;您可以单独命名每个提交,而不是指定范围。无论分支拓扑如何,这都应该有效。请注意,还原操作可能会发生冲突,并且在您要还原的提交之后发生的更改越多,冲突的可能性就越大。
作为一种特殊情况,如果 10 次提交构成了一个功能分支的全部,如
x -- x -- x -- x -- x -- x -- y --- M -- o <--(master)
\ /
A -- B -- ... -- I -- J <--(feature_branch)
你可以说
git revert -m1 M
(其中 M
又是一些表达式,例如 M
的提交 ID,或本例中的 master^
等)
这意味着您要应用对第一个父级 (y
) 所做的更改 M
的逆向。但是请注意,一旦你恢复合并,你就不能稍后重做合并(因为从 git 的角度来看,这些更改已经合并,即使你后来碰巧撤消了它们) .您可以稍后 "revert the revert",或者您可以进行变基以使用新提交重新创建分支并从中重新合并。
选项 2:重写历史记录
另一方面,您可以从 master
分支的历史记录中删除原始提交。您的第二次尝试是一种方法。正如您所注意到的,并非每个遥控器都允许您进行强制推送 - 这是有充分理由的(有副作用)。每一种重写历史的方法最终都需要强制推送,所以如果你没有权限那么这根本不是一个选择。
无法通过拉取请求对旧提交创建分支。
如果你没有强制推送权限,你应该在一个新分支上恢复更改并创建 PR 将新分支合并到 master
,或者你可以要求团队项目管理员将 master 分支重置为一个旧提交。
选项 1:还原 master
分支上的更改
假设 master 分支上的提交历史如下,提交 C1
到 C10
是您要还原的提交:
…---A---C1---C2---…---C10 master
如果
master
分支没有分支策略,您可以直接在master
分支上恢复并推送到远程。# On local master branch git revert C1^.. git push origin master
还原更改后,
master
分支上的提交历史应该是:…---A---C1---C2---…---C10---C10'---C9'---…---C1' master
如果
master
分支有分支策略,你可以从master
分支创建一个新分支(例如feature/something
分支),然后恢复feature/something
分支并创建一个 PR 以将feature/something
分支合并到master
:# On local master branch git checkout -b feature/something git revert C1^.. git push -u origin feature/something
那么提交历史将是:
…---A---C1---C2---…---C10 master \ C10'---C9'---…---C1' fearure/something
您可以创建一个 PR 将
feature/something
合并到master
。它不应该抱怨没有新的变化,除非你revert/merge相反。
选项 2:要求团队项目管理员重置并强制推送到 master
分支
如果master
分支上没有分支策略,你可以要求团队项目管理员重置master
分支然后强制推送(作为你尝试的第二次尝试)。或者你可以让管理员允许你强制推送。