DEV Community

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

Tomer Ben David on September 15, 2018

If you access: https://stackoverflow.com/questions?sort=votes you would see the top voted questions on StackOverflow. It's not hard to notice th...
Collapse
 
thinsoldier profile image
thinsoldier

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

Collapse
 
qm3ster profile image
Mihail Malo

No pain - no gain (no fun, no profit)

Collapse
 
shaijut profile image
Shaiju T • Edited

If source tree can do the work easily then why do we want take pain by using git terminal ? Anything special about terminal ?

Thread Thread
 
qm3ster profile image
Mihail Malo

It might be faster, more precise, and you might already be in the terminal.

Collapse
 
tomerbendavid profile image
Tomer Ben David

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.

Collapse
 
subbramanil profile image
Subbu Lakshmanan • Edited

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.

Collapse
 
syncsynchalt profile image
Michael Driscoll

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.

Collapse
 
entrptaher profile image
Md Abu Taher

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!

Collapse
 
kepta profile image
Kushan Joshi

New comers think twice before using git reset —hard

Collapse
 
david_j_eddy profile image
David J Eddy • Edited

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.

Collapse
 
bacchusplateau profile image
Bret Williams

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.

Collapse
 
anuranbarman profile image
Anuran Barman

Use sourcetree and cherrypick it

Collapse
 
susensio profile image
Susensio

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

Collapse
 
tomerbendavid profile image
Tomer Ben David • Edited

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].)

Collapse
 
grillermo profile image
.

My solution, been using it for years

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