git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: List all commits of a specified file in oldest to newest order

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Nov 5, 2021, 08:13 UTC
Message-ID
<211105.86a6ijhujg.gmgdl@evledraar.gmail.com>
In-Reply-To
<c3932b3c-323a-39d6-26a7-ba0c3d17378b@onenetbeyond.org>
On Fri, Nov 05 2021, Vipul Kumar wrote:
Show 6 quoted lines
> I want to list all commits (including renames) of a specified file in
> oldest to newest order. But when I run "git log --follow --reverse -- 
> <path/to/the/file>" command, I'm getting a single commit, which points
> to the "rename of the file". This behavior is weird to me because I 
> expected to get list of all commit in oldest to newest order, whereas
> "git log --follow -- <path/to/the/file>" command works as expected.

This is a known caveat of how the history traversal works, but from a quick glance I couldn't see any explicit documentation for it, aside from this terse mention in git-log(1):

     "[-M can be used] for following files across renames while
     traversing history, see --follow.".

The key thing being the "traversal", i.e. as we walk history we'll encounter a tree entry where b.txt was deleted, and see that it was moved from a.txt.

However, if we walk history from the beginning we have no idea of the relationship of a->b.txt, since we didn't encounter that commit yet, that's only something we see while walking the history.

Perhaps we should have some option like --buffer-then-reverse, which wouldn't change the walking order, but would only change the output, but we don't.

This caveat doesn't only apply to reverse, try to apply a move of b.txt on top of your history:

    b.txt -> c.txt
And now do:
    git log [--follow] -- b.txt

What should we output there? If we're arguing that we should first traverse the history to "look forward" that'll also apply to a non-reverse walk, since we're asking to follow b.txt.

But we haven't encountered the b->c.txt relationship yet (well, we run into the rename commit, but once you add a c->d.txt on top...). So maybe instead of --buffer-then-reverse we'd need a hypothetical --two-pass, which would also impact options other than --reverse whose behavior relies on traversal order.

Take all the above as an explanation for how it works now, not some defense of this being user-friendly. I've also often been annoyed at this behavior.

For small sets you can feed your into an alias like:
    git show $(git -P log --pretty=format:"%h" --pretty=tformat:%H --follow -- b.txt | tac)
As a poor man's --buffer-then-reverse.
Previous: Vipul KumarNext: Vipul Kumar
Message 6 of 9 in “List all commits of a specified file in oldest to newest order”
  1. Vipul KumarNov 5, 2021
  2. Jeff KingNov 5, 2021
  3. Junio C HamanoNov 5, 2021
  4. Jeff KingNov 5, 2021
  5. Vipul KumarNov 9, 2021
  6. Ævar Arnfjörð BjarmasonNov 5, 2021
  7. Vipul KumarNov 9, 2021
  8. Ævar Arnfjörð BjarmasonNov 9, 2021
  9. Vipul KumarDec 14, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.