Sometimes you may find that you made changes that you aren't happy with. Wouldn't it be great if there was a simple way to undo all your changes and return to the last commit? Here are two ways!
>>>
The commands "git reset" and "git revert" both allow you to rollback changes to an older commit. While "git reset" is used for the local branch, "git revert" is typically used for remote branches that other people are likely to have based their work off of. Another difference is that "git reset" throws away the commit you are working on while "git revert" keeps the commit (preserving your changes) and gives you a fresh copy of the original beneath it.
>>>
Let's start with "git reset". There are three modes: --soft, --mixed(default), and --hard. Remember, all of these modes delete the commit you are working on; they differ in the ways that your changes are preserved (or not).
>>>
Use "git reset --hard <commit_ref>" when you've made changes you do not want to keep. Using this mode will not preserve any changes you have made. A typical use of "git reset --hard" is when you've made changes to the wrong branch. After moving these changes to the correct branch, it is useful to use "git reset --hard" to return the incorrectly modified branch back to its original state.
>>>
What if you want to discard some but not all changes you've made? Use "git reset --soft <commit_ref>" or "git reset <commit_ref>". These are the soft and mixed modes respectively. These commands will discard the working commit; however, the changes you've made will still be preserved as staged and unstaged changes respectively. In this way, you can selectively remove changes you dislike. Use a soft reset when most of the preserved changes will be kept (i.e. you will checkout/reset a smaller number of changes) and use a mixed reset when most of the preserved changes will be discarded (i.e. you only want to commit a couple of the preserved changes).
>>>
The second method is "git revert". Using "git revert" will create a new commit that will undo the changes that were made in a specified commit. For example, suppose I commit three files, 1, 2, and 3(<-HEAD). Using "git revert HEAD" will create a fourth commit where there are only files 1 and 2. In other words, the changes made at HEAD (commit 3) will be undone. Similarly, I could have used "git revert HEAD^" and this would have created a fourth commit with only files 1 and 3.
>>>
Notice that in the previous example the commit with files 1, 2, and 3 still exists in the commit history! Git revert allows you to keep track of the commits prior to the revert. Therefore, if we decided we actually needed those changes, we can return to them. If you recall, this is unlike reset which abandons the working commit. Additionally, reverting allows git to undo changes for everyone. If you simply reset, there will be nothing to tell git that everyone else's copy should remove unwanted changes. In other words, when others pull your changes, the deleted file will just sit in their repositories unmodified. Reverting allows git to process the removal as a commit and apply it to all downstream repositories.
>>>
Finally, one last thing! There is a shortcut to reverting consecutive commits! For example, suppose we commit five files separately and we want to remove the changes made in commits 2 through 4 (i.e. remove files 2, 3, and 4). Use this syntax: "git revert <older_ref>..<newer_ref>". The older ref is non-inclusive; therefore, it should be the parent of the oldest commit to be reverted. The newer ref is inclusive; meaning it is the newest commmit to be reverted. All commits in-between will also be reverted. For our example: "git revert HEAD~4..HEAD^". This will revert the child of HEAD~4 (= C2) through HEAD^ (=C4). Also, since each of the changes are likely to build off of each other when specifying a sequence of commits like that, it's only natural to undo them in reverse order, so running "git revert HEAD~4..HEAD^" will revert C4, C3, then C2.
>>>
Wow! You learned a lot (hopefully), prove yourself by completing the challenge! 
