Before we continue with branching and believe me there is a lot to cover there. I want to take this moment to address some things we saw but didn't fully discuss.
Here we are going to cover:
When we are making changes to our files, staging them and finally committing them to history, we might want to compare the changes in history.
Lets modify our index.html file and we can use those changes to look and compare different versions in history. Once we modified the file and saved, we can see the status with
git status. Nothing new here, we see that we have made changes to our file but not staged for a commit.
But lets say for example, we see this change and we want to view those changes. We can run the following command to view the changes that Git does not know about:
As you can see, Git tells us we have two versions we are comparing:
diff --git a/index.html b/index.html
Then we can see their hashes(ID's) and file permissions:
index 8774966..07898f7 100644
We see the line in the file that has been changed:
@@ -8,7 +8,8 @@
Finally the actual changes in question. Here notice that where we added new lines, we see a green plus. Where we removed lines we see a red minus.
Now lets stage the index.html file by using the command
git add index.html. Now when we run
git status the file is in the staging area and ready to be committed. If we want to have a look or be reminded of what the changes are in the staging area. If we run
git diff nothing will return.
This is because
git diff is showing us the differences from what Git knows to what the actual changes are. Since Git already knows about these changes because it's in the staging area, there are no differences Git does not know about.
If want want to look at the differences in the staging area we need to run the command:
git diff --staged
This will give us the differences from the staging area. If we are happy with it, we can now commit the changes to history.
Now that we have committed our file, its state has been set in history. If we want to compare our current state with any previous state,
git diff allows us to do this as well, by running the command:
This command is followed by the ID of the commit we want to compare or by using the HEAD. This command will allow us to refer to any point in time, relative to HEAD (which in this case is the current state of our project). If you remember from the Extended chapter, to see the previous state of our commit history relative to our current state we use
HEAD~1 and we can go as many commits back as we want. For example if we want to go two commits back we would use
HEAD~2 and so on...
So by running the command:
git diff HEAD~1
We see the same output we saw before. Although this time we are comparing the current state with the previous state.
If we have a large Git history, it's not realistic for us to count how many commits back or forward, relative to where we currently are. So we can always make any two comparisons in time by using looking at the commit ID.
One way to get the ID is by running the command:
git log --oneline. Then we can compare our current state with any of the states based on their ID. We do this by running the command, for example:
git diff d61a34e
Thats two ways how we can compare our current state of our commit history with any other point in that history.
Now that we know how to compare our current state with any state in our history, it is time to go through the process of restoring a state from our history. In order to restore files from our past, we need to learn a new Git command.
git restore we used another familiar command to move around our history
git checkout. Checkout is a command that essentially moves around the HEAD to a different location in our history. However since Git 2.23, checkout was split into two functions. One called Restore and another called Switch.
First we can modify any file in our project directory for example: the
index.html. after making changes, we can save it and then check the difference. If we run
git status it gives us a hint how we can deal with this. On a newer version of Git it will say use git restore to discard changes in working directory, in older versions it might say something along the line of
git reset. We can use these commands to reset/restore the changes we made to our file.
We use the following command:
This command is followed by the file we want to restore. For example:
git restore index.html
If we now check the status by using
git status. You will notice our index.html file doesn't have anymore changes. If you go to the index.html file you will see the changes we made are gone, This is how we can restore our current state to the last known state that Git knows of.
git restorecommand will only work on newer versions of Git,
git checkoutwhich preceded the
git restorewill work on all versions of Git.
git checkout we can use
git restore to restore a file to a state in another commit. This can be a file you already have and you want that specific version in that previous state or it can be a file you deleted and committed that deletion.
If we look at our history of commits using the
git log --oneline command. For example we want to restore our index.html file to the very first commit we made. We can refer to this commit either releatively by using HEAD or we can use the unique identifier of the commit.
We can do this by running the command:
git restore --source d61a34e index.html
If we look at
git status we can see the file has been changed. If we look inside our index.html file, we can see our file has been restored to that version in time.
If we want to restore our file to the previous commit and we forget to specify which file we want to restore, then we get an error.
However this is not the case with
git checkout. As we know when you run the
git checkout command without specifying the file. You are set into a Detached HEAD state.
As you can see when you end up in this Detached HEAD state. You can run a few commands that allow you to create a new Branch from this Detached state, to retain commits you create. Since usually when you make commits in a Detached HEAD state the commits are not saved.
To create a new branch and switch into the branch, relative to HEAD, we use the command:
git switch -c
We do this by running, For example:
git switch -c mybranch
This command is followed by the name of the branch you want to create.
If you remember from previous chapters, we can also create a branch by using the command:
git branch followed by the name of the branch.
We can see the list of all our branches, be they local or remote is the command:
git branch -a
A command that allows you to quickly to back to the master branch is:
git switch -
git switch master
If I am being honest, with the introduction of these newer Git commands I am left a bit more confused about the concept, especially when it comes to restore and switch. Seems like new ways to do the same old stuff.
However I do feel it's necessary to know of these commands so that they don't confuse you when you see them in the wild.
Some practice will definitely help me understand this even more. So I do hope you enjoyed this one. I hope you see you in the next.