git rollback

Rollback operation of traditional VCS

For the version control system VCS, rollback should be a very common and important requirement.

If you are a traditional VCS, such as SVN or P4, revert is the most intuitive and direct method, of course, provided that your changes have not been submitted to the remote central repository.

If you have already ci your code to the remote central warehouse, then revert may not be able to do anything. You can only use other commands to workaroud. For example, if you use SVN, you have to perform a reverse merge operation to merge all the changes back. .

But doing so also has some disadvantages:

This merge will be recorded as a new commit record, which means it can't really erase your unwanted changes from your history. Usually it's not a big deal, unless your personal cleanliness is that you don't want to see the previous commit record or what you really did that you don't want others to know.

Rollback operations in the Git era

But when it comes to the git era, the complexity of this rollback operation has become less simple with the characteristics of the git model itself.

Those who are familiar with git know that for distributed requirements, git uses each network node as a complete VCS, that is, each single host can meet the requirements without any influence on the premise of no network. Almost everything except synchronizing with other nodes (eg: git pull/push).

In order to achieve this effect, git not only has a complete local repository locally, but also cuts the original simple working tree (or working directory) into two areas - working tree and index (also called stage).

In this way, from the perspective of local modifications, your modifications may exist in three areas, the working tree, the index or the historical object area after the commit. Below we generally roll back each area one by one.

Rollback within the working tree

This is the simplest case. In essence, it is also a scene that directly corresponds to revert in traditional VCS, except that it is not called revert here, but git checkout. This situation is very simple, and no screenshots are shown here. List the vaguely commonly used commands in the following form:

  • git checkout file1 (rolls back a single file)
  • git checkout file1 file2 ... fileN (rollback multiple files at a time, separated by spaces)
  • git checkout . (Directly roll back all modifications in the working tree under the current directory, and recursively scan all subdirectories under the current directory)

Rollback within index

This part of the rollback is not complicated, because this part of the rollback, as long as you use the git status command diligently, the output of the command will prompt you what you need to do. But this process is generally divided into two steps:

  1. Remove the modified files in the index area from the index, that is, restore them to the working tree. This is solved with git reset.
  2. Once the file is back in the working tree, the rollback operation is the git checkout mentioned above.

Take a look at this screenshot to be more intuitive:

The original file information under my working tree is as follows.

 I modified a.txt and my_dir/b.txt, and added them to the index area. Currently running git status and getting the following output


 Execute git reset again here. Move all modifications in the current directory and subdirectories out of the index area, and run the git status command again


 After this step, just use the git checkout mentioned above to solve the problem.

 

rollback after commit

This situation is the most complicated and most confusing in git local rollback, because there are many methods for different situations, so it is not easy to remember.

  • Modify the record of the last commit : In many cases, you have to roll back first because you missed the last commit (note that the missing here is not only the modification of the file that you submitted less, but also the more you submitted. something you don't want to commit), you want to roll back this commit and then re-commit it. If that's the case, there's really no need to roll back and re-commit. As long as you are satisfied with all your modifications, you can directly execute git commit --amend, you can turn on the "remedial" submission mode of the last submission, and then add all the things you missed last time. . Let's look at an example: I made a wrong submission, and the modified content is as follows:

     The current commit record is as follows:

     Now I want to remedy this commit, which is equivalent to canceling the newly added file b. Modify the three lines, and then add the modification I really want: add a c.txt under my_dir, and modify the third line of a.txt to another sentence.

     

     Check the commit record through git log again.

     Please note that the modification of the latest commit has actually been modified to another SHA1 value. Note here that, in a sense (in fact, this replacement is easy to trace in the reflog, but in all the commit backreference chains, we can't find the previous fad4...), this This operation has been done invisibly modify the last commit. This is fundamentally different from SVN's reverse merge.
  • Roll back a commit in the middle (including the last one, of course) : For example, if I want to roll back the penultimate commit in the picture above, which is the HEAD^ time, let's first use git show HEAD^ to see if that commit is done. what?

     Then roll back this operation with git revert HEAD^, and then we get the following prompt:

     Cup, conflict. . . In fact, as long as you are familiar with any kind of VCS tool, it is quite normal to think about this scenario. Then git status to see which files conflict.

     In fact, as long as you carefully read the instructions above, you should already know how to resolve this conflict. Obviously, a.txt is the file where the conflict occurred:

     open this file and you can see the standard conflict identification file. This is exactly the sentence we modified by the remedial submission method before. As for how to resolve the conflict, it is very easy to see what you want, edit it yourself, remove the conflict scope identifier, and save the file. Then submit again according to the normal process of git, and edit the submitted information. The log information after resubmission is as follows:

     Above we basically demonstrated a standard revert scenario (including conflict resolution). As can be seen from this process, the reverse merge of git revert and SVN is almost the same, that is, to roll back what you need to do All the operations done by that commit, reverse the operation once, and then re-do a separate commit object for submission. Whether this process conflicts or not depends on your modification. Please note that although you rolled back the modifications you did not want in this process, you cannot erase the information in the history of that commit. Please pay attention to the third line in the picture above, he is still standing there. This is also a feature of git revert. Of course, git revert actually also provides the -n (--no-commit) parameter, which is used to indicate that only the changes of revert are reflected in the current working tree, and the commit is not automatically performed. But if you really want to roll back those changes, the link of committing again cannot be escaped.
  • Roll back the last N commits (permanently erase these records from the commit's history) : This is where git reset comes in. The help documentation of git reset is very clear. In the scenario of rolling back a commit, its role is to reset the current HEAD to the branch you specified. But the most noteworthy thing in this process is the parameters you use. The most commonly used ones are --soft (personally recommend to use this, it will not modify any changes you have made in the current index or working tree)/--mixed ( The default behavior when you do not add any parameters when you reset, will silently destroy your changes in the index!)/--hard (this is the most dangerous parameter for me, it will put your index and working tree in the All modifications to destroy the hair are not left, please think twice before using, this is indeed the behavior you want!) These three. Because I recommend the use of the --soft parameter, the following mainly demonstrates the rollback to 3f412... The record of that time (git reset --soft HEAD~2):

     As you can see from the above, your index area suddenly has a lot more uncommitted These are the records that have been rolled back. How to deal with them is up to you. At this time, I will take a look at the log record information:

     the latest commit has become the one we hoped. In fact, from the explanation of git reset, we can see that git reset is a "cut-off" rollback operation, because you move the current HEAD pointer directly to the record you need to roll back to. The commit chain of git itself is reversed, so you can no longer find the record after the commit pointed to by the current HEAD in the commit history. (But if you are a git literary youth, of course you know that if you want to find those commits that you can't find on the surface, it is also easy to pass reflog).

Well, here, the commonly used git rollback operations and scenarios have been introduced. Hope it helps for TX who are not familiar with git.

 

Difference between Git fetch and git pull

There are two commands in Git to get the latest version from the remote branch to the local:
1.  git fetch : It is equivalent to fetching the latest version from the remote to the local, it will not automatically merge

    
Git fetch origin master
git log -p master..origin/master
git merge origin/master

    The meaning of the above commands:
   first download the latest version from the master branch of the remote origin to the origin/master branch,
   then compare the difference between the local master branch and the origin/master branch, and
   finally merge
   the above process in the following clearer way to proceed:

git fetch origin master:tmp
git diff tmp 
git merge tmp

    Get the latest version from the remote to the local test branch and
   then compare and merge
2.  git pull : It is equivalent to getting the latest version from the remote and merging to the local

git pull origin master

The above commands are actually equivalent to git fetch and git merge
. In actual use, git fetch is safer
because we can check the update before merging, and then decide whether to merge or not.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326572485&siteId=291194637