Get a list of all Git commits, including the 'lost' ones
Asked Answered
C

12

278

Let's say that I have a graph like this:

A---B---C---D (master)
     \
      \-E---F (HEAD)

If I do git log --all --oneline, I will get all six of my commits.

But if the graph is:

A---B---C---D (master, HEAD)
     \
      \-E---F

I will not see E and F. Can I get Git to tell me all the commits, including those on branches which are not named?

Calendra answered 24/1, 2011 at 20:43 Comment(0)
F
75

Not particularly easily- if you've lost the pointer to the tip of a branch, it's rather like finding a needle in a haystack. You can find all the commits that don't appear to be referenced any more- git fsck --unreachable will do this for you- but that will include commits that you threw away after a git commit --amend, old commits on branches that you rebased etc etc. So seeing all these commits at once is quite likely far too much information to wade through.

So the flippant answer is, don't lose track of things you're interested in. More seriously, the reflogs will hold references to all the commits you've used for the last 60 days or so by default. More importantly, they will give some context about what those commits are.

Flashy answered 24/1, 2011 at 20:49 Comment(10)
+1: There is absolutely no difference between a commit deliberately orphaned by commit --amend or rebase and one accidentally orphaned by working with a detached HEAD, say.Shanahan
indeed. probably the easiest way to recover from that situation will be to look at the reflog for HEAD itself.Flashy
@Jefromi: Great point out about git commit --amend etc. leaving dead-end, lost commits. I did some rebasing and whatnot and ended up with some commits not reachable from any branches, and felt a bit dirty leaving them in the repo. Now the thought isn't quite as unsettling anymore. :)Lambdacism
@Flashy I got myself in the same pickle as the original poster and your suggestion to look at the reflog was just the thing to do.Sadye
I agree with this answer, but in the case where someone does need to see all commits, including orphaned ones whether deliberate or accidental, git fsck --unreachable doesn't provide that. I just tried it. The better approach is the --reflog option for git log, as kenorb answered. What's especially nice about this is that combined with --graph, you get an easy to parse visual context, much like that illustrated in the original question. For example, try: git log --graph --all --oneline --reflogAlong
@Along git fsck --no-reflogs --unreachable should find all the unreferenced one.Secluded
I wonder when/if git will ever add a built-in log of every git command that changes something, as well as parodically snapshotting the entire branch graph - that would be useful and not take up hardly any space on-disk, imo...Impermanent
@Along - Given that reflogs work with the local repository, how would you use that to get information about a remote? The scenario is I have a clone of a repository made 6 months ago, very complex with many branches, labels (where branch is deleted, but label remains) .... Now I want to find out if anyone has altered history in any way on the remote....Semiotic
@DavidV.Corbin I'm a bit unclear about what you mean/want. The commit history of a branch, tag or any commit is just the sequence of commits leading up to it, i.e. following parent commits recursively, as shown with git log. If you want to see a remote branch's current history, use git fetch, which makes sure your local repo has a copy, and then use git log to examine it. A git reflog is a history of history. I don't understand why you'd need to see the remote's version of that, but if you do: #10098595Along
Inigo - Create some commits, now remove ALL branches, tags, everything that would reference that chain of commits. "git fsk" with options will show some of them but I have had occasion where not all would show... Note: there is a big difference between working with local repos (where reflog is very helpful) and working with hosted [GitHub, Azure, etc].... Consider a repo in use for 5 years, and somewhere around 3 years ago some work was done [committed and pushed], but then later heads are reset, tags and branches deleted. I want to see every commit that was ever pushed by anyone ...Semiotic
K
299

Try:

git log --reflog

which lists all git commits by pretending that all objects mentioned by reflogs (git reflog) are listed on the command line as <commit>.

Kinard answered 31/12, 2015 at 15:41 Comment(5)
This is what I was looking for - the functionality of the --reflog argument.Soninlaw
Btw, gitk also supports that: gitk --reflog .Counterman
type q to exit from git logPalate
This one also shows the local commits "lost" when doing stuff like git reset origin/branch which aren't actually unreachable, just not shown in log anymore.Mortician
Accidentally did git checkout -B my/branch which meant it did an accidental > Switched to and reset branch Using this log list I found the commit that was the previous HEAD, thank you.Laryngology
P
80

What saved my life was the following command:

git reflog

There you find a screen with history commits done to git like this one:

enter image description here

At this point, you only have to find the HEAD@{X} that you need, create a temporary branch and move to it like this:

git checkout -b temp_branch HEAD@{X}

That way you will have a temporary branch with your lost commit without rebasing or breaking even more your git repository.

Hope this helps...

Peisch answered 16/5, 2019 at 7:13 Comment(1)
vontade de apertar a bochecha desse anjoEugene
F
75

Not particularly easily- if you've lost the pointer to the tip of a branch, it's rather like finding a needle in a haystack. You can find all the commits that don't appear to be referenced any more- git fsck --unreachable will do this for you- but that will include commits that you threw away after a git commit --amend, old commits on branches that you rebased etc etc. So seeing all these commits at once is quite likely far too much information to wade through.

So the flippant answer is, don't lose track of things you're interested in. More seriously, the reflogs will hold references to all the commits you've used for the last 60 days or so by default. More importantly, they will give some context about what those commits are.

Flashy answered 24/1, 2011 at 20:49 Comment(10)
+1: There is absolutely no difference between a commit deliberately orphaned by commit --amend or rebase and one accidentally orphaned by working with a detached HEAD, say.Shanahan
indeed. probably the easiest way to recover from that situation will be to look at the reflog for HEAD itself.Flashy
@Jefromi: Great point out about git commit --amend etc. leaving dead-end, lost commits. I did some rebasing and whatnot and ended up with some commits not reachable from any branches, and felt a bit dirty leaving them in the repo. Now the thought isn't quite as unsettling anymore. :)Lambdacism
@Flashy I got myself in the same pickle as the original poster and your suggestion to look at the reflog was just the thing to do.Sadye
I agree with this answer, but in the case where someone does need to see all commits, including orphaned ones whether deliberate or accidental, git fsck --unreachable doesn't provide that. I just tried it. The better approach is the --reflog option for git log, as kenorb answered. What's especially nice about this is that combined with --graph, you get an easy to parse visual context, much like that illustrated in the original question. For example, try: git log --graph --all --oneline --reflogAlong
@Along git fsck --no-reflogs --unreachable should find all the unreferenced one.Secluded
I wonder when/if git will ever add a built-in log of every git command that changes something, as well as parodically snapshotting the entire branch graph - that would be useful and not take up hardly any space on-disk, imo...Impermanent
@Along - Given that reflogs work with the local repository, how would you use that to get information about a remote? The scenario is I have a clone of a repository made 6 months ago, very complex with many branches, labels (where branch is deleted, but label remains) .... Now I want to find out if anyone has altered history in any way on the remote....Semiotic
@DavidV.Corbin I'm a bit unclear about what you mean/want. The commit history of a branch, tag or any commit is just the sequence of commits leading up to it, i.e. following parent commits recursively, as shown with git log. If you want to see a remote branch's current history, use git fetch, which makes sure your local repo has a copy, and then use git log to examine it. A git reflog is a history of history. I don't understand why you'd need to see the remote's version of that, but if you do: #10098595Along
Inigo - Create some commits, now remove ALL branches, tags, everything that would reference that chain of commits. "git fsk" with options will show some of them but I have had occasion where not all would show... Note: there is a big difference between working with local repos (where reflog is very helpful) and working with hosted [GitHub, Azure, etc].... Consider a repo in use for 5 years, and somewhere around 3 years ago some work was done [committed and pushed], but then later heads are reset, tags and branches deleted. I want to see every commit that was ever pushed by anyone ...Semiotic
S
74

When I tackle this issue I use the following command:

git reflog |  awk '{ print $1 }' | xargs gitk

This lets me visualise recent commits which have become headless.

I have this wrapped up in a script helper called ~/bin/git-reflog-gitk.

Edit: - my git-reflog-gitk wrapper is redundant - as you can now call gitk --reflog directly

Simplehearted answered 21/5, 2014 at 10:45 Comment(5)
This just SAVED me big time... THANK YOU!Gwenora
this is awesome! thank you! it really visualizes the important parts of the tree.Exult
Just a tip: This will only work for your local work as reflog records when the tips of branches and other references were updated in the *local repository*. You may want to use git log --reflog if you would like to do this for non-local ref changesMetempirics
As an update here - as mentioned in other answers/comments - My solution here is outdated - you can now use 'gitk --reflog' directly.Simplehearted
This opens gitk gui without any commit hash shownEdee
G
32

Like @Kieran 's Answer, but for the console: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Griskin answered 29/5, 2015 at 1:41 Comment(5)
Do you need to include the last part: $(git reflog | awk '{print $1}')? What does this do? After trying out your solution, it seems like it produces the same output even without that last part.Anabelle
If you move your branch pointer and leave some commits without a reference (like OP did) they will no longer show up in git log --all. A quick example: After a git reset --hard @^ your HEAD@{0} commit will only be in the reflog, and since git reflog does not support --graph you have to pass the commits to git log --graph to get a visual representation.Griskin
you can use --reflog instead of $(git reflog | awk '{print $1}')Doc
I compared git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}') to git log --oneline --all --graph --decorate --reflog, they're nearly identical except --reflog included details such as WIP entries.Fiddlestick
@FlorianFida, instead of reflog why not use log --reflog instead?Fresher
D
15
git log --reflog

saved me! I lost mine while merging HEAD and could not find my lates commit! Not showing in source tree but git log --reflog show all my local commits before

Deviation answered 21/4, 2020 at 11:59 Comment(0)
G
9

How I solve this problem? Use git fsck and logging!

First create a file containing lost (unreachable) commits and blobs. (NOTE: if you did something like git gc then it will garbage collect all of they commits and you won't find them here!)

$git fsck --lost-found > lost_found.commits

That gives you a file like this:

dangling commit dec2c5e72a81ef06963397a49c4b068540fc0dc3
dangling blob f8c2579e6cbfe022f08345fa7553feb08d60a975
dangling blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
dangling blob 11cbd8eba79e01f4fd7f496b1750953146a09502
dangling commit 18733e44097d2c7a800650cea442febc5344f9b3
dangling blob 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

You can then open this file with you favorite text editor to copy the commit/blog hashes from there. (*cough* vim macros works great for this *cough*)

Now you can log back from this commit with something like git log --oneline <commit hash>. Alternatively, gitk, tig, or any other git viewer should work.

In your case if you find the hash for commit F the log will show you something like this,

A---B---E---F

Quick and easy! Now you can find the context behind all of those dangling commits.

P.S. Yes, I know, late post, but oh well, somebody might find it here and find it useful. (Mostly likely me in 6 months when I google this again)

Gow answered 10/12, 2014 at 16:4 Comment(0)
I
7

I've had luck recovering the commit by looking at the reflog, which was located at .git/logs/HEAD

I then had to scoll down to the end of the file, and I found the commit I just lost.

Ingold answered 18/12, 2013 at 9:51 Comment(1)
This is what just ended up doing when I screwed something up. Tried to commit to master and Stash balked when I pushed. I reset --hard , then realized my mistake. The commit was in the reflog, so I checked it out, made a branch out of it, then pushed that. Everything worked out in the end.Voigt
S
7

Actually git fsck can be used to find all the lost commits, you just need the right option:

git fsck --unreachable --no-reflogs

--unreachable alone is not enough because some commits might still be referenced by the reflog. If you need a pretty clear view of the entire commit history, you can create an alias for something like this:

git log --all --decorate --oneline --graph $(git fsck --no-reflogs --unreachable | awk '{if ($2 == "commit") print $3}')

To be honest I am not sure if in this last command you need the --unreachable option, given that git log traverse the ancestors by default (unless --no-walk is specified). I would not bet on it, but I think it is not necessary.

Secluded answered 15/6, 2021 at 6:53 Comment(0)
S
5

We'll git log sometimes is not good to get all commits detail, so to view this...

For Mac: Get into you git project and type:

$ nano .git/logs/HEAD

to view you all commits in that, or:

$ gedit .git/logs/HEAD

to view you all commits in that,

then you can edit in any of your favourite browser.

Sokul answered 22/3, 2014 at 8:16 Comment(0)
D
3

@bsimmons

git fsck --lost-found | grep commit

Then create a branch for each one:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Now many tools will show you a graphical visualization of those lost commits.

Diplomate answered 17/7, 2017 at 14:1 Comment(0)
A
2

If you use Git Extensions GUI it can show you a graphical visualization of dangling commits if you check "View -> Show reflog references". This will show dangling commits in the tree, just like all other referenced ones. This way it is way easier to find what you are looking for.

See this image for demonstration. Commits C2, C3, C4, and C5 on the image are dangling but still visible.

Argentina answered 11/7, 2018 at 16:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.