DEV Community

Cover image for Git and GitHub: The Complete Guides - Chapter 4 (More Git Basics)
Goran Kortjie
Goran Kortjie

Posted on • Updated on

Git and GitHub: The Complete Guides - Chapter 4 (More Git Basics)

goran-hello

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:

  • Diff
  • Restore
  • Switch

Diff

Compare file diff(erences) while working

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.

investigate

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:

git diff
Enter fullscreen mode Exit fullscreen mode

As you can see, Git tells us we have two versions we are comparing:

diff --git a/index.html b/index.html
Enter fullscreen mode Exit fullscreen mode

Then we can see their hashes(ID's) and file permissions:

index 8774966..07898f7 100644
Enter fullscreen mode Exit fullscreen mode

We see the line in the file that has been changed:

@@ -8,7 +8,8 @@
Enter fullscreen mode Exit fullscreen mode

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.

Git-diff

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
Enter fullscreen mode Exit fullscreen mode

This will give us the differences from the staging area. If we are happy with it, we can now commit the changes to history.

git-diff

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:

git diff
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

compare-diff

Thats two ways how we can compare our current state of our commit history with any other point in that history.

Restore

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
Enter fullscreen mode Exit fullscreen mode

Before 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.

checkout-two

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:

git restore
Enter fullscreen mode Exit fullscreen mode

This command is followed by the file we want to restore. For example:

git restore index.html
Enter fullscreen mode Exit fullscreen mode

git-retore

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.

The git restore command will only work on newer versions of Git, git checkout which preceded the git restore will work on all versions of Git.

Similar to 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
Enter fullscreen mode Exit fullscreen mode

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.

git-restore

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.

git-restore-detached

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.

Switch

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 
Enter fullscreen mode Exit fullscreen mode

git-switch-branch

We do this by running, For example:

git switch -c mybranch
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

git-switch-new

A command that allows you to quickly to back to the master branch is:

git switch -
Enter fullscreen mode Exit fullscreen mode

or

git switch master
Enter fullscreen mode Exit fullscreen mode

git-switch

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.

goodbye

Discussion (0)