0

I figured I could find the answer for this with a simple google search because it seems so simple and common, but every answer I'm finding is for a very specific situation that doesnt apply to me.

I had two local commits in my repository:
commitA - commitB(H)

(*the H means HEAD)

I wanted to view a snapshot of my code at commit A, so I did: git reset --hard A so now I have this
commitA(H) - commitB (well, I'm HOPING B is still there)

I just want to go back to having B be my HEAD!

4
  • 3
    To view the snapshot of A you should have performed a checkout to A and not a hard reset
    – PeCosta
    Commented Nov 5, 2015 at 20:06
  • git reset --hard performs the following Resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded.
    – PeCosta
    Commented Nov 5, 2015 at 20:08
  • (insert gif of FML guy from superbad here)
    – Siavash
    Commented Nov 5, 2015 at 20:10
  • No git saves you, you can use git reflog
    – PeCosta
    Commented Nov 5, 2015 at 20:11

3 Answers 3

6

Luck is with you, provided you have not disabled git's "reflogs": commit B is still there. (Even if you have removed the airbags and seatbelts it's probably still there anyway. :-) Reflog entries preserve commits for at least 30 days by default.)

If you know the SHA-1 ID of commit B:

$ git reset --hard <id of B>

will get it back.

If you don't know the ID of B, you must find it, or direct git to find it, but fortunately that's easy1 since they are in the reflogs:

$ git reflog         # shows the reflog for HEAD
$ git reflog master  # shows the reflog for branch master

You can then copy-and-paste the ID, or use the HEAD@{1} style syntax that you'll see in the reflog output:

bf8be34 master@{0}: reset: moving to bf8be34bb970c875585952efc5c09898f98e1d10
d106870 master@{1}: commit: ...

Note that --hard will, as always, wreck any uncommitted work you have in the work-tree.


1Well, "easy", if scanning through a bunch of SHA-1s and one-line commit messages to find the right one is "easy". In an active repository, finding a buried reflog entry is tricky. If you do a lot of rebasing and amending, the same commit message gets repeated a lot. Fortunately in this case it's going to be ...@{1}.

0
1

If you still have the commit hash of commit B you can

git checkout -b new_branch COMMIT_HASH

Then went back to the original branch and merge the new_branch:

git checkout branch
git merge new_branch

Btw, you should not use reset --hard if you want to view a previous commit. Use:

git checkout COMMIT_HASH

instead.

3
  • I do have the hash and that DID work, now was there a way to do this without creating a new branch?
    – Siavash
    Commented Nov 5, 2015 at 20:12
  • 1
    @Siavash: yes, git reset "moves the branch": you give git reset a commit ID, and it changes the current branch to point to that commit ID. If you don't give git reset a new commit ID, it still "moves" the branch, but it moves it from where it points now, to where it points now. Think of the branch as a sticky-note, or as a name with an arrow on it. You peel off the sticky-note, currently pasted on commit A, and paste it on B. Or, you move the arrow so that it points to B instead of A. Another git reset moves it again.
    – torek
    Commented Nov 5, 2015 at 20:15
  • 1
    " was there a way to do this without creating a new branch" the same way as you messed it up: git reset --hard HASH
    – Lol4t0
    Commented Nov 5, 2015 at 20:15
0

Unfortunately, that --hard obliterated commitB entirely. As in torek's answer, you can hopefully reflog the deleted commits, but I'm personally not familiar enough with reflog to comment on it.

You could have checked out A, which would have been a detached head (just a commit to which no branch is associated). At that point you could browse your code, and then either re-checked out B (git checkout HEAD), or continued with A in a new branch (git checkout -b myNewBranch).

For next time, here's a good post on the differing versions of reset.

1

Not the answer you're looking for? Browse other questions tagged or ask your own question.