Skip to main content
deleted 184 characters in body
Source Link
Jörg W Mittag
  • 367.7k
  • 78
  • 450
  • 657

If you have not yet garbage collected your repository (e.g. using git repack -d or git gc, but note that garbage collection can also happen automatically), then your commit is still there – it's just no longer reachable through the HEAD.

You can try to find your commit by looking through the output of git fsck --lost-found.

Newer versions of Git have something called the "reflog", which is a log of all changes that are made to the refs (as opposed to changes that are made to the repository contents). So, for example, every time you switch your HEAD (i.e. every time you do a git checkout to switch branches) that will be logged. And, of course, your git reset also manipulated the HEAD, so it was also logged. You can access older states of your refs in a similar way that you can access older states of your repository, by using an @ sign instead of a ~, like git reset HEAD@{1}.

It took me a while to understand what the difference is between HEAD@{1} and HEAD~1, so here is a little explanation:

  1. git init
  2. git commit --allow-empty -mOne
  3. git commit --allow-empty -mTwo
  4. git checkout -b anotherbranch
  5. git commit --allow-empty -mThree
  6. git checkout master # This changes the HEAD, but not the repository contents
  7. git show HEAD~1 # => One
  8. git show HEAD@{1} # => Three
  9. git reflog
git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

So, HEAD~1 means "go to the commit before the commit that HEAD currently points at", while HEAD@{1} means "go to the commit that HEAD pointed at before it pointed at where it currently points at".

That will easily allow you to find your lost commit and recover it.

If you have not yet garbage collected your repository (e.g. using git repack -d or git gc, but note that garbage collection can also happen automatically), then your commit is still there – it's just no longer reachable through the HEAD.

You can try to find your commit by looking through the output of git fsck --lost-found.

Newer versions of Git have something called the "reflog", which is a log of all changes that are made to the refs (as opposed to changes that are made to the repository contents). So, for example, every time you switch your HEAD (i.e. every time you do a git checkout to switch branches) that will be logged. And, of course, your git reset also manipulated the HEAD, so it was also logged. You can access older states of your refs in a similar way that you can access older states of your repository, by using an @ sign instead of a ~, like git reset HEAD@{1}.

It took me a while to understand what the difference is between HEAD@{1} and HEAD~1, so here is a little explanation:

  1. git init
  2. git commit --allow-empty -mOne
  3. git commit --allow-empty -mTwo
  4. git checkout -b anotherbranch
  5. git commit --allow-empty -mThree
  6. git checkout master # This changes the HEAD, but not the repository contents
  7. git show HEAD~1 # => One
  8. git show HEAD@{1} # => Three
  9. git reflog

So, HEAD~1 means "go to the commit before the commit that HEAD currently points at", while HEAD@{1} means "go to the commit that HEAD pointed at before it pointed at where it currently points at".

That will easily allow you to find your lost commit and recover it.

If you have not yet garbage collected your repository (e.g. using git repack -d or git gc, but note that garbage collection can also happen automatically), then your commit is still there – it's just no longer reachable through the HEAD.

You can try to find your commit by looking through the output of git fsck --lost-found.

Newer versions of Git have something called the "reflog", which is a log of all changes that are made to the refs (as opposed to changes that are made to the repository contents). So, for example, every time you switch your HEAD (i.e. every time you do a git checkout to switch branches) that will be logged. And, of course, your git reset also manipulated the HEAD, so it was also logged. You can access older states of your refs in a similar way that you can access older states of your repository, by using an @ sign instead of a ~, like git reset HEAD@{1}.

It took me a while to understand what the difference is between HEAD@{1} and HEAD~1, so here is a little explanation:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

So, HEAD~1 means "go to the commit before the commit that HEAD currently points at", while HEAD@{1} means "go to the commit that HEAD pointed at before it pointed at where it currently points at".

That will easily allow you to find your lost commit and recover it.

Source Link
Jörg W Mittag
  • 367.7k
  • 78
  • 450
  • 657

If you have not yet garbage collected your repository (e.g. using git repack -d or git gc, but note that garbage collection can also happen automatically), then your commit is still there – it's just no longer reachable through the HEAD.

You can try to find your commit by looking through the output of git fsck --lost-found.

Newer versions of Git have something called the "reflog", which is a log of all changes that are made to the refs (as opposed to changes that are made to the repository contents). So, for example, every time you switch your HEAD (i.e. every time you do a git checkout to switch branches) that will be logged. And, of course, your git reset also manipulated the HEAD, so it was also logged. You can access older states of your refs in a similar way that you can access older states of your repository, by using an @ sign instead of a ~, like git reset HEAD@{1}.

It took me a while to understand what the difference is between HEAD@{1} and HEAD~1, so here is a little explanation:

  1. git init
  2. git commit --allow-empty -mOne
  3. git commit --allow-empty -mTwo
  4. git checkout -b anotherbranch
  5. git commit --allow-empty -mThree
  6. git checkout master # This changes the HEAD, but not the repository contents
  7. git show HEAD~1 # => One
  8. git show HEAD@{1} # => Three
  9. git reflog

So, HEAD~1 means "go to the commit before the commit that HEAD currently points at", while HEAD@{1} means "go to the commit that HEAD pointed at before it pointed at where it currently points at".

That will easily allow you to find your lost commit and recover it.