简体   繁体   中英

How to revert a push to master and then push again the same changes from new branch?

I accidentally pushed to master . I reverted this push via git revert shaToPreviousState and pushed the original master state back. Then checked out the sha commit with the accidentally pushed changes and switched via git switch -c new_stuff with these changes to a new branch new_stuff . I did some minor modifications, did an update and pushed these changes to branch new_stuff . Now when I create an MR to merge new_stuff with the master , only the very recent changes (after creating new_stuff ) are displayed as a diff. 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?

Current master

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 branch

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

So after pushing 5ff6b9 and creating an MR, there are no changes in the diff except for the ones added by 5ff6b9 . So, I am trying to understand how does git not see that 649a6f + 5ff6b9 come with a lot of new stuff but only shows a diff for 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 Most likely the answer to your question is that the changes you expect to see in the diff are already part of master , so they aren't actually in the diff. You can see this is the case from the output of git log because both master and new_stuff have the commit with hash 649a6f5f4dc31e6ba363fef7a9f77661f45254e9 .

You can also see that master contains another commit 8573277b289224d93993e374e070fa66da63d309 that reverts the changes you are trying to get rid of. This second commit was created when you did git revert . It has the changes that are exactly the opposite of the original commit. You can see this by running

git diff master master~

( master~ refers to the parent of the commit at master .)

To return master to its original state, you should use git reset --hard :

git checkout master
git reset --hard master~2

This version will reset master back 2 commits and completely discard all changes . You can use the exact sha hash for the commit before the change instead of master~2 if you want.

Now you will need to force push becuase you modified the history of master:

git push -f

Most git services disallow force pushing master by default, so you might get a message that the push was rejected. If this is the case, you will need to set the permissions on your git server to allow the force push. I suggest setting it back after you are done.

After you successfully force push master, the PR diff should show exactly what you expect.

You are trying to merge a commit that is already on that branch. It doesn't matter to the PR that that commit was reverted.

Instead, from the new branch you can cherry-pick the commit which creates a duplicate of it. Checkout the new branch and git cherry-pick shaToPreviousState . Solve potential conflicts with the other edits you made. Then you can merge this commit in you PR to master as it is not the same commit you previously reverted, it is a duplicate of it.

The problem is that you don't understand what GitHub displays in the diff you see when you make a pull request. It is a triple-dot diff ; it shows only what happened on the branch, since the point where it branched. The point where it branched is 649a6f . The only thing that happened on the branch since that point is 5ff6b9 . So that's what you see.

You probably expected a double-dot diff, ie the diff between the branch and master. But that is not what GitHub is displaying. (And you can readily see why. To someone reviewing the pull request, what happened on master while the branch was in preparation is of no interest whatever; that is not the content of the pull request .) You can ask GitHub to show a double-dot diff, but that is not what the pull request diff displays.


Example:

$ 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'

Okay, that reproduces your situation. Now let's do a 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

The double-dot diff knows that on branch both B.txt and C.txt exist, as opposed to master where they do not. (A.txt is not mentioned, because it is not a diff; it is the same on both.)

Okay, now we'll do a 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

In the triple-dot diff, B.txt is not mentioned! That's because it didn't happen on branch since it diverged from master . The change that happened on next is not included in the diff, even though that change is "in" the branch. That is exactly like what you are seeing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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