5 Things I Frequently Do and Forget With Git

| Comments

Here are few things I used to do a lot in my starting days with git and then forgot to re-search them when needed next time. These tips are from my notes.

How to undo the last Git commit?

There are two scenarios in this case, and hence two ways to achieve our goal.

Hard Reset - Completely undo the last commit and all the changes it made.

git reset –hard HEAD~1
Imagine the state of the tree is as following:


where (F) is the current state of files and ‘C’ is the commit we want to undo. The above command completely removes the last commit along with all the changes involved in the commit. The new state of the tree is like this:


What is HEAD?
We can think of the HEAD as the “current branch”. HEAD is basically a pointer which points to the latest commit. When we switch branches with git checkout, the HEAD revision changes to point to the tip of the new branch.
What is HEAD~1?
It’s kind of complicated to explain HEAD~1 without explaining HEAD^1.
HEAD^1  means the first parent of the commit object. ^ means the th parent.
HEAD~1 means the commit object that is the first generation grand-parent of the named commit object, following only the first parents. e.g ~3 is equivalent to ^^^ which is equivalent to ^1^1^1.

Undo the commit but keep the changes

git reset HEAD~1
If we want to undo the last commit for some reason (like if we entered the wrong commit message or the commit was incomplete), we can use a soft reset on HEAD.
In this case, the tree structure changes to something like:


What’s happening?
In both cases, HEAD is just a pointer to the latest commit. When we do a git reset HEAD~1, we tell Git to move the HEAD pointer back one commit. But (unless we use –hard) we leave your files as they were. So now git status shows the changes you had checked into C. You haven’t lost a thing!

How to change the commit message of last commit

git reset –soft HEAD~1
Using this command we undo the last commit but keep the files as well as the index untouched. This means we can just recommit with no extra effort as a new commit with a new commit message.

What’s happening here?
Same as first point. But it leaves the files as well as the index unchanged, so we just need to ‘commit’ again with a new commit message.

How to get a commit back after ‘reset –hard’

In the first point, we undid the previous commit permanently(?). Sometimes (read often) it happens that we need the destroyed commit back. Following commands can be used to resurrect the destroyed commit.
git reflog
This command shows a list of partial commit shas. We need to choose the commit we want to restore from this list and use following command.
git checkout -b someNewBranchName shaOfDestroyedCommit
This will create a new branch and restore the destroyed commit in it, which we can re-merge as required.

What’s happening here?
Commits don’t actually get destroyed in git for about 90 days. So usually we can go back and restore commits with method explained above.

How to remove a git submodule?

Git submodule?
Submodules allow foreign repositories to be embedded within a dedicated subdirectory of the source tree, always pointed at a particular commit. Submodules are meant for different projects you would like to make part of your source tree, while the history of the two projects still stays completely independent and you cannot modify the contents of the submodule from within the main project.

Removing a git submodule

Git submodules can simply be removed with ‘git rm’, but that keeps the submodule entry intact in the .git/config and .gitmodules. There is actually an easier way to remove submodules with a single command.
git submodule deinit
This is in comprehension to ‘git submodule init’ command and does all the submodule removal work itself.

How to delete a remote git branch?

 This one is easy. We just need one command to delete a remote branch.
git push origin –delete
To remove a local branch, we can of course use
git branch -d