tl;dr: much faster than the fsck method, so, helpful on long histories, is:
find .git/objects/?? -type f -exec ls -t {} + | awk -F/ '{print $3$4}' \| git cat-file --batch-check | awk '$2=="commit" { print $1 }' \| git log --no-walk --stdin --mergesor you've set your clone for really frequent automatic compaction, or just got unlucky and went looking that soon after a repack, this is still a good bit faster than fsck'ing:
{ find .git/objects/?? -type f -exec ls -t {} + | awk -F/ '{print $3$4}'; git verify-pack -v $(ls -t .git/objects/pack/*.idx) | awk '$2=="commit" {print $1}';} | git cat-file --batch-check | awk '$2=="commit" { print $1 }' \| git log --no-walk --stdin --mergesand with the default stash messages you can add --grep '^WIP' to the final git log options.
The breakdown on the above commands is:
Recently-added objects, most-recent first, with type and size appended
find .git/objects/?? -type f -exec ls -t {} + | awk -F/ '{print $3$4}' \| git cat-file --batch-checkRecently-added merge commits, most recent first:
find .git/objects/?? -type f -exec ls -t {} + | awk -F/ '{print $3$4} \| git cat-file --batch-check | awk '$2=="commit" { print $1 }' \| git log --no-walk --stdin --mergesIf Git is set to very aggressively pack up loose objects (by default it doesn't bother until there are clearly gratifying compression wins available) the above find can be unreliable; to avoid having to search all the packed history for candidates you can extend your search to include the most-recently-packed objects with
git verify-pack -v $(ls -t .git/objects/pack/*.idx|sed q) | awk '$2=="commit" {print $1}'and folding that in to the find above gets
{ find .git/objects/?? -type f -exec ls -t {} + | awk -F/ '{print $3$4}'; git verify-pack -v $(ls -t .git/objects/pack/*.idx) | awk '$2=="commit" {print $1}';} | git cat-file --batch-check | awk '$2=="commit" { print $1 }' \| git log --no-walk --stdin --merges