Git & GitHub made simple - Undoing commits
Tags: github, git, beginners
Published: 2020-10-31 16:59:04

It can happen to everyone (especially at 4 am 😴) to push a commit and immediately realize that it shouldn't be done. Why mess with your commit history with other commits when you can just take one (or more) back steps?

As usual, for simplicity, let's establish a simple situation that allows us to easily understand the matter: you have connected your local project to a remote repository on GitHub via Git. You only have one `README.md` and obviously, the concept you are about to learn is independent of the type and number of files involved.
The `README.md` that you already pushed to the remote repository contains:
![git_initial_state](https://dev-to-uploads.s3.amazonaws.com/i/nn0pzfpsy2v67wrtv9kl.PNG)

Tap-tap-tap 👩‍💻, you tweak a little your file
![git_regrettable_commit](https://dev-to-uploads.s3.amazonaws.com/i/j4if5xfah8wzycixz28w.PNG)
and finally, decide it's time to `git add README.md`, thus `git commit -m "regrettable commit"`.
Oh, no! You would like to go back, so try `git status` but
![git_status](https://dev-to-uploads.s3.amazonaws.com/i/jd2nh1y5vgyym8ugiw2e.PNG)

Well, you must know that in the hidden `.git` folder 👻, among the various files, there is one called **HEAD**. It is a pointer to the commits. When it is not followed by anything else it is referencing the last commit made. Otherwise, by posting a ~ (*tilde*) and an integer to it you can point to previous commits:
* `HEAD` - the current commit
* `HEAD~1` - one commit ago
* `HEAD~2` - two commits ago

And so on...


Then, with a magical phrase, revert time to your heart's content:
`git reset HEAD~1`
![git_reset](https://dev-to-uploads.s3.amazonaws.com/i/w1hy9agrug2s2xdtw4c0.PNG)

Now the staging step is repopulated from what you added or changed before committing
![git_status_after_reset](https://dev-to-uploads.s3.amazonaws.com/i/xvnxiv392c4h9gfdq2kw.PNG)
You can fix what needs to be fixed and proceed as you already know: add, commit and push it.
![git_add_commit_push](https://dev-to-uploads.s3.amazonaws.com/i/xe5z9tq01xpygavgsff9.PNG)

***

## Bonus: compare the differences between two versions
As soon as you have reset to a previous commit you can quickly see the differences between it and the current one using `git diff`:
![git_diff](https://dev-to-uploads.s3.amazonaws.com/i/10t1qvxj5ok1c7rhjczo.PNG)

***

## When commits can't be counted on two hands 🤚✋
Using the `git log` command, you are shown a list of all commits (on this branch) in reversed chronological order (the latest at the top). 
![git_log](https://dev-to-uploads.s3.amazonaws.com/i/jcyoyxsxs39kohzklsfy.PNG)

> Notice how HEAD lays on the most recent commit

As you have certainly noticed, an ID is associated with each commit. Choose the commit you want to go back to, copy the ID, and type `git reset [commit_ID]`
Now in the staging step there are the files added or modified at that point and you are free to modify and commit them again.

One last note, in case you want to go back to a previous commit and have all the changes made completely removed, both from the IDE and from the staging step, you can add the `--hard` flag: `git reset --herd [commit_ID]`

> This command causes the **HEAD** pointer to now be associated with the newly obtained state. *Beware*: in fact, by doing so you have lost the various commits made after the one you just *hardly* returned to.

***

There is one last thing any programmer looking to improve should know, and that is the concept of forking. 
What do you say, tiger 🐯? [
Okay, let's go]() [VERY_VERY_SOON]

***

🐤 twitter: https://twitter.com/did0f