One of the most characteristic and some with any version control system is to "undo (undo)" Your ability to erroneous operation. In Git, "undo" contains a number of slightly different function.
When you make a new submission time, Git will store your code base at that particular point in time snapshots; then, you can use Git to return to an earlier version of your project.
In this post, I will explain some of you need to "undo" changes have been made common scenarios, and the best way to use Git conduct these operations.
Revoke a "disclosed" change
Scenario: You have performed git push, your changes are sent to the GitHub, and now you are aware of these commit one is a problem, you need to undo that a commit.
Methods: git revert < SHA >
Principle: git revert will produce a new commit, and it specifies the SHA corresponding commit the opposite (or is reversed). If the original commit is "material", the new commit is the "antimatter" - any deleted from the original commit where content will be added back in the new commit any efforts in the original commit was added content will be in the new commit It has been dropped.
Git It is the safest, the most basic revoked scene, because it does not change the history - so you can now git push a new "reverse" commit you commit to offset errors committed.
Fixed last commit message
Scenario: You have the last commit message in a clerical error, has been performed git commit -m "Fxies bug # 42", but the git push until you realize that the message should be "Fixes bug # 42".
Methods: git commit --amend or git commit --amend -m "Fixes bug # 42"
Principle: git commit --amend will use a new commit update and replace the latest commit, this will commit any new content and a content commit together. If the current does not propose any changes, this operation is only the last commit message rewrite it.
Undo "local" modification
Scene: A cat walked from the keyboard, inadvertently saved the changes, and then destroyed the editor. However, you do not commit the changes. You want to restore the file to modify all content - exactly the same as the last commit time.
Methods: git checkout - < bad filename >
Principle: git checkout will modify the working directory of the file to a previous state Git records. You can provide a name you want to return or branch specific SHA, or by default, Git will think you want to checkout the HEAD, checkout the current branch last commit.
Remember: Any changes you use this method of "undo" will really disappear completely. Because they have never been submitted, so after Git can not help us to recover them. You have to make sure you understand what you throw away in this operation in what is! (Perhaps the first use of git diff confirm)
Reset "local" modification
Scene: You commit locally something (not yet push), but all these things are very bad, you want to undo the preceding three commits - as if they never happened.
Methods: git reset < last good SHA > or git reset --hard
Principle: git reset your code library history will return to the specified SHA state. These submissions like this never happened. By default, git reset will keep working directory. Thus, the author is not, but the content is still on the disk. This is a safe choice, but usually we want to step on the "undo" submission and content - this is the function --hard options.
Revocation "Local Edit" then after recovery
Scenario: You submitted several commit, then git reset --hard revoke these changes (see above), and then you realize: you want to restore these changes!
Methods: git reflog and git reset or git checkout
Principle: git reflog for historical restoration projects is a fabulous resource. You can restore almost anything - anything you commit something too - just by reflog.
You may already be familiar with the git log command, it will display a list of commit. git reflog is similar, but it shows a list of changes in the time a HEAD.
It involves only HEAD change. You switch branches with git commit to commit, and when used git reset revocation commit, HEAD will change, but when you use git checkout - < bad filename > revoking (as we mentioned in the previous case), HEAD and It will not change - As mentioned earlier, these changes have never been submitted so reflog can not help us to recover them.
git reflog not always kept. Git will regularly clean up those "less than" objects. Do not expect to submit also been lying there a few months ago.
Your reflog is yours, just for you. You can not use git reflog to restore another developer does not push over commit.
So ... how you use reflog to "recover" before "undo" the commit it? It depends on what you want to do in the end is what:
If you want to accurately restore the history of the project to a point in time, use git reset --hard < SHA >
If you want to recreate the working directory of one or more files, so that they return to the state a point in time, use git checkout < SHA > - < filename >
If you want to commit them in the one to resubmit your code library, use git cherry-pick < SHA >
Another approach is the use of branch
Scenario: You were in a number of submissions, and then realize that you start check out the master branch. You want these submissions into another characteristic (feature) in the branch.
Methods: git branch feature, git reset --hard origin / master, and git checkout feature
How it works: you may be used to create a new branch with git checkout -b < name > - This is creating a new branch and immediately check out the popular shortcut - but you do not want to immediately switch branches. Here, git branch feature to create a new branch called feature and point your latest commit, but still lets you check out the master branch.
Next, before submitting any new commit, use git reset --hard rewind the master branch origin / master. But do not worry, those who commit still feature in the branch.
Finally, git checkout to switch to a new feature branch, and let all your most recent results of the work are intact.
Timely branch, eliminating the cumbersome
Scenario: You create a feature branch based on the master branch, but has lagged behind the master branch origin / master lot. The branch is now master and origin / master synchronization feature you want to submit from now on, instead began to lag from a lot of places.
Methods: git checkout feature and git rebase master
Principle: To achieve this effect, you could have by git reset (without --hard, so you can modify the retention on disk) and git checkout -b resubmit modified, but to do so, you You will lose commit history. We have a better way.
git rebase master will do the following things:
First, it will find you check out the common ancestor of the current branch and master branch.
It then reset the current branch to check out that common ancestor, in a temporary holding area to store all previous submissions.
It then check out the current branch mentioned end portion of the master, and from the temporary storage area re-deposited after the last commit commit to submit to the master branch.
A large number of undo / redo
Scenario: You start in a certain direction to achieve a feature, but you realize halfway another program better. You already have submitted a dozen times, but now you need only part of it. You want other unwanted submit all disappear.
Methods: git rebase -i
Principle: -i parameter allows rebase into the "interactive mode." It began like rebase discussed earlier, but before any re-submitted, it will pause and allow you to modify each submission in detail.
rebase -i will open your default text editor, which lists the candidate submission.
Front two are key: the first one is selected command, corresponding to the second column in the SHA determined commit. By default, rebase -i assumed that each commit should be utilized by the pick command.
To drop a commit, simply delete the line in the editor on the line. If you no longer need to project that several errors in the submission, you can delete the previous example 1,3,4 line.
If you need to keep the content of the commit, but the commit message editor, you can use reword command. The first column in the pick replaced reword (or directly r). Some people may think here direct overwrite commit message on the line, but this does not work -rebase -i ignores anything SHA front row. It is just behind the text to help us remember 0835fe2 is Gansha. When you complete rebase -i operation, you will be prompted to enter any commit message needs to be written.
If you need to commit two merged together, you can use the squash or fixup command
squash and fixup will be "up" merge - commit with these two commands will be incorporated into its front in a commit. In this example, 0835fe2 and 6943e85 will be merged into a single commit, 38f5e4e and af67f82 will be merged into another.
If you choose squash, Git will prompt us to commit a new consolidation of the new commit message; fixup is the first consolidated list in a commit message directly to the newly merged commit. Here, you know af67f82 is a "finished finished ...." The commit, so you will keep 38f5e4e commit message, but will give you merged 0835fe2 and 6943e85 new commit to write a new message.
You save time and exit the editor, Git will order from the top in the end portion of the use of your commit. You can save the changes before the commit order to change the order of use. If you wish, you can also arrange the following af67f82 and 0835fe2 merged together
Repair earlier commit
Scenario: You're in a much earlier commit forget to add a file, if an earlier commit forgotten file can contain this would be great. You do not push, but this is not a recent commit, so you can not use commit --amend.
Methods: git commit --squash < SHA of the earlier commit > and git rebase --autosquash -i < even earlier SHA >
Principle: git commit --squash will create a new commit, it comes with a commit message, similar to squash Earlier commit!. (You can also create a similar commit the commit message with a manual, but commit --squash can help you save input work.)
If you do not want to be prompted to enter a new merge commit new commit message, you can also use git commit --fixup. In this case, you are likely to use commit --fixup, because you just want to use the early commit the commit message rebase time.
rebase --autosquash -i activates an interactive rebase editor, but the editor is open, in the commit list in any squash! and fixup! of commit have been paired to the target commit a
Using --squash and --fixup, you may not remember you want to fix the commit SHA - and just remember that it is the first one in front of the first five or commit. You will find the Git ^ and ~ operator particularly useful. HEAD ^ before a commit HEAD of. Previous HEAD HEAD ~ 4 is the fourth - or considered together, the penultimate 5 commit.
Stop following a document
Scenario: you accidentally put application.log Curry added to the code, and now every time you run the application, Git will report application.log there are uncommitted changes. You put .gitignore * .login file, the file is still in the code library - how can you tell Git "undo" track on this document it?
Methods: git rm --cached application.log
Principle: Although .gitignore prevent modification Git trace files, and even does not care about the file exists, but only for those who had never been tracking files. Once a file is added and submitted, Git will continue to focus on changing the file. Similarly, if you use git add -f to force or covered .gitignore, Git will keep track of the situation to change. Then you do not have to use -f to add this file.
If you want to delete a file that should be ignored from the Git object tracking, git rm --cached will remove it from the track object, but let the files remain intact on the disk. Because now it has been ignored, you git status will no longer see in this file, it will not accidentally modify the submission of the document.
This is how to undo any actions in Git, methods. To learn more about the Git commands used in this article, please see the following related documents: