Git and GitHub: The Complete Guides - Chapter 4 (More Git Basics)
Tags: github, git, webdev, beginners
Published: 2021-09-19 13:01:40

![goran-hello](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/inryduolut6c5xl2itax.gif)

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:**
<ul>
<li>Diff</li>
<li>Restore</li>
<li>Switch</li>
</ul>

<h2>Diff</h2>

####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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ssh951zggis7v181tzau.png)

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
```

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 <u>green plus</u>. Where we **removed lines** we see a <u>red minus</u>.

![Git-diff](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1vskwjqcuymne5cgnkf.gif)

 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.

![git-diff](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zvb3cdncrnbr73h0y0p.gif)

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
```

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
```
![compare-diff](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1g0q23kwg77xo9bso8n.gif)

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

<h2>Restore</h2>

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
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rx0npe89d5v3kytvo6w0.gif)

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 **diff**erence. 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<file> 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 <u>reset/restore</u> the changes we made to our file.

We use the following command:
```
git restore
```
This command is followed by the file we want to restore. For example: 
```
git restore index.html
```

![git-retore](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v44uar8me89zu3lzfvm8.gif)

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 <u>unique identifier</u> 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.

![git-restore](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wec9s4wghobop8gsuith.gif)

>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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5o9wzj1y26hkde9ktc96.gif)

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.

<h2>Switch</h2>

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 
```
![git-switch-branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/788llkjvmyo9sdb14aqg.gif)

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
```

![git-switch-new](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93958v3rl3lyy3y61kz8.gif)

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

``` 
git switch -
```
or

```
git switch master
```

![git-switch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oi91idxe6uu11ed2q7k9.gif)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6812kj50028lddh735tr.gif)