Book on the last, straight into the theme. If you follow the previous article, run git reset head test.txt and git checkout test.txt to discard the current changes so that the latest commit goes back to "commit temp," which runs git status and sees " Nothing to commit, working directory clean ". Here, "nothing to commit" indicates that the staging directory is empty, and "working directory Clean" indicates that your working directory has not been modified.
Back to this state is to facilitate our explanation below, at this time the Sourcetree status is: diff-Come, uncle to check your body
A good diff command can make me think of this wretched classic line, diff allows you to compare any two different states in the project. When it comes to comparisons, there is also source and target, so the most intuitive use of the diff command is actually git diff source target. Here the source and target are similar to those in checkout, which can be "commit hash", "branch Name", "Shortcut". For example, we would like to compare the first two commits in Figure 13 and run git diff ce81811 6382c7d to get the results shown below:
As you can see, the results of the comparison are actually based on target, which means that target has changed from source, and in the result of Figure 15, the Commit "6382c7d" is three fewer than "ce81811" and one line, with minus and Gash respectively. Similarly, using Git diff Master branch2 and git diff head branch2 The results are consistent with the above, and both the branch name and the "head" can be viewed as a commit shortcut.
This source and target are the easiest to understand and complex to do if we omit an argument. Like running git diff branch2 results as shown in the following illustration:
As you can see, the result of Figure 16 is the opposite of Figure 15. That is, git diff branch2 the same result as Git diff branch2 Head, that is, if only one argument is given, this argument is the latest commit for the branch that Source,target is currently in. Now that's the conclusion, right? Note that we are now in the "Scratch directory is empty" + "working directory Clean" situation, now we make the working directory into dirty try, give test.txt add a line of "Test 6" and save. Then try git diff branch2, and the result is as shown in Figure 17:
You can see that the new "Test 6" also goes in. It can be concluded that in the case of a working directory that is not clean, target defaults to represent the working directory. Whether this conclusion is still too early, if there is something in the staging directory. Running git add test.txt, and then continuing with Git diff branch2, finds that the result is consistent with Figure 17, which still doesn't explain the problem because the working directory is consistent with the staging directory (all to test 6). So let's add a line of "Test 7", when the working directory is "Test 7", the Staging directory is "Test 6", and then run Git diff branch2 and the "Test 7" line is added. At this point, we can basically conclude that target's default display is indeed the working directory.
Look at the omission of a parameter, the two parameters are omitted. Run git diff results in the following figure:
You can see that the comparison results in adding only "Test 7", so this time source is the staging directory, and Target is the working directory. To verify this, we run git add test.txt, add the "Test 7" modification to the staging directory, then run Git diff, and the result is empty because the staging directory and working directory are the same at this time. We do a commit git commit-m "commit 6,7" at this time, the staging directory is empty, the working directory clean, continue to run Git diff, or empty. Here we can conclude that if two parameters are omitted, the default source is the staging directory, and the default target is the working directory.
The previous situation involved "comparisons between various commits", "comparisons between commit and working directory," "Staging directory vs. working directory", so just one situation, I want to compare "staging directory" and "individual commit" how to do it all. To do this, let's start by adding a line of "Test 8" and saving it, then git add test.txt, and then add a line to "Test 9" in the edit test.txt, because registers has something and registers is different from the working directory. When you run Git diff--cached Branch2, you can find the result to be the following figure:
You can see from the diagram that "Test 8" is not in the "Test 9", indicating that target has become registers at this time.
Summarize the diff situation: git diff source Target Returns the result of target relative to source, where source and target can be commit's hash/branch name/shortcut If only one argument is given, This parameter is source, and the default target is the working directory, and if the working directory is clean, target is the latest commit for the current branch if none of the arguments are given, the default source is the staging directory, and the target or working directory If you want to make the staging directory a target, you need to use the--cached parameter
Before you go any further, just commit all the changes you've made and run git add test.txt and git commit-m "commit 8,9". Reset-You can do whatever you want with me.
The biggest advantage of versioning is that you can easily find the previous version and restore, so from this point of view the position of the Reset command is more important, can let you recklessly arbitrarily ravage the whole project. When it comes to recovery, there is also the concept of source and target, where source must be each commit (including branch names and shortcuts), and target may be either a staging directory or a working directory based on a different parameter or both target. For example, we select the current commit's parent commit as source, run git reset head~ test.txt, hint unstaged change, at this time Sourcetree uncommitted The status of the changes is as follows:
As you can see from Figure 20, the file status of the staging area is consistent with the parent commit, and the change is to subtract the two rows of "Test 8" and "Test 9", indicating that the working directory does not change (the working directory contains the two lines). You can see that the target in this case is actually a staging directory, and it does not change the working directory. So here, to make up for the lessons you owe, remember that we used git reset head when we did the reverse of git Add. Test.txt, in fact, is also the head state of the file restored to the registers, the working directory remains unchanged, and at that time the latest commit file status and working directory is consistent, so the resulting effect is "git add reverse operation." In fact, the head here can also be omitted because the default source is the latest commit for the current branch. Further, the filename test.txt can also be omitted, the default will be all the files in repo recovery, because at this time we have only this one file, so the effect is the same.
Again to introduce the other parameters of reset before, we want to reset just to reset off, very simple, just run again git reset can, because we need is actually "git add reverse operation." Then add parameters to run Reset,git reset--soft head~, note that we do not omit the filename, but once the--soft can not be with the file path, but to restore the entire project all the files, the results are as follows:
Can see, this reset directly changed head, the original "Commit 8,9" disappeared, the latest commit into the original head~, but this reset still did not modify the working directory, just "commit 8,9" file status add to the registers. Since there are--soft parameters, there must be--hard parameters, this time we keep the current state, run the git reset--hard ce81811 (the hash corresponding to the commit temp), and find that the current commit becomes "commit temp , and the staging area is empty, and the working directory is clean, stating that the--hard parameter, regardless of the state before the command is run, restores the working directory directly to the "commit temp" state, emptying the staging area. This is also more in line with the--hard word tough meaning. The Sourcetree state diagram at this point is:
As you can see from the diagram, the commit before "commit temp" has been lost and the entire project has been forcibly restored to the state of "commit temp".
To sum up the usage of reset: git reset [commit hash/Branch name/shortcut] [filename] is similar to "git add" to restore the file state of the commit to the staging area directly. Omitting a commit defaults to head, omitting the file name by default to all files. Changes only the staging directory, does not change the working directory, the current commit unchanged. git reset--soft [commit hash/Branch name/shortcut] Soft recovery restores the file state of the commit before the recovery to registers, and the current commit is a commit in the parameter. Only changes the staging directory, does not change the working directory, the current commit changes. git reset--hard [commit hash/Branch name/shortcut] Hard recovery, force the entire project to revert to the file status in the commit in the parameter, empty the staging directory, clean the working directory. The staging directory and working directory are changed at the same time, and the current commit changes.
Additional additions to the Reset command: The current head is already in "commit temp", and it is not the previous commit that can be found. Of course not, the reset of the operation can also be reset. There are two ways to do this: if you remember the hash of "commit 8,9" (as you can see in Figure 20), just git reset--hard 1a222c3, and the project is directly forced back to the state of the commit 8,9. If you don't remember, run Git reflog, and this command will output a list containing all the changes to the head. The following figure:
In Figure 23, you can see that the "Commit 8,9" corresponds to an entry of 1A222C3 head@{9}: Commit:commit 8, 9, the first is a commit hash, and the second is a natural shortcut. So long as we run git reset--hard head@{9}. Note that my reflog output may be different from yours, because I may have done a lot of extra work to write tutorials.
P.s. Obviously two is not enough Ah, found that the main Retina screen Tutanima large ... Let's talk about the rest in the next chapter.
from:http://pinkyjie.com/2014/08/09/git-notes-part-2/