and the second top voted question on StackOverflow is...

Tomer Ben David on September 15, 2018

If you access: you would see the top voted questions on StackOverflow. It's not hard to notice ... [Read Full]
markdown guide

Simplest answer is to use a git gui like sourcetree and look at its console. No guesswork. No fear.


git reset --hard HEAD, I cannot remember how many hundreds of thousands times I used this snippet and it saved me from disaster.

Great post!


New comers think twice before using git reset —hard


Another great article about git on dev dot to.

Every statement was simply understandable for me except this past commit would be the parent of our current commit. That I don't get what the current commit is here? If we have moved to the last but one commit isn't it the current commit? It's like saying the current commit is the parent of itself.

I really appreciate if someone could shed light on this.


thanks, and sorry for that section it was not clear indeed! Allow me to try again:

As we have moved our HEAD one commit to the past, this means that any other commit which was the future of that past point is not pointed by the graph anymore - assuming we make new commits to that HEAD~ parent commit. This means we are not appending only to the git history we are changing the history, taking parents (in our case HEAD~ and with a new commit we give it a different child than it had). For example if we move one commit to the past with HEAD~ and start commit from there the commit from the original HEAD (which was the child of HEAD~) would not exist anymore in the standard history log. So if anyone else had that child HEAD commit and used it to create new commits (new children for this HEAD commit, HEAD + 1 you could call it) it would create problemns (ofcourse assuming we share our history rewrite with him).

So after we do git reset and go back one commit in our local repo, we usually are then making local fixes in our working directory and then we commit. This commit is a new commit but it has the same parent as the commit that we are fixing, so children are possibly different for us and for others who already have this same snapshot of the repository before our change.


So I tried to understand what tilde ~ symbol means in git and found a good article explains it.

git caret and tilde.

In short version, HEAD points to current commit, HEAD~1 points to one commit before(parent). HEAD~ is a shorthand for HEAD~1.

what the current commit is here?

Always HEAD points to the current commit.

If we have moved to the last but one commit isn't it the current commit?

Yes. Now HEAD points to the commit (which was last but one earlier)

It's like saying the current commit is the parent of itself.

No. Always HEAD~ points to the first parent commit.

The article explains the usage of ~ symbol a bit more.


Good idea mentioning reflog in this article—I never felt free and safe enough to play with the darker corners of git on production code until I found out that:

  1. git reflog will remember all previously committed states for 90 days, no matter what you do to rewrite history.
  2. If nothing else you can do a checkout to any of those hashes in reflog's output and hard reset / force push it as your new branch tip.

I know a force push sounds like bad advice to mention in any newbie git article, but the above operations were exactly the safety net that I (a decades-long user of CVS, TLA, and Hg) needed to really start getting creative and map out a mental model for git.


Two (better) options IMO:

'git commit --amend' to fix the message

'git revert' to undo a commit change set

Why do I think these are better? No rewriting of the history! No need to understand HEAD, graph theory, or the other abstractions. And they maintain the forward only design paradigm of git.


Git "gives off a smell" when you try to do something that should be easy. All I wanted to do was roll back a changeset that is sandwiched between other commits. My favorite solution to date is to branch off of Master and recreate the release branch without the offending commit you wanted to rollback.


My solution, been using it for years

alias undo_commit git reset HEAD~ --soft && git reset HEAD


Wouldn't amend also distort commit history and mess up collaborators' repository?


Yeah amend messes the recent commit and creates a new one so we have a new sha-1 for that commit. if that recent commit was pushed to remote repo and other users checked it out and used it. I had the instinct that yes and that it's "reusing" git reset for amend but for safety I checked the git documentation about what it says about it and here is what is has to say about it:

git amend is a rough equivalent for:

$ git reset --soft HEAD^
$ ... do something else to come up with the right tree ...
$ git commit -c ORIG_HEAD

but can be used to amend a merge commit.

You should understand the implications of rewriting history if you amend a commit that has already been published. (See the "RECOVERING FROM UPSTREAM REBASE" section in git-rebase[1].)

code of conduct - report abuse