Summarizes the article

To quote a short summary from "Tomi21634" in the comments section: Git reset deletes the previous commit. Git reset --hard does not delete the previous commit. You need to force git push-fCopy the code

If the short version doesn’t make sense to you, you can read the pictures and instructions carefully below.

git reset

develop ----1      3-----
             \   /
branch a       a
Copy the code

Develop merged the A branch and wanted to withdraw the merger without leaving a trace. Git reset is a good option.

The specific operation steps are as follows:

  1. Switch the branch to Develop
  2. Git log Displays current branch logs

For example, my log looks like this:

commit 3 Merge 1 2 Author: admin <[email protected]> Date: Wed May 30 15:00:00 2018 +0800 Merge branch 'feature/a' into 'develop' close a See merge request ! 20 commit 2 Author: admin <[email protected]> Date: Wed May 30 14:00:00 2018 +0800 close a commit 1 Author: admin <[email protected]> Date: Wed May 30 13:00:00 2018 +0800 init projectCopy the code

I’m going to revert develop to its pre-merge state, which is commit 1, and copy the COMMIT number. Exit the editing screen.

  1. Git resetSee the official website for details.
    -- Mixed resets the index, but does not reset the working tree. The changed files are marked as uncommitted. Default operation. -- Hard resets the index and working tree, and all files modified by the A branch and any intermediate commits, uncommitted code are discarded. -- Merge is similar to --hard, except that if you make changes to files and do not commit them before executing reset, merge keeps your changes, whereas hard does not. Merge and hard will delete your commit if your changes were added or committed. Keep and hard will delete your commit if your changes were made before you reset. If the file is not modified by branch A, the cache is removed. Git status still keeps these changes.Copy the code

I don’t need the a branch code anymore, and I don’t think I’ll need it anymore. Therefore:

Git reset 1 --hard

I still want the a branch code, but I don’t want this commit:

git reset 1

  1. git logCheck it out:
commit 1
Author: admin <[email protected]>
Date: Wed May 30 13:00:00 2018 +0800
    init project
Copy the code

That’s what I want. I can push it to the far end. (This step is dangerous, you must make sure that the reset result is really the result you want, otherwise, do not blame me for the lost code)

git push origin develop

! [Rejected] develop -> develop (non-fast-forward) error: Reject some references to '[email protected]:... 'Tip: Updates were rejected because the latest commit of your current branch is behind its corresponding remote branch. .Copy the code

Well, my branch does lag behind the remote Develop branch. I need –force.

git push origin develop --force

Total 0 (delta 0), reused 0 (delta 0) To git@... + 83 * * *... 23***** develop -> develop (forced update)Copy the code

That’s it. Go back to Github and check out Network. Yeah, that’s what you want.

git revert

Again, this is an example

develop ----1      3-----
             \   /
branch a       a
Copy the code

It’s going to be the same thing as before, you don’t want to merge A, you just want to look like you didn’t merge A.

Operation steps:

  1. Cut branches to develop:git checkout develop
  2. View logs:git log , or the above log:
commit 3 Merge 1 2 Author: admin <[email protected]> Date: Wed May 30 15:00:00 2018 +0800 Merge branch 'feature/a' into 'develop' close a See merge request ! 20 commit 2 Author: admin <[email protected]> Date: Wed May 30 14:00:00 2018 +0800 close a commit 1 Author: admin <[email protected]> Date: Wed May 30 13:00:00 2018 +0800 init projectCopy the code

Instead of copying the commit number of commit 1, I need to copy the commit number of commit 2. Because revert follows which branch you want to merge, not which COMMIT you want to revert to.

  1. Start a rollback:git revert 2
Revert "close a"
This reverts commit 2
#.......
Copy the code

This is equivalent to adding a commit, reversing all changes on branch A.

  1. Ctrl+X leaves the Edit Commit information page.

Git log to see if it is what I think it is

commit 4 Author: admin <[email protected]> Date: Wed May 30 17:00:00 2018 +0800 Revert "close a" This reverts commit 2 commit 3 Merge 1 2 Author: admin <[email protected]> Date: Wed May 30 15:00:00 2018 +0800 Merge branch 'feature/a' into 'develop' close a See merge request ! 20 commit 2 ....Copy the code

I did add a commit, and when I looked at the code, I found that all the changes to branch A were gone, which was what I wanted.

  1. On push’s remote servergit push origin develop

Look at network, it looks like this:

develop ----1      3-----revert a------
             \   /
branch a       a
Copy the code

Git reset and Git Revert both work well for you. What’s the difference between git revert and Git Revert?

The difference between

  1. Git revert allows you to use a new COMMIT to rollback the previous commit. Git reset deletes the specified commit.

    This is easy to understand, and we saw this phenomenon in the log in the previous operation.

    Commit 1 (branch A) and commit 3 (merge branch 3) are missing.

    After the Git revert operation, you can still see branches a and merge branches A in the network, but add a COMMIT to them.

  2. Git reset moves the HEAD back, while Git Revert moves the HEAD forward, but the new commit is the opposite of what you want to revert, and canceles what you want to revert.

    This is also clearly visible, and I’m not going to explain it too much

  3. In the case of rollback, the effect is similar. However, there are differences when continuing to merge older versions before. Because Git revert “neutralizes” previous commits with a reverse commit, this change does not reappear when older branches are merged, but git reset deletes a commit directly from a branch. Therefore, when merging with the old branch again, these rollback commits should be introduced again.

    git revert

    The current requirement is that I have already revert branch A before, but NOW I need the code of branch A again. I have already written it again and cannot rewrite it again. The first thing I came up with was to merge the A branch into Develop.

    git merge a
    Copy the code

    The results of

    Already up-to-date
    Copy the code

    What? Since the a branch we submitted to merge is still in the code, we can’t remerge the A branch.

    Workaround: Use the commit number used before REVERT. In the example above it is Git Revert 4. Add a COMMIT to revert the previous revert code. Specific reference

git reset

It’s still the requirement above.

develop -----1-----4-------5------6
              \   / \     / \    /
feature         b      c       d
Copy the code

I will now reset to Commit 4 and continue to commit my code

develop -----1-----4-------7------8
              \   / \\     /
feature         b     \ e
                        \------5----d
                          \-c-/
Copy the code

I now want to remerge the d branch code

 develop -----1-----4-------7------8------9
              \   / \\     /             /
feature         b     \ e              /
                        \------5----d/
                          \-c-/
Copy the code

So it’s going to look something like this. This means that branch D has merged with branch C before, so if you want to merge branch D again, the code from branch C will be synchronized.

Application scenarios

At this point, most common application scenarios should be fairly clear.

  1. If the code for the rollback branch is needed latergit revertIt would be great; If I’m just throwing out the wrong branch and I don’t want anyone to find out I’m wrong, thengit reset!
  2. For example, the develop branch merges branches A, B, C, and D, and I suddenly realize that the B branch is useless and the code is not needed, so I can’t use reset because the C and D branches also disappear. This is the only timeGit Revert B branch COMMITSo the c and D code is still there.

conclusion

That’s pretty much all I can think of, and of course there are a lot of things that we don’t have to deal with on a specific project. My advice is not to blindly look for similar problems and then fix them, because his problems are not necessarily the same as your problems. I recommend creating a branch of the test, and then go to a branch of the entire line after you’ve really figured it out.

It is the first time to write such a detailed article, mainly because of the knowledge found on the Internet, for the general knowledge system of Git, read more confusing.