简体   繁体   English

如何“强制”来自特定提交的拉取请求?

[英]How to "force" a pull request from a specific commit?

The scenario is the following:场景如下:

  • We have around 10 commits that we want to revert from our master branch.我们有大约 10 个要从主分支恢复的提交。 They are causing some sort of issue and I need to revert to a specific commit 123abc ;他们导致了某种问题,我需要恢复到特定的提交123abc

Some things we tried here:我们在这里尝试了一些事情:

  • We created a new branch called feature/something in order to revert the commit and do a pull request to the master branch.我们创建了一个名为feature/something的新分支,以便恢复提交并向主分支发出pull request However, VSTS is complainng that we don't have new changes.但是,VSTS 抱怨我们没有新的更改。

  • When we do git reset --hard 123abc into master branch, my local space is reverted to the given commit, that's OK so far.当我们执行git reset --hard 123abcmaster分支时,我的本地空间恢复到给定的提交,到目前为止还可以。 However, I don't have permission to force a push to the master branch.但是,我无权强制推送到主分支。

So, my questions are:所以,我的问题是:

  • Regarding the 1st attempt, how to make git understand that I want to pull those changes to master branch and don't complain?关于第一次尝试,如何让 git 明白我想将这些更改拉到 master 分支并且不要抱怨?

  • Regarding the 2nd attempt, how to force a pull request from master branch from that given commit?关于第二次尝试,如何从给定的提交强制从主分支拉取请求?

Thank you all!谢谢你们!

There is no way to make a branch to an old commit through pull request.无法通过拉取请求对旧提交进行分支。

If you have not force push permission, you should revert changes on a new branch and create PR to merge the new branch into master , or you can ask the team project administrator to reset master branch to an old commit.如果你没有强制推送权限,你应该恢复对新分支的更改并创建 PR 将新分支合并到master ,或者你可以要求团队项目管理员将 master 分支重置为旧提交。

Option 1: revert the changes on master branch选项 1:还原master分支上的更改

Assume the commit history on master branch as below, and the commits C1 to C10 are the commits you want to revert:假设 master 分支上的提交历史如下,并且提交C1C10是您要还原的提交:

…---A---C1---C2---…---C10   master
  • If master branch has no branch policies, you can directly revert on master branch and push to remote.如果master分支没有分支策略,您可以直接在master分支上恢复并推送到远程。

     # On local master branch git revert C1^.. git push origin master

    After revert the changes, the commit history on master branch should be:恢复更改后, master分支上的提交历史应该是:

     …---A---C1---C2---…---C10---C10'---C9'---…---C1' master
  • If master branch has branch policies, you can create a new branch (such as feature/something branch) from master branch, then revert commits on feature/something branch and create a PR to merge feature/something branch into 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

    Then the commit history will be:然后提交历史将是:

     …---A---C1---C2---…---C10 master \\ C10'---C9'---…---C1' fearure/something

    You can create a PR to merge feature/something into master .您可以创建一个 PR 以将feature/something合并到master And it shouldn't complain there hasn't new changes unless you revert/merge on the opposite way.它不应该抱怨没有新的变化,除非你以相反的方式恢复/合并。

Option 2: ask team project administrator to reset and force push to master branch选项 2:要求团队项目管理员重置并强制推送到master分支

If there has no branch policies on master branch, you can ask team project administrator to reset master branch and then force push (as the 2nd attempt you tried).如果master分支上没有分支策略,您可以要求团队项目管理员重置master分支,然后强制推送(作为您尝试的第二次尝试)。 Or you can ask the administrator to allow you to force push.或者您可以要求管理员允许您强制推送。

Option 1: revert选项 1: revert

In the first attempt, it seems you want to add a commit to master to undo the changes from the 10 commits.在第一次尝试中,您似乎想向master添加一个提交以撤消 10 个提交的更改。 You're envisioning this as a merge between the current ip of master , and a commit before the 10 commits you want to undo.您将此设想为master的当前 ip 与要撤消的 10 个提交之前的提交之间的合并。

Of course if this did what you're currently wanting, then that would mean that normal merges would be constantly undoing changes from one side of the merge or other - which is exactly what a merge is supposed to not do.当然,如果这样做你目前想要什么,那么这将意味着正常的合并将是不断地从合并或其他的一侧撤消的变化-这正是合并应该不会做。

In git, the word for what you're trying to do is revert .在 git 中,你想要做的事情的词是revert If you have如果你有

x -- x -- x -- A -- B -- ... -- I -- J -- o <--(master)

and you want to undo A thru J , you could say something like并且您想撤消AJ ,您可以这样说

git revert -n A^..J

(replacing A and J with ID's or other expressions that resolve to the corresponding commits; in this example one way to spell it out would be (用 ID 或其他解析为相应提交的表达式替换AJ ;在本例中,一种拼写方法是

git revert -n master~11..master^

remembering that the first expression would point to A 's parent rather than A itself).记住第一个表达式将指向A父级而不是A本身)。

This will update your index and working tree to undo the changes from the specified range of commits.这将更新您的索引和工作树,以撤消指定提交范围内的更改。 So then那么

git commit -m "Revert commits A through J"

If you don't want to have to explicitly commit, you can leave off the -n option, but then you'll get 10 new commits (one to undo each of the original commits).如果您不想显式提交,您可以不使用-n选项,但是您将获得 10 个新提交(一个用于撤消每个原始提交)。

The commits don't necessarily have to be sequential;提交不一定是顺序的; you could name each commit individually instead of specifying a range.您可以单独命名每个提交,而不是指定范围。 And this should work regardless of the branch topology.无论分支拓扑如何,这都应该有效。 Do note that revert operations can conflict, and the more changes have occurred after a commit that you're reverting the more likely a conflict becomes.请注意,还原操作可能会发生冲突,并且在您还原的提交后发生的更改越多,冲突的可能性就越大。

As a special case, if the 10 commits make up all of a feature branch, as in作为一种特殊情况,如果 10 次提交构成了一个功能分支的所有内容,如

x -- x -- x -- x -- x -- x -- y --- M -- o <--(master)
           \                       /
            A -- B -- ... -- I -- J <--(feature_branch)

you could say你可以说

git revert -m1 M

(where M is again some expression like the commit ID of M , or master^ in this example, etc.) (其中M是一些表达式,例如M的提交 ID,或本例中的master^等)

This means you want to apply the inverse of the changes M made over its 1st parent ( y ).这意味着您要应用M对其第一个父级 ( y ) 所做更改的逆操作。 Be aware, though, that once you revert a merge you can't just redo the merge later (because from git's point of view, those changes are already merged in even though you happen to have later undone them).但是请注意,一旦您恢复合并,您就不能稍后再重新进行合并(因为从 git 的角度来看,这些更改已经被合并了,即使您后来碰巧撤消了它们)。 You could later "revert the revert", or you could do a rebase to recreate the branch with new commits and re-merge from that.您可以稍后“还原还原”,或者您可以执行重新设置以使用新提交重新创建分支并从中重新合并。

Option 2: rewrite history选项 2:重写历史记录

On the other hand, you could remove the original commits from the history of the master branch.另一方面,您可以从master分支的历史记录中删除原始提交。 Your second attempt is one way to do that.您的第二次尝试是一种方法。 As you note, not every remote gives you the permission to do a force push - and for good reason (there are side effects).正如您所注意到的,并非每个遥控器都允许您进行强制推送 - 并且有充分的理由(有副作用)。 Every method of rewriting history will ultimately require a force push, so if you don't have permission then this simply isn't an option.重写历史的每种方法最终都需要强制推送,因此如果您没有权限,那么这根本不是一种选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM