Search code examples
gitgit-squashgit-blame

git annotate a squashed commit


I've always been sceptical about 'squashing' or rewriting history, and now I'm just about convinced that I should ban this practice from the repos I manage. But maybe somebody can answer this, and save the day for my squash-championing colleagues.

I just came across a line of code that I want to understand the reasoning behind, so I used git annotate to find out who wrote it and why. But it points to a 'squashed' commit, a long list of commit message headers about a myriad of features and bug-fixes, without detail. Not really helpful.

'Oh, but there's always the reflog,' I've been assured; 'information never actually gets lost in git!' Okay, glad to hear it! But I tried git reflog <squashed-commit-hash>, and got no output at all—not helpful. I also tried git rev-list <squashed-commit-hash>, and got a list of hundreds of hashes, and after manually inspecting a few of them with git show, I've concluded they're not parts of what got squashed—also not helpful.

So is it actually possible to find out which single commit contributed to that line of code, and see that commit's entire message? Can it be done in a single git command, without having to be a bash guru? Or has this information, in fact, actually been lost in git after all?


Solution

  • Since other answers haven't addressed it, I think this needs to be called out:

    'Oh, but there's always the reflog,'

    No. 100% false. The reflog is both local and temporary.

    It's true that git does a very good job protecting against loss of history (unless you specifically direct it to lose history), but to say that information never gets lost is wildly inaccurate and dangerous. People need to understand the ways information can (and can't) be lost so that they know when and how to rely on the protections git really does offer.

    As to the broader issue:

    Rewriting shared histories is generally not a good practice. Most people who advocate for aggressive rebasing want to rewrite histories before pushing to the remote. Not only is that a less unpopular practice, it's pretty much impossible to ban even if you want to (because when I push a commit, you don't know whether I created it by squashing several previous commits or not).

    Acceptable granularity of the final commits, and acceptable documentation for each commit, are standards you'll need to set with the team. The enforcement will probably end up being more social than technical.