【问题标题】:How to revert a push to master and then push again the same changes from new branch?如何将推送恢复为 master,然后再次从新分支推送相同的更改?
【发布时间】:2021-01-01 14:58:08
【问题描述】:

我不小心推到了master。我通过git revert shaToPreviousState 恢复了此推送并将原始主状态推回。然后checked out sha 提交带有意外推送的更改,并通过git switch -c new_stuff 将这些更改切换到新分支new_stuff。我做了一些小的修改,对updatepushed 进行了这些更改以分支new_stuff。现在,当我创建一个 MR 以将 new_stuffmaster 合并时,只有最近的更改(在创建 new_stuff 之后)显示为差异。但是,我试图推动的内容包括我已经恢复的那些更改(在检查 sha 并创建 new_stuff 之前)。为什么它们也没有显示在差异中,我该如何解决这个问题?

现任主人

commit 8573277b289224d93993e374e070fa66da63d309 (HEAD -> master, origin/master, origin/HEAD)
Author: user.me <user.me@gmail.com>
Date:   Mon Sep 14 22:37:39 2020 +0200

    Revert "added loading some bin files"

    This reverts commit 649a6f5f4dc31e6ba363fef7a9f77661f45254e9.

commit 649a6f5f4dc31e6ba363fef7a9f77661f45254e9
Author: user.me <user.me@gmail.com>
Date:   Mon Sep 14 22:34:02 2020 +0200

    added loading some bin files

new_stuff 分支

commit 5ff6b90931685a32ae3e7bcde7b00db7440fac5e (HEAD -> new_stuff, origin/new_stuff)
Author: user.me <user.me@gmail.com>
Date:   Mon Sep 14 22:57:33 2020 +0200

    added a few docstrings

commit 649a6f5f4dc31e6ba363fef7a9f77661f45254e9
Author: user.me <user.me@gmail.com>
Date:   Mon Sep 14 22:34:02 2020 +0200

    added loading some bin files

所以在推送 5ff6b9 并创建 MR 之后,除了 5ff6b9 添加的差异之外,差异没有任何变化。所以,我想了解 git 怎么看不到 649a6f + 5ff6b9 带来了很多新东西,但只显示了 5ff6b9 的差异:(

【问题讨论】:

  • 澄清几点: 1. git revert 创建一个新的提交,其更改与shaToPreviousState 所指的提交相反。它不会“恢复推送”,因为“推送”不是不是一个对象,而是一个动作。
  • 2. “然后检查带有意外推送更改的 sha 提交,并将这些更改切换到新分支 new_stuff”我假设您的意思是您做了类似git checkout &lt;some sha hash&gt; 然后git checkout branchA 的事情。这不会“随着这些变化而变化”。当您签出另一个分支时,提交的更改不会跟随您,除非该提交已经在该分支上。
  • git switch 是一个我从未使用过的相对较新的命令。查看帮助文件后,我上面关于 git checkout 的 cmets 似乎同样适用于 git switch:如果它们已经提交,则无法切换“这些更改”。
  • 你想保留这些你不小心推送到 master 但在 new_stuff 分支上的更改吗?
  • 我只希望我推送到 master 的任何内容都可以还原,然后从 MR 显示差异的专用分支重新推送,以便审阅者可以看到我的更改。

标签: git git-merge git-branch git-revert


【解决方案1】:

但是,我试图推送的内容包括我已经恢复的那些更改(在检查 sha 和创建 new_stuff 之前)。为什么它们也没有显示在差异中,我该如何解决这个问题?

TL;DR 您问题的答案很可能是您希望在差异中看到的更改已经是master 的一部分,因此它们实际上并不在差异中。您可以从git log 的输出中看到这种情况,因为 master 和 new_stuff 都具有哈希 649a6f5f4dc31e6ba363fef7a9f77661f45254e9 的提交。

您还可以看到 master 包含另一个提交 8573277b289224d93993e374e070fa66da63d309 ,它恢复了您试图摆脱的更改。第二次提交是在您执行git revert 时创建的。它具有与原始提交完全相反的更改。你可以通过运行看到这一点

git diff master master~

master~ 指的是提交的父级master。)

要让master恢复到原来的状态,你应该使用git reset --hard

git checkout master
git reset --hard master~2

此版本将 master 重置 2 次提交并完全放弃所有更改。如果需要,您可以在更改之前使用确切的 sha 哈希而不是 master~2

现在你需要强制推送,因为你修改了master的历史:

git push -f

大多数 git 服务默认不允许强制推送主服务器,因此您可能会收到推送被拒绝的消息。如果是这种情况,您将需要在您的 git 服务器上设置权限以允许强制推送。我建议在完成后将其重新设置。

在你成功强制 push master 之后,PR diff 应该准确地显示你所期望的。

【讨论】:

    【解决方案2】:

    您正在尝试合并已在该分支上的提交。对于 PR 来说,该提交被还原并不重要。

    相反,您可以从新分支中挑选创建副本的提交。签出新分支和git cherry-pick shaToPreviousState。解决与您所做的其他编辑的潜在冲突。然后你可以将你 PR 中的这个提交合并到 master,因为它不是你之前恢复的那个提交,它是它的副本。

    【讨论】:

      【解决方案3】:

      问题是您不了解 GitHub 在您发出拉取请求时看到的差异中显示的内容。这是一个triple-dot diff;它只显示分支上发生的事情,因为它分支的点。它的分支点是649a6f。从那时起,分支上唯一发生的事情是5ff6b9。这就是你所看到的。

      您可能期望一个双点差异,即分支和主节点之间的差异。但这不是 GitHub 所显示的。 (而且您可以很容易地看到原因。对于审查拉取请求的人来说,在分支准备期间发生在 master 上的事情是无关紧要的;那不是拉取请求的内容。)您可以要求 GitHub 显示双点差异,但这不是拉取请求差异显示的内容。


      例子:

      $ git init
      $ echo "start" > A.txt
      $ git add .
      $ git commit -m'start'
      $ echo "next" > B.txt
      $ git add .
      $ git commit -m 'next'
      $ git revert HEAD
      $ git log
      commit 257883 Revert "next"
      commit 229db2 next
      commit 21d9f0 start
      $ git checkout 229db2
      $ git branch branch
      $ git checkout branch
      $ echo "yoho" > C.txt
      $ git add .
      $ git commit -m 'yoho'
      

      好的,这重现了您的情况。现在让我们做一个双点差异:

      $ git diff master..branch
      diff --git a/B.txt b/B.txt
      new file mode 100644
      index 0000000..5b69858
      --- /dev/null
      +++ b/B.txt
      @@ -0,0 +1 @@
      +next
      diff --git a/C.txt b/C.txt
      new file mode 100644
      index 0000000..faf1efe
      --- /dev/null
      +++ b/C.txt
      @@ -0,0 +1 @@
      +yoho
      

      双点差异知道在branch 上同时存在 B.txt 和 C.txt,而在 master 上它们不存在。 (没有提到 A.txt,因为它不是差异;两者都相同。)

      好的,现在我们将做一个三点差异:

      $ git diff master...branch
      diff --git a/C.txt b/C.txt
      new file mode 100644
      index 0000000..faf1efe
      --- /dev/null
      +++ b/C.txt
      @@ -0,0 +1 @@
      +yoho
      

      在三点差异中,没有提到 B.txt!那是因为它没有发生在 branch 上,因为它与 master 不同。 next 上发生的更改不包含在差异中,即使该更改“在”分支中。这和你看到的完全一样。

      【讨论】:

      • 问题在于masterbranch 都包含OP 只希望在branch 上的提交。这以及对 git revert 所做的事情的困惑。
      猜你喜欢
      • 1970-01-01
      • 2013-04-20
      • 2014-11-27
      • 1970-01-01
      • 2021-05-12
      • 2020-07-29
      • 2015-07-16
      • 1970-01-01
      • 2014-10-02
      相关资源
      最近更新 更多