Resetting Commits

Reset vs Revert

At first glance,resetting_might seem coincidentally close to_reverting, but they are actually quite different. Reverting creates a new commit that reverts or undos a previous commit. Resetting, on the other hand,_erases_commits!

⚠️ Resetting Is Dangerous ⚠️

You've got to be careful with Git's resetting capabilities. This is one of the few commands that lets you erase commits from the repository. If a commit is no longer in the repository, then its content is gone.

To alleviate the stress a bit, Git_does_keep track of everything for about 30 days before it completely erases anything. To access this content, you'll need to use thegit reflogcommand. Check out these links for more info:

Relative Commit References

You already know that you can reference commits by their SHA, by tags, branches, and the specialHEADpointer. Sometimes that's not enough, though. There will be times when you'll want to reference a commit relative to another commit. For example, there will be times where you'll want to tell Git about the commit that's one before the current commit...or two before the current commit. There are special characters called "Ancestry References" that we can use to tell Git about these relative references. Those characters are:

  • ^ – indicates the parent commit
  • ~ – indicates the _first _parent commit

Here's how we can refer to previous commits:

  • the parent commit – the following indicate the parent commit of the current commit
    • HEAD^
    • HEAD~
    • HEAD~1
  • the grandparent commit – the following indicate the grandparent commit of the current commit
    • HEAD^^
    • HEAD~2
  • the great-grandparent commit – the following indicate the great-grandparent commit of the current commit
    • HEAD^^^
    • HEAD~3

The main difference between the^and the~is when a commit is createdfrom a merge. A merge commit has_two_parents. With a merge commit, the^reference is used to indicate the_first_parent of the commit while^2indicates the_second_parent. The first parent is the branch you were on when you rangit mergewhile the second parent is the branch that was merged in.

It's easier if we look at an example. This what mygit logcurrently shows:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
*   796ddb0 Merge branch 'heading-update'
|\  
| * 4c9749e (heading-update) Set page heading to "Crusade"
* | 0c5975a Set page heading to "Quest"
|/  
*   1a56a81 Merge branch 'sidebar'
|\  
| * f69811c (sidebar) Update sidebar with favorite movie
| * e6c65a6 Add new sidebar content
* | e014d91 (footer) Add links to social media
* | 209752a Improve site heading for SEO
* | 3772ab1 Set background color for page
|/  
* 5bfe5e7 Add starting HTML structure
* 6fa5f34 Add .gitignore file
* a879849 Add header to blog
* 94de470 Initial commit

Let's look at how we'd refer to some of the previous commits. SinceHEADpoints to the9ec05cacommit:

  • HEAD^ is the db7e87a commit
  • HEAD~1 is also the db7e87a commit
  • HEAD^^ is the 796ddb0 commit
  • HEAD~2 is also the 796ddb0 commit
  • HEAD^^^ is the 0c5975a commit
  • HEAD~3 is also the 0c5975a commit
  • HEAD^^^2 is the 4c9749e commit (this is the grandparent's ( HEAD^^ ) second parent ( ^2 ))

Which Commit?

Use this repository to answer the following quiz questions:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
*   796ddb0 Merge branch 'heading-update'
|\  
| * 4c9749e (heading-update) Set page heading to "Crusade"
* | 0c5975a Set page heading to "Quest"
|/  
*   1a56a81 Merge branch 'sidebar'
|\  
| * f69811c (sidebar) Update sidebar with favorite movie
| * e6c65a6 Add new sidebar content
* | e014d91 (footer) Add links to social media
* | 209752a Improve site heading for SEO
* | 3772ab1 Set background color for page
|/  
* 5bfe5e7 Add starting HTML structure
* 6fa5f34 Add .gitignore file
* a879849 Add header to blog
* 94de470 Initial commit

QUESTION 1 OF 4

Which commit is referenced byHEAD~6?

  • 4c9749e

  • 0c5975a

  • 1a56a81

  • f69811c

  • e014d91

  • 209752a

SUBMIT

You did so well on that last one, why not give this one a go! Using the same repository, which commit is referenced byHEAD~4^2?

SUBMIT: f69811c

That's right! HEAD~4 references the fourth parent commit of the current one and then the ^2 tells us that it's the _second _parent of the merge commit (the one that got merged in!).

Thegit resetCommand

Thegit resetcommand is used to reset (erase) commits:

$ git reset <reference-to-commit>

It can be used to:

  • move the HEAD and current branch pointer to the referenced commit
  • erase commits
  • move committed changes to the staging index
  • unstage committed changes

Git Reset's Flags

The way that Git determines if it erases, stages previously committed changes, or unstages previously committed changes is by the flag that's used. The flags are:

  • --mixed : last commit moves to working directory (default)

  • --soft: last commit moves to staging index

  • --hard: last commit moves to trash

It's easier to understand how they work with a little animation.

VIDEO

💡 Backup Branch 💡

Remember that using thegit resetcommand will_erase_commits from the current branch. So if you want to follow along with all the resetting stuff that's coming up, you'll need to create a branch on the current commit that you can use as a backup.

Before I do any resetting, I usually create abackupbranch on the most-recent commit so that I can get back to the commits if I make a mistake:

$ git branch backup

Reset's--mixedFlag

Let's look at each one of these flags.

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
* 796ddb0 Merge branch 'heading-update'

Using the sample repo above withHEADpointing tomasteron commit9ec05ca, runninggit reset --mixed HEAD^will take the changes made in commit9ec05caand move them to the working directory.

The Terminal application showing the result of resetting with the--mixedflag. The changes are unstaged.

💡 Back To Normal 💡

If you created thebackupbranch prior to resetting anything, then you can easily get back to having themasterbranch point to the same commit as thebackupbranch. You'll just need to:

  1. remove the uncommitted changes from the working directory
  2. merge backup into master (which will cause a Fast-forward merge and move master up to the same point as backup )
$ git checkout -- index.html
$ git merge backup

Reset's--softFlag

Let's use the same few commits and look at how the--softflag works:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
* 796ddb0 Merge branch 'heading-update'

Runninggit reset --soft HEAD^will take the changes made in commit9ec05caand move them directly to the Staging Index.

The Terminal application showing the result of resetting with the--softflag. The changes are moved to the Staging Index.

Reset's--hardFlag

Last but not least, let's look at the--hardflag:

* 9ec05ca (HEAD -> master) Revert "Set page heading to "Quests & Crusades""
* db7e87a Set page heading to "Quests & Crusades"
* 796ddb0 Merge branch 'heading-update'

Runninggit reset --hard HEAD^will take the changes made in commit9ec05caand erases them.

The Terminal application showing the result of resetting with the--hardflag. The changes are moved erased.

Now it's your turn!

Refer to the following repository:

* e014d91 (HEAD -> master, footer) Add links to social media
* 209752a Improve site heading for SEO
* 3772ab1 Set background color for page
* 5bfe5e7 Add starting HTML structure
* 6fa5f34 Add .gitignore file
* a879849 Add header to blog
* 94de470 Initial commit

QUESTION 3 OF 4

What will happen to the changes from the3772ab1commit ifgit reset --hard HEAD~3is run? Will the changes be in the Staging Index, in the Working Directory, or complete erased?

  • Staging Index

  • Working Directory

  • erased

SUBMIT

QUESTION 4 OF 4

What will happen to the changes from the209752acommit ifgit reset --soft HEAD^^is run? Will the changes be in the Staging Index, in the Working Directory, or complete erased?

  • Staging Index

  • Working Directory

  • erased

SUBMIT

Reset Recap

To recap, thegit resetcommand is used erase commits:

$ git reset <reference-to-commit>

It can be used to:

  • move the HEAD and current branch pointer to the referenced commit
  • erase commits with the --hard flag
  • moves committed changes to the staging index with the --soft flag
  • unstages committed changes --mixed flag

Typically, ancestry references are used to indicate previous commits. The ancestry references are:

  • ^ – indicates the parent commit
  • ~ – indicates the first parent commit

Further Research

results matching ""

    No results matching ""