Subject: [RFD] should "git log --graph -g" work and if so how?

From: Junio C Hamano <[email-masked]>
Date: Sat, 24 Feb 2024 11:04:52 -0800

Outside work, I keep one repository that keeps copies of a subset of
what is available elsewhere (but that is not version controlled in
any way), and in this repository, I do either one of two operations:

 * I "fetch" the latest state of the things I keep track of from
   that "elsewhere", and then record that state as a "snapshot".

 * I update the "subset" I keep track of from that "elsewhere",
   download that new part of the subset, and then record the result
   as a commit with messages like "add 'foo'" or "drop 'bar'".

One curiosity is that I do not care too much about "snapshot"; the
latest state is often enough, so when the topmost one is a snapshot,
I may "amend" it when making a new "snapshot", instead of making two
or more consecutive "snapshot" commits (when the topmost "snapshot"
is too old, I may choose to add a new shapshot on top of it, but
let's ignore that for simplicity).

    if I am doing a snapshot
    then
	fetch what I've been tracking from "elsewhere"
	"git add ."
	if the topmost commit is an earlier "snapshot"
	then
		"git commit --amend -m 'snapshot as of ...'"
	else
		"git commit -m 'snapshot as of ...'"
	fi
    elif I am adding new things to be tracked
    then
	fetch the new part of "elsewhere"
	"git add ."
	"git commit -m 'add ...'
    fi

After I started from empty, started tracking 'foo' and then a few
days later started tracking 'bar', and then started taking snapshots
on 2024-02-22 and took one every day, I may end up with a history
that "git show-branch -g" may give me something like this:

    $ git show-branch -g5
    ! [master@{0}] (24 minutes ago) commit {amend}: snapshot as of 2024-02-24
     ! [master@{1}] (1 day ago) commit (amend): snapshot as of 2024-02-23
      ! [master@{2}] (2 days ago) commit: snapshot as of 2024-02-22
       ! [master@{3}] (3 days ago) commit: add 'bar'
        ! [master@{4}] (7 days ago) commit: add 'foo'
    -----
    +     [master@{0}] snapshot as of 2024-02-24
     +    [master@{1}] snapshot as of 2024-02-23
      +   [master@{2}] snapshot as of 2024-02-22
    ++++  [master@{3}] add 'bar'
    +++++ [master@{4}] add 'foo'

and that output is sort-of readable (if you have seen and know how
to read what show-branch produces, that is), but the command way
predates commit slabs and uses the usual object flag bits, so it is
limited to show only 25 or so commits [*1*].

Now, if I could run

    $ git log --oneline --graph -g --since=2024-02-20 --boundary

on the result, such a history might look like this:

    * snapshot as of 2024-02-24 (HEAD)
    | * snapshot as of 2024-02-23 (HEAD@{1})
    |/
    | * snapshot as of 2024-02-22 (HEAD@{2})
    |/
    * add 'bar' (HEAD~1)
    o add 'foo' (HEAD~2)

to show the same history.

Unfortunately, "--graph" and "-g" does not mix X-<.

So, the RFD is,

 (1) Should "git log" learn a trick to show a history like this in a
     readable way?  Does it have utility outside this use case of
     mine?  I am not interested in adding a new feature just for
     myself ;-)

 (2) The use case requires a solution to look at reflog entries, but
     it does not need to "walk" reflog [*2*].  Should such a feature
     still be tied to the "-g" flag, or should we want a separate
     flag?

 (3) What should the UI and the implementation look like?  "Show me
     what happened to this branch since 2024-02-20, including what
     is in reflog" that results in:

     - we first enumerate commits on the reflog of this branch that
       were made since the given date.

     - we then pretend as if all of these commits were given on the
       command line of "git log --oneline --graph", with some other
       commits that probably are ancestors of these commits marked
       as UNINTERESTING.

     may be a promising approach to go.  In the sample history
     depicted above, we would want an equivalent to

       $ git log --oneline --graph HEAD HEAD@{1} HEAD@{2} --not HEAD~2

     where the positive commits are gathered by inspecting the
     reflog for commits newer than 2024-02-20, and then list of
     negative commits (HEAD~2 in this case) is somehow computed to
     stop the usual "git log" traversal from these positive commits
     after showing all of them (and before showing other commits not
     in that initial set).

Thoughts?

[Footnotes]

 *1* It may be an interesting side project to teach show-branch to
     store the bits it uses to paint commits in commit slabs,
     instead of using the object flags, to lift this limitation.
     I'll not put the l e f t o v e r b i t s label on this item, as
     it certainly is an interesting exercise but its usefulness is
     rather dubious.

 *2* "walking" reflog stresses the fact that HEAD@{2} came
     immediately before HEAD@{1} which came immediately before
     HEAD@{0} (or HEAD, which are equivalents), but in this use
     case, it is equally (if not more) important that the snapshots
     taken on 2024-02-22, 2024-02-23, and on 2024-02-24 are more or
     less equals, with the latest one a bit more important than
     others because it is on the branch while the other ones are not
     and merely appear in the reflog.