0% found this document useful (0 votes)
44 views51 pages

Git+&+Github+Course +Undoing+Stuff

The document discusses various commands in Git like checkout, restore, switch and reset that allow undoing changes, restoring files, switching branches and resetting commits. It explains concepts like detached HEAD and how these commands can be used to view previous commits, discard changes, restore files and undo commits.

Uploaded by

suresh chaudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views51 pages

Git+&+Github+Course +Undoing+Stuff

The document discusses various commands in Git like checkout, restore, switch and reset that allow undoing changes, restoring files, switching branches and resetting commits. It explains concepts like detached HEAD and how these commands can be used to view previous commits, discard changes, restore files and undo commits.

Uploaded by

suresh chaudhary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Undoing Stuff &

Time Traveling
Checkout
The git checkout command is like a Git Swiss Army knife.
Many developers think it is overloaded, which is what lead to
the addition of the git switch and git restore commands

We can use checkout to create branches, switch to new


branches, restore files, and undo history!
Checkout
We can use git checkout commit <commit-hash>
to view a previous commit.

Remember, you can use the git log command to view ❯git checkout d8194d6
commit hashes. We just need the first 7 digits of a
commit hash.

Don't panic when you see the following message...


Detached HEAD??
You are in 'detached HEAD' state. You can
look around, make experimental changes and
commit them, and you can discard any commits
you make in this state without impacting any
branches by switching back to a branch.
What On Earth
Is Going On??
HEAD
Usually, HEAD points to a specific branch reference
rather than a particular commit.

Master

987fac... d8194d6 171615...


How It Works HEAD
HEAD is a pointer to the current branch reference
The branch reference is a pointer to the last
commit made on a particular branch
Master

987fac... d8194d6 171615...


When we make a new commit, the branch reference
is updated to reflect the new commit.
The HEAD remains the same, because it's pointing
at the branch reference
HEAD

Master

987fac... d8194d6 171615... f9e321...


When we make a new commit, the branch pointer
is updated to reflect the new commit.
The HEAD remains the same, because it's
pointing at the branch reference
HEAD
HEAD still points to master
Master

987fac... d8194d6 171615... f9e321...


HEAD
When you switch branches, HEAD is updated to
point to the specific branch reference.
master
Here, HEAD is pointing to master

bugfix
If we switch to the bugfix branch, HEAD is now
pointing at the bugfix reference.
master

bugfix
❯ git switch bugfix
HEAD
This is all to say that HEAD usually refers
to a branch NOT a specific commit. master

bugfix

HEAD
Back to this
Detached HEAD thing
HEAD

Master

987fac... d8194d6 171615...


When we checkout a particular commit,
HEAD points at that commit rather than
at the branch pointer. ❯git checkout d8194d6

HEAD Master

987fac... d8194d6 171615...

DETACHED HEAD!
Detached HEAD
Don't panic when this happens! It's not a bad thing!
❯ git checkout <commit-hash>
You have a couple options:
1. Stay in detached HEAD to examine the contents of
the old commit. Poke around, view the files, etc.
2. Leave and go back to wherever you were before -
reattach the HEAD
3. Create a new branch and switch to it. You can now
make and save changes, since HEAD is no longer
detached.
If you checkout an old commit and
decide you want to return to where you ❯git checkout d8194d6
were before....

HEAD Master

987fac... d8194d6 171615...

DETACHED HEAD!
❯git switch master

Simply switch back to whatever branch you HEAD


were on before (master in this example).

Master

987fac... d8194d6 171615...

RE-ATTACHED HEAD!
HEAD Master
Suppose you want to go back to an old
commit and make some new changes

987fac... d8194d6 171615...


HEAD Master

❯git checkout d8194d6

987fac... d8194d6 171615...

Checkout the old commit.


Now in detached HEAD state.
Master

❯git switch -c newbranch

987fac... d8194d6 171615...

While in detached HEAD,


Make a new branch and switch to it.
newbranch
Head is now back to pointing at a
branch reference!
HEAD
Master
❯ git add .
❯ git commit -m "new commit"

987fac... d8194d6 171615...

Now on the new branch, make as many 4a4d6

new commits as you want!

It's like you time traveled! We went back


to an old commit and made a new newbranch
branch based on it.
HEAD
Checkout
git checkout supports a slightly odd syntax for
referencing previous commits relative to a particular
commit.

HEAD~1 refers to the commit before HEAD (parent)


❯ git checkout HEAD~1

HEAD~2 refers to 2 commits before HEAD (grandparent)

This is not essential, but I wanted to mention it because


it's quite weird looking if you've never seen it.
HEAD

Master
HEAD~3 HEAD~2 HEAD~1

987fac... d8194d6 171615... f9e321...


Discarding
Changes
Suppose you've made some changes to a file but don't
want to keep them. To revert the file back to whatever
it looked like when you last committed, you can use:
❯ git checkout HEAD <file>
git checkout HEAD <filename> to discard any changes
in that file, reverting back to the HEAD.
Another Option
Here's another shorter option to revert a file...
❯ git checkout -- <file>
Rather than typing HEAD, you can substitute -- followed
by the file(s) you want to restore.
Restore
git restore is a brand new Git command that helps with
undoing operations.

Because it is so new, most of the existing Git tutorials


and books do not mention it, but it is worth knowing!

Recall that git checkout does a million different things,


which many git users find very confusing. git restore was
introduced alongside git switch as alternatives to some
of the uses for checkout.
Unmodifying Files
with Restore
Suppose you've made some changes to a file since your ❯ git restore <file-name>
last commit. You've saved the file but then realize you
definitely do NOT want those changes anymore! NOTE: The above command is not "undoable"
If you have uncommited changes in the file,
To restore the file to the contents in the HEAD, they will be lost!
use git restore <file-name>
Unmodifying Files
with Restore
git restore <file-name> restores using HEAD as the
default source, but we can change that using ❯git restore --source HEAD~1 app.js
the --source option.

For example, git restore --source HEAD~1 home.html


will restore the contents of home.html to its state from
the commit prior to HEAD. You can also use a
particular commit hash as the source.
Unstaging Files
with Restore
If you have accidentally added a file to your
staging area with git add and you don't wish to ❯git restore --staged <file-name>
include it in the next commit, you can use git restore
to remove it from staging.

Use the --staged option like this:


git restore --staged app.js
Feeling Confused?
git status reminds you what to use!
Git Reset
Suppose you've just made a couple of commits on the
master branch, but you actually meant to make them on
a separate branch instead. To undo those commits, you ❯ git reset <commit-hash>
can use git reset.

git reset <commit-hash> will reset the repo back to a


specific commit. The commits are gone
OH NO! I didn't mean to make that commit here!
Working Directory Staging Area Repository

modified about.html

created lisa.jpg

39c3fdd

0026739

bb43f1f
❯ git reset 0026739

Working Directory Staging Area Repository


modified about.html

created lisa.jpg

0026739

bb43f1f
❯ git reset 0026739

Working Directory Staging Area Repository


modified about.html

created lisa.jpg

The file contents are still here!

Commit(s) are gone

0026739

bb43f1f
Reset --hard
If you want to undo both the commits AND the actual
changes in your files, you can use the --hard option. ❯ git reset --hard <commit>

for example, git reset --hard HEAD~1 will delete the


last commit and associated changes.
OH NO! I don't want that commit OR the changes
Working Directory Staging Area Repository

modified about.html

created lisa.jpg

39c3fdd

0026739

bb43f1f
❯ git reset --hard 0026739

Working Directory Staging Area Repository


The changes in the file(s)
are gone too!

Commit(s) are gone

0026739

bb43f1f
git revert
Yet another similar sounding and
confusing command that has to do
with undoing changes.
Git Revert
git revert is similar to git reset in that they both "undo"
changes, but they accomplish it in different ways.

git reset actually moves the branch pointer backwards,


❯ git revert <commit-hash>

eliminating commits.

git revert instead creates a brand new commit which


reverses/undos the changes from a commit. Because it
results in a new commit, you will be prompted to enter a
commit message.
"Undoing"
With Reset
HEAD

Master
❯git reset HEAD~2

HEAD

Master The branch pointer is moved back to an earlier


commit, erasing the 2 later commits
"Undoing"
With Revert
HEAD

Master
❯git revert 51494a6
HEAD

Master

51494a6

This new commit


reverses the changes
from 51494a6
Which One
Should I Use?
Both git reset and git revert help us reverse changes, but there is
a significant difference when it comes to collaboration (which
we have yet to discuss but is coming up soon!)

If you want to reverse some commits that other people already


have on their machines, you should use revert.

If you want to reverse commits that you haven't shared with


others, use reset and no one will ever know!
HEAD

Master

HEAD
1 2 3 My Local Repo Master

HEAD 1 2 3
Master

1 2 3 4
HEAD

Master

HEAD

1 2 3 Master My Changes

HEAD 1
Master
I use git reset to remove commits that
1 2 3 4 I already shared with my team!
HEAD

Master

HEAD

1 2 3 Master My Changes

HEAD 1
Master
This makes their lives harder. I altered
1 2 3 4 history that they already have. BAD!
HEAD

Master

HEAD
1 2 3 My Local Repo Master

HEAD 1 2 3
Master

Let's try again...


1 2 3 4
HEAD

Master

1 2 3 My Changes
HEAD

Master

HEAD
1 2 3
Master
I use git revert to reverse the same
1 2 3 4 commits as before, by ADDING a
new commit to the chain
HEAD

Master

1 2 3 My Changes
HEAD

Master

HEAD
1 2 3
Master
My team can merge in the new
1 2 3 4 "undo" commit without issue.
I didn't alter history.

You might also like