如何将推送还原到 master 然后再次从新分支推送相同的更改?
How to revert a push to master and then push again the same changes from new branch?
不小心推到了master
。我通过 git revert shaToPreviousState
恢复了这个推送并将原来的主状态推回。然后 checked out
带有意外推送更改的 sha 提交,并通过 git switch -c new_stuff
将这些更改切换到新分支 new_stuff
。我做了一些小修改,对分支 new_stuff
做了 update
和 pushed
这些更改。现在,当我创建一个 MR 以将 new_stuff
与 master
合并时,只有最近的更改(在创建 new_stuff
之后)显示为差异。但是,我试图推动的内容包括我已经还原的那些更改(在检查 sha 和创建 new_stuff
之前)。为什么它们也没有显示在 diff 中,我该如何解决这个问题?
现任主人
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
的差异 :(
However, what I am attempting to push includes those very changes I already reverted (before checking out the sha and creating new_stuff). Why are they not displayed in the diff as well and how do I resolve this issue?
TL;DR 您问题的答案很可能是您希望在 diff 中看到的更改已经是 master
的一部分,因此它们不是实际上在差异中。您可以从 git log
的输出中看到这种情况,因为 master 和 new_stuff 都具有哈希 649a6f5f4dc31e6ba363fef7a9f77661f45254e9
.
的提交
您还可以看到 master 包含另一个提交 8573277b289224d93993e374e070fa66da63d309
,它还原了您试图删除的更改。这第二次提交是在您 git revert
时创建的。它具有与原始提交完全相反的更改。你可以通过运行
看到这个
git diff master master~
(master~
指的是 master
处提交的父项。)
要return掌握到原来的状态,你应该使用git reset --hard
:
git checkout master
git reset --hard master~2
此版本将重置 master
2 次提交并且 完全放弃所有更改。如果需要,您可以在更改之前为提交使用确切的 sha 哈希,而不是 master~2
。
现在你需要强制推送因为你修改了master的历史:
git push -f
大多数 git 服务在默认情况下不允许强制推送 master,因此您可能会收到推送被拒绝的消息。如果是这种情况,您需要在 git 服务器上设置权限以允许强制推送。我建议您在完成后将其设置回去。
成功强制推送主机后,PR diff 应该准确显示您的预期。
您正在尝试合并已在该分支上的提交。那个提交被恢复对 PR 来说并不重要。
相反,您可以从新分支 cherry-pick 创建它的副本的提交。检查新分支和 git cherry-pick shaToPreviousState
。解决与您所做的其他编辑的潜在冲突。然后你可以在你的 PR 中合并这个提交到 master 因为它不是你之前恢复的同一个提交,它是它的副本。
问题是您不理解 GitHub 在您发出拉取请求时看到的差异中显示的内容。这是一个triple-dot diff;它只显示分支上发生的事情,从分支点开始。它分支的点是649a6f
。从那时起在分支上发生的唯一事情是 5ff6b9
。这就是你所看到的。
您可能期望 double-dot 差异,即分支和主节点之间的差异。但这不是 GitHub 显示的内容。 (而且你很容易明白为什么。对于审查拉取请求的人来说,在分支准备期间 master 上发生的事情毫无意义;那不是 拉取请求的内容 。)你 可以 要求 GitHub 显示 double-dot 差异,但这不是拉取请求差异显示的内容.
示例:
$ 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'
好的,这重现了你的情况。现在让我们做一个 double-dot diff:
$ 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
double-dot diff 知道 branch
上 B.txt 和 C.txt 都存在,而 master
则不存在。 (A.txt 未提及,因为它不是差异;两者相同。)
好的,现在我们来做一个triple-dot diff:
$ 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
在triple-dot diff中,没有提到B.txt!那是因为它没有发生在 branch
上,因为它偏离了 master
。 next
上发生的更改不包含在差异中,即使该更改“在”分支中也是如此。这与您所看到的完全一样。
不小心推到了master
。我通过 git revert shaToPreviousState
恢复了这个推送并将原来的主状态推回。然后 checked out
带有意外推送更改的 sha 提交,并通过 git switch -c new_stuff
将这些更改切换到新分支 new_stuff
。我做了一些小修改,对分支 new_stuff
做了 update
和 pushed
这些更改。现在,当我创建一个 MR 以将 new_stuff
与 master
合并时,只有最近的更改(在创建 new_stuff
之后)显示为差异。但是,我试图推动的内容包括我已经还原的那些更改(在检查 sha 和创建 new_stuff
之前)。为什么它们也没有显示在 diff 中,我该如何解决这个问题?
现任主人
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
的差异 :(
However, what I am attempting to push includes those very changes I already reverted (before checking out the sha and creating new_stuff). Why are they not displayed in the diff as well and how do I resolve this issue?
TL;DR 您问题的答案很可能是您希望在 diff 中看到的更改已经是 master
的一部分,因此它们不是实际上在差异中。您可以从 git log
的输出中看到这种情况,因为 master 和 new_stuff 都具有哈希 649a6f5f4dc31e6ba363fef7a9f77661f45254e9
.
您还可以看到 master 包含另一个提交 8573277b289224d93993e374e070fa66da63d309
,它还原了您试图删除的更改。这第二次提交是在您 git revert
时创建的。它具有与原始提交完全相反的更改。你可以通过运行
git diff master master~
(master~
指的是 master
处提交的父项。)
要return掌握到原来的状态,你应该使用git reset --hard
:
git checkout master
git reset --hard master~2
此版本将重置 master
2 次提交并且 完全放弃所有更改。如果需要,您可以在更改之前为提交使用确切的 sha 哈希,而不是 master~2
。
现在你需要强制推送因为你修改了master的历史:
git push -f
大多数 git 服务在默认情况下不允许强制推送 master,因此您可能会收到推送被拒绝的消息。如果是这种情况,您需要在 git 服务器上设置权限以允许强制推送。我建议您在完成后将其设置回去。
成功强制推送主机后,PR diff 应该准确显示您的预期。
您正在尝试合并已在该分支上的提交。那个提交被恢复对 PR 来说并不重要。
相反,您可以从新分支 cherry-pick 创建它的副本的提交。检查新分支和 git cherry-pick shaToPreviousState
。解决与您所做的其他编辑的潜在冲突。然后你可以在你的 PR 中合并这个提交到 master 因为它不是你之前恢复的同一个提交,它是它的副本。
问题是您不理解 GitHub 在您发出拉取请求时看到的差异中显示的内容。这是一个triple-dot diff;它只显示分支上发生的事情,从分支点开始。它分支的点是649a6f
。从那时起在分支上发生的唯一事情是 5ff6b9
。这就是你所看到的。
您可能期望 double-dot 差异,即分支和主节点之间的差异。但这不是 GitHub 显示的内容。 (而且你很容易明白为什么。对于审查拉取请求的人来说,在分支准备期间 master 上发生的事情毫无意义;那不是 拉取请求的内容 。)你 可以 要求 GitHub 显示 double-dot 差异,但这不是拉取请求差异显示的内容.
示例:
$ 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'
好的,这重现了你的情况。现在让我们做一个 double-dot diff:
$ 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
double-dot diff 知道 branch
上 B.txt 和 C.txt 都存在,而 master
则不存在。 (A.txt 未提及,因为它不是差异;两者相同。)
好的,现在我们来做一个triple-dot diff:
$ 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
在triple-dot diff中,没有提到B.txt!那是因为它没有发生在 branch
上,因为它偏离了 master
。 next
上发生的更改不包含在差异中,即使该更改“在”分支中也是如此。这与您所看到的完全一样。