【问题标题】:How to "force" a pull request from a specific commit?如何“强制”来自特定提交的拉取请求?
【发布时间】:2018-06-07 12:31:08
【问题描述】:

场景如下:

  • 我们有大约 10 个提交要从我们的主分支恢复。它们引起了某种问题,我需要恢复到特定的提交 123abc

我们在这里尝试过的一些事情:

  • 我们创建了一个名为feature/something 的新分支,以恢复提交并对主分支执行pull request。但是,VSTS 抱怨我们没有新的变化。

  • 当我们在master 分支中执行git reset --hard 123abc 时,我的本地空间将恢复为给定的提交,到目前为止还可以。但是,我无权强制推送到主分支。

所以,我的问题是:

  • 关于第一次尝试,如何让 git 明白我想将这些更改拉到 master 分支而不抱怨?

  • 关于第 2 次尝试,如何强制从给定提交的主分支发出拉取请求?

谢谢大家!

【问题讨论】:

  • 您是否使用git request-pull 发出此拉取请求?如果没有,您使用的是什么,VSTS 是什么(不在您的标签中)? (最后一个问题是一种暗示。我可以假设它代表 Visual Studios Team Services,但我不使用 Visual Studios,所以我不能确定,不幸的是,也不能帮助无论 Visual Studios 本身做什么。)

标签: git version-control git-push pull-request git-reset


【解决方案1】:

选项 1:revert

在第一次尝试中,您似乎想向master 添加提交以撤消 10 次提交中的更改。您将其设想为master 的当前 ip 与您想要撤消的 10 次提交之前的一次提交之间的合并。

当然,如果这达到了您当前想要的效果,那么这将意味着正常的合并将不断撤消合并一侧或另一侧的更改 - 这正是合并应该不 做。

在 git 中,您要执行的操作是 revert。如果你有

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

如果你想撤消 AJ,你可以这样说

git revert -n A^..J

(将 AJ 替换为可解析为相应提交的 ID 或其他表达式;在此示例中,一种拼写方式是

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^ 等)

这意味着您希望应用与 M 对其第一个父级 (y) 所做的更改的逆操作。但是请注意,一旦您恢复合并,您就不能稍后重做合并(因为从 git 的角度来看,即使您后来碰巧撤消了这些更改,这些更改也已经合并)。您可以稍后“还原还原”,或者您可以进行变基以使用新提交重新创建分支并从中重新合并。

选项 2:重写历史记录

另一方面,您可以从 master 分支的历史记录中删除原始提交。您的第二次尝试是做到这一点的一种方法。正如您所注意到的,并非每个遥控器都允许您进行强制推送 - 并且有充分的理由(有副作用)。每一种重写历史的方法最终都需要强制推送,所以如果你没有权限,那么这根本不是一个选择。

【讨论】:

    【解决方案2】:

    无法通过拉取请求对旧提交进行分支。

    如果您没有强制推送权限,您应该在新分支上恢复更改并创建 PR 以将新分支合并到 master,或者您可以要求团队项目管理员将 master 分支重置为旧提交。

    选项 1:还原 master 分支上的更改

    假设 master 分支上的提交历史如下,提交 C1C10 是您要恢复的提交:

    …---A---C1---C2---…---C10   master
    
    • 如果master分支没有分支策略,可以直接在master分支上revert并推送到远程。

      # 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。它不应该抱怨没有新的变化,除非你以相反的方式恢复/合并。

    选项 2:请团队项目管理员重置并强制推送到 master 分支

    如果master 分支上没有分支策略,您可以要求团队项目管理员重置master 分支,然后强制推送(作为您尝试的第二次尝试)。或者你可以请求管理员允许你强制推送。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 2019-09-01
      • 2022-01-01
      • 1970-01-01
      相关资源
      最近更新 更多