Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits
Summary
TLDRThis video offers an advanced Git tutorial for undoing mistakes and rolling back commits. It covers various scenarios, including fixing bad commit messages, undesired file changes, and committing to the wrong branch. The tutorial introduces commands like 'git checkout', 'git commit --amend', 'git cherry-pick', and 'git reset', explaining their impact on the Git history. It also addresses how to handle situations where changes have been pushed and need to be undone without altering the shared history, using 'git revert'. The script is designed for those familiar with basic Git commands, aiming to help maintain a clean and accurate project history.
Takeaways
- 😀 The video provides an advanced Git tutorial focusing on undoing mistakes and rolling back commits.
- 🔧 It explains the difference between Git commands that change history and those that don't.
- 📚 Assumes viewers have basic Git and command-line knowledge, with a reference to a beginner Git video.
- 📄 Demonstrates how to undo unwanted file changes using 'git checkout' without committing.
- 💾 Shows the process of correcting a bad commit message with 'git commit --amend'.
- ⚠️ Highlights the importance of not changing Git history if others have pulled changes to avoid conflicts.
- 🔀 Discusses how to handle committing to the wrong branch and moving commits to the correct branch using 'git cherry-pick'.
- 🗑️ Covers the three types of 'git reset': soft, mixed, and hard, and their effects on the repository.
- 🛠️ Introduces 'git clean' to remove untracked files and directories, useful for cleaning up after mistakes.
- 🔄 Explains 'git reflog' as a way to recover lost commits that were accidentally removed.
- 🔄 Details 'git revert' as a method to undo commits in a way that doesn't rewrite history, which is safe for shared branches.
Q & A
What are some common scenarios where you might need to undo changes in Git?
-Common scenarios include needing to revert bad commits, correcting mistakes, or rolling back changes that were not intended to be committed.
What command can you use in Git to discard changes in a file without staging them?
-You can use the command `git checkout -- <file>` to discard changes in a file without staging them.
How can you correct a commit message that was previously made in Git?
-You can correct a commit message by using `git commit --amend` followed by the correct message.
What is the difference between a soft, mixed, and hard reset in Git?
-A soft reset (`git reset --soft <commit>`) moves the HEAD to a specific commit but keeps the changes in the staging area. A mixed reset (`git reset --mixed <commit>`, which is the default) moves the HEAD and keeps changes in the working directory. A hard reset (`git reset --hard <commit>`) moves the HEAD and discards all changes.
How can you move a commit from one branch to another in Git?
-You can move a commit from one branch to another by using `git cherry-pick <commit-hash>` on the target branch.
What does `git reflog` show and when might you use it?
-`git reflog` shows a log of commits that you've interacted with, which can be useful for recovering commits that were accidentally lost, such as after a hard reset.
How can you undo a commit that has already been pushed to a remote repository?
-You can undo a commit that has been pushed by using `git revert <commit-hash>`, which creates a new commit that reverses the changes made by the specified commit.
What is a 'detached HEAD state' in Git and why should you be cautious about it?
-A 'detached HEAD state' occurs when you're not on any branch, typically after checking out a specific commit. You should be cautious because any commits made in this state will not be associated with any branch and could be lost if you switch branches without saving them.
How can you remove untracked files and directories from your Git repository?
-You can remove untracked files with `git clean -f` and untracked directories with `git clean -fd`.
What does `git diff` show when comparing two commits, and how can it be useful?
-`git diff` shows the differences between two commits, which can be useful for understanding exactly what changes were made and to verify that a revert commit undoes the intended changes.
Outlines
📚 Introduction to Undoing Mistakes in Git
The video begins with an introduction to advanced Git techniques for undoing mistakes and rolling back commits. The presenter assumes viewers have basic Git knowledge and offers a link to a beginner Git tutorial for those who need it. The focus is on commands that either alter or preserve the Git history, with an initial demonstration of a clean working directory and a single commit in the repository. The presenter then simulates a common mistake—making unwanted changes to a file—and shows how to revert these using 'git checkout' to restore the file to its last committed state.
🔄 Correcting Commit Messages and Amending Commits
The second paragraph delves into the scenario of correcting erroneous commit messages. The presenter demonstrates how to amend a commit message using 'git commit --amend'. It's highlighted that this changes the commit hash because the message is part of the commit's content. The video then addresses the situation of accidentally committing to the wrong branch and wanting to include changes in a different branch. The presenter uses 'git commit --amend' to include a forgotten file in the previous commit, illustrating how to maintain a clean commit history without additional commits.
🌿 Resolving Commits to the Wrong Branch
In this segment, the presenter tackles the common issue of committing to the wrong branch. Using 'git cherry-pick', the video shows how to move a commit from the master branch to a feature branch, thereby preserving the intended project structure. It's explained that 'git cherry-pick' creates a new commit on the target branch based on the source commit. The presenter then demonstrates how to remove the now undesired commit from the master branch using 'git reset', distinguishing between the three types of resets: soft, mixed, and hard. Each reset method is tested, showing their effects on the repository's state.
🗑️ Reverting Changes with git reset and git clean
The fourth paragraph explains how to use 'git reset' to remove commits that were made in error. The presenter uses 'git reset --hard' to revert all changes back to a single initial commit, cautioning that this method is risky as it can permanently delete changes. To further clean up, 'git clean' is introduced to remove untracked files and directories, ensuring the working directory is completely free from unintended changes. The presenter also discusses the importance of using these commands cautiously, especially when changes have been shared with others.
🔐 Recovering Lost Commits with git reflog
The final paragraph addresses the recovery of commits that were accidentally removed using 'git reset --hard'. The presenter introduces 'git reflog', which logs all actions that change the repository's state, allowing users to find and recover lost commits. By checking the reflog, the presenter locates the hash of a commit that was mistakenly deleted and restores it using 'git checkout'. The video concludes with a discussion on 'git revert', which is used to undo commits in a way that doesn't rewrite history, making it safe for collaborative environments.
Mindmap
Keywords
💡Git
💡Commit
💡Checkout
💡Diff
💡Amend
💡Branch
💡Cherry-pick
💡Reset
💡Reflog
💡Revert
Highlights
Introduction to advanced Git techniques for undoing mistakes and rolling back commits.
Assumption of basic Git command line functionality knowledge.
Demonstration of a clean working directory and initial repository state.
Explanation of using 'git checkout' to undo file changes without committing.
Example of committing changes with an incorrect commit message.
Use of 'git commit --amend' to correct a commit message.
Caution about changing Git history and its implications for collaborators.
How to include a forgotten file in the previous commit using 'git commit --amend'.
Scenario of committing to the wrong branch and the solution using 'git cherry-pick'.
Description of three types of 'git reset' and their effects on the repository.
Use of 'git reset --hard' to revert to an initial commit and remove unwanted changes.
Cleansing the working directory of untracked files with 'git clean'.
Utilizing 'git reflog' to recover lost commits after a 'git reset --hard'.
Creating a new branch from a recovered commit to save changes.
How to undo commits that have been pushed and pulled by others using 'git revert'.
Explanation of 'git diff' to view the changes between commits before and after a revert.
Conclusion summarizing the Git tips for undoing mistakes and rolling back commits.
Transcripts
hey how's it going everybody in this
video we're going to be looking at a few
common scenarios in git where you can
find yourself needing to undo some
mistakes or even roll back some bad
commits um now some of these commands
will change the git history and some
will not and we're going to take a look
at exactly what that means here in a
second now this will be a slightly more
advanced git walkthr and uh we're going
to assume that you already know the
basic uh command line functionality of
git um if you aren't familiar with basic
git commands or how git works I do have
a video on getting started with Git in
the command line if you would like to
watch that video first but with that
said let's go ahead and get started uh
so let's take a look at the sample
repository that I have set up here so if
I do an ls- LA within this directory you
can see that I have this calc. py file
and I also have that cal. py file pulled
up in my text editor over here and you
can also see that we have theget
uh directory here which just means that
we are within a git repository so now if
I run a git status you can see that
currently our working directory is clean
if I do a get log then you can see that
we've only had one commit so far it's
just the initial commit and also if I
run a git Branch uh you can see that we
have another Branch here called subtract
feature um so both uh the subtract
feature branch and the master Branch are
currently exactly the same they both
only have that one initial commit um but
for now we're not going to bother with
the subtract feature Branch we'll take a
look at that uh here in a little bit so
let's look at our first example of a
mistake that you might want to undo um
so first we're going to say that we've
made changes to a file and after a while
we realize that we don't want any of the
changes that we've made so whatever
whatever we've done it just isn't right
and we want to go back to the way things
were uh so for this example I'm just
going to uh type in a bunch of gibberish
here into uh the text editor but more
realistically uh in the real world this
would likely be a bunch of code that for
one reason or another just isn't right
and you want to go back to the way that
things were um so uh for this example if
I go over here and do a get status you
can see that we have modified the file
if I do a get diff you can see all the
gibberish lines that we've put in there
um now the way that we can fix this is
to just use a simple G checkout uh so
what I'm going to do here is a get
checkout calc. py and if I hit enter
there now if I do a get status you can
see that our working directory is clean
and if I do a get diff you can see that
we don't have any changes and if I go
over here to the file and uh this
reloads over here you can see that we
are back to the way that things were
after we made our initial commit so now
let's actually make some changes to our
file that we do want to commit to our
repository um so I'm going to come in
here and change the subtract function
and I'm just going to do a return x
minus y so that's what we want so now
I'm going to go back over here to our
terminal now if I run a get status you
can see that the file has been modified
in the working directory and I'm going
to add that to the staging area and now
if I do another G status you can see
that that file is ready to be committed
so now I'm going to go ahead and commit
this file um but let's say that we make
a get commit and I accidentally mess up
our commit message so I'm going to say
that we completed the multiply function
which is wrong because we uh completed
the subtract function so I'm going to go
ahead and commit that with the bad
commit message so now if I do a get log
you can see that we've made the commit
but the message is wrong so uh how do we
modify this message without doing
another commit well to do that uh we can
just do another commit with the-- amend
option so if I do a get commit D- amend
then I can type in dasm for my message
and I'm just going to say completed
subtract function
so now if I do a get log here you can
see that uh we haven't added any more
commits we still just have the two
commits but we have changed this uh
commit message on our last commit which
is what we wanted now I do need to point
out that this unique hash here is
different than it was before we changed
the commit message now that's because
the commit message is part of the commit
and changing it will also change the
hash and when the hash changes that
means that it changed the git history um
so we only want to ever change the git
history when we are the only ones who
have had access to the changes that
we've made um so if we've pushed our
changes for other people to see and pull
from then we do not want to change the
get history because it can cause
problems with their repositories so
later in this video we're going to look
at some ways in which we can make
Corrections without changing the get
history but as long as we're the only
ones who have seen our changes then
changing the history isn't necessarily a
bad thing and it also makes for cleaner
commits um so in the case of a bad
commit message this is likely something
that you'll notice right away and can
fix it right on the spot like we just
did now kind of a similar scenario is
that instead of accidentally committing
the wrong message uh let's say that we
accidentally left off a file that we
meant to commit so in this example let's
say that I meant to create a get ignore
file and I wanted to add it to that last
commit so I'm going to create a do get
ignore file here and now let me go ahead
and run a get status and also let me add
that to the staging area so I'll do the
get add. GE ignore so now it's in our
staging area but we don't want to make a
new commit Let's uh so for this example
we're saying that we wanted that to be a
part of the last commit so again we're
just going to do the get commit D- amend
like we did before but this time it's
going to do it with a file so if I hit
enter here now it's going to bring up
this interactive editor where we can
change the get commit message if we want
now notice here that this is the same
get commit message uh from our previous
commit now we don't want to change the
message in this case so I'm just going
to uh save and close out so now I'm
going to do a get log and you can see
that we still just have the two commits
that we had before now if I do a g log
D- stat um this will show us the files
that were changed within the commit and
you can see here that the get ignore
file is now part of the last commit
where we did the uh completed the subtra
subtract function now once again just to
point out uh this unique hash is now
different so we once again changed to
get history so just one more time uh
just to remind you only do this type of
thing if you haven't pushed your changes
yet to other people so now if I do a get
log and then I do a get Branch um so now
we see our subtract Fe feature branch
and now uh just say that it hits us all
of a sudden that we've been making all
of these commits to the master Branch by
accident uh really we've been meaning to
make these commits to our subtract
teacher Branch now this is a fairly
common mistake to commit to the wrong
Branch because when you switch back and
forth sometimes you just forget exactly
where you are and um end up committing
to uh the wrong Branch by accident so
how do we move this commit uh right here
this 1B 818 how do we move that commit
to our feature Branch now to be clear
here exactly what we want to do is our
goal is to move this commit to our
subtract feed teach branch and then we
want to return our Master Branch back to
the state of only having the single
initial commit so the way that we're
going to do this is we're going to use
get cherry pick and cherry pick creates
a new commit based off of our original
so in this case our original is going to
be uh this top commit here now cherry
pick only creates a new commit based off
of that commit it doesn't delete the
original after it cherry-picks it so let
me clear my screen here and so the
process that you go through to do a get
cherry pick is first you want to do a
get log uh because we want to grab the
the hash of the commit that we want to
cherry pick um so we don't have to grab
the entire hash usually six or seven
characters is fine uh so I'm just going
to copy this here and now I want to do a
get checkout on my subtract feature
Branch so now I'm going to switch to my
subtract feature branch and now from
that Branch if I do a get log you can
see that we only have the initial commit
now I'm going to do a get cherry pick
and I'm going to paste in the hash that
I had copied from the master Branch so
now if I hit enter there and now I do a
get log now you can see that we brought
that commit for the complete subtract
function we brought that commit over to
our subtract feature branch so now we
have that commit on our feature Branch
but it still exists on our Master Branch
because cherry pick doesn't delete
commits um but we don't want that commit
on our Master Branch we never meant to
commit it there to begin with so how do
we get rid of it so to do this we're
going to use a git reset so I'm going to
do a git checkout on master and now I'm
going to do a get log so that we can see
the commits that we have now there are
three different types of resets that we
should know about uh these are get reset
soft get reset mixed which is the
default and get reset hard um so first
let's run through all of these so first
let's run get reset soft to try to
return uh to our initial commit so I'm
going to grab the hash from this initial
commit and copy that and now I'm going
to do a get reset D- soft and then I'm
going to paste in that hash of our
initial commit so now if I do a get log
you can see that we no longer have that
second commit which is good that's what
we wanted um but let's also look at our
get status now you can see that we have
some files in our staging area so soft
will reset us back to the commit that we
specified but it will keep our changes
that we've made in the staging directory
uh so we didn't lose any of our work so
in this case our work refer to the
addition of theg ignore file and the
modifications that we made to the cal.
py file so that is a soft reset uh let's
look at a mixed reset which is the
default um so again I'm going to grab
the hash of the initial commit and this
time let's do a get reset and I'm just
going to paste in the hash because
without any additional options it will
default to mixed so let's go ahead and
run that and now let's look at our get
log we only have the one commit which is
good but now if I do a get status you
can see just like get reset soft it kept
the changes um however now these changes
aren't in the staging area now they're
in the working directory so it's very
similar to get reset soft but the files
are either put in the staging or working
directory based on which one you specify
but in this example we we really don't
want our changes um we really just want
to go back to that initial commit and
have everything the way that they were
um so again let's copy the initial
commit hash and this time we're going to
try a get reset hard so get reset hard
is going to make all of our tracked
files match the state that they were in
uh at the hash that we specify and you
have to be careful with get reset hard
because it will get rid of your changes
but in this example that's what we
that's what we want so I'm going to do a
get reset D- hard and paste in that hash
and now if I do a get log you can see
that we have the one commit and now I'm
going to run get status so notice that
the modifications that we made to the
calc. py file are gone um but that theg
ignore file is still there now if you
remember I said that the git reset hard
reverts all of the tracked files back to
the state that they were but but it
leaves any untracked files alone so we
can uh see here that we still have some
leftovers with the get reset hard uh but
luckily getting rid of untracked files
is extremely simple so to get rid of
untracked files we can just use get
clean so if I do a get clean and then
I'm going to specify the D and the F
option so the D option gets rid of any
untracked directories and the F gets rid
of any untracked files so if I run that
now if I do a get status you can see
that our working directory is clean and
thatg ignore file is gone now that clean
command is a good command to know U
because it actually comes in handy more
often than You' think um for example one
time I was accidentally uh I
accidentally unzipped a file within my
git repository and it created just a ton
of untracked files and subdirectories
and I could have gone through and tried
to pick all those out manually and
delete all of them but the easiest way
to remove all those untracked files is
just with this single get clean command
okay so we learned that the get reset
hard totally totally deletes all of our
changes uh but what if you accidentally
ran that and it turns out that you did
need some of those changes so let's
pretend for the sake of this walk
through that we don't have uh those
changes still saved to the subtract
feature branch and we thought that the
reset deleted all of the changes that
we've made
so if you did run a get reset hard on
some changes that you really needed then
are you completely out of luck well not
entirely so you could be out of luck if
a lot of uh time has gone by since you
ran that get reset um I don't know the
exact amount of time but I think get
garbage collects uh those commits after
30 days or so um but get ref log is what
we're going to want to use here so get
ref log shows commits in the order of
when you last reference them so let me
run a get ref log here and you can see
that it kind of shows us exactly a
walkthrough of exactly what we've been
doing so you can see here at the bottom
is where I made my initial commit and
then we committed our complete multiply
multiply function which was wrong and
then you can even see where you amended
commits so this was an amended commit
where we changed our message and another
amend that's where we added the do get
ignore file and it shows us that we
checked out and moved from Master to
subtract feature and then did our cherry
pick and our checkout and then our reset
now if you'd accidentally got rid of
files that you didn't mean to get rid of
then so for this example I'm going to
grab the hash before the reset and copy
that and I'm going to do a get checkout
of that hash and now from here I'm going
to run a get log so you can see when I
run a get log from this hash uh that we
have our changes back this is the commit
that we reset and got rid of all those
changes now right now we are in a
detached head State now I'm not going to
go fully into what this means uh but
basically it means that we aren't on a
branch uh and where we currently are it
will be trashed at some point in the
future uh so to save these changes we
need to make a branch from it so from
here I'm going to do a get branch and
I'm just going to call this backup and
now if I run get Branch command to look
at all my branches you can see that
currently we're in a detached head State
and that's we'll get garbage collected
at some point and now we have our Master
Branch our subtract feature Branch we
also have this backup Branch so now let
me check out the master branch and now
from the master Branch if I do a get
Branch you can see that we still have
our backup Branch so those changes that
we thought that we'd lost uh now we have
those in this Branch here so just to
confirm that we still have those changes
uh let's do a get checkout of that
backup branch and now from here let's do
a get log and now you can see that we
have those changes that we thought that
we'd lost so the get ref log can really
be a lifesaver if you thought that you
had lost some critical files that you
really didn't mean to delete or that if
you accidentally did a reset on
something um The Ref log can really help
you out if you know how to use it okay
so in these examples so far I mentioned
that you shouldn't change the get
history if other people have pulled
those changes already uh well what if
you are in a situation where you really
need to undo some commits but other
people have already pulled those changes
so in a situation like that you're going
to want to use get revert uh revert
creates new commits to reverse the
effect of some earlier commits uh so
this way you don't rewrite any history
just to clarify that it's not going to
modify or delete our existing commits
that we've made it's going to create new
commits on top of those uh that
completely undo all of the changes so
that our history remains intact so just
to show an example of this I'm going to
run a git log and you you can see that
we have our two commits here so now what
if this completed subtract function uh I
wanted to undo that but other people
have already checked that out well uh I
can just copy the hash here and I'm
going to do a get revert and then paste
in that hash and now it's going to come
up here with a message and I'm just
going to save that and exit out of that
and now if I close out of there and do a
get log you can see that we now have
three commits and these two bottom
commits are completely untouched both of
their hashes are still the same as they
were before the revert now we have this
additional commit that says that it
reverted the complete subtract function
so if I go over here to my cal. py file
and reload it you can see that it's uh
it undid that return statement that we
typed in um now one nice little trick
with uh the git diff command is that if
I do a if I do a git log here and then I
do a git diff of this
hash and this hash here it's going to
show me the difference between the
complete subtract function commit and
then the uh reverted version of that so
you can see that whenever I compare
these two commits uh all it did was go
in here and it complet it saw all the
changes that uh we made in our
complete subtract function commit and
then it just redid or undid those so for
that commit we took out the past line
and added in the return xus Y Line and
in the revert it took out the return xus
Y and added in the pass so it just did
the complete opposite so now whenever
you push these changes and somebody else
um pulls those down uh their history is
not going to be corrupted because all of
this history is the same and all they're
going to get is these are these new
commits that undid those uh previous
commits well that about does it for this
video I hope that these uh G tips on how
to undo some of your mistakes and roll
back some previous commits I hope that
this was useful for you all um if you do
have any questions just ask in the
comment section below uh be sure to
subscribe for future get videos and
thank you for watching
Посмотреть больше похожих видео
Git and GitHub - 0 Experience to Professional in 1 Tutorial (Part 1)
13 Advanced (but useful) Git Techniques and Shortcuts
Git Tutorial For Dummies
Git Tutorial: Using the Stash Command
Day-11 | Git Interview Q&A and Commands for DevOps | Real World Example |#devops #github #git #2023
Day-9 | Git and GitHub | What is GIT ? | What is Version Control ? | #devops #2023 #github #gitlab
5.0 / 5 (0 votes)