Git development
 help / color / mirror / Atom feed
From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Toon Claes <toon@iotcl.com>
Cc: Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>,
	 git@vger.kernel.org, Elijah Newren <newren@gmail.com>,
	 Patrick Steinhardt <ps@pks.im>
Subject: Re: [PATCH/RFC 4/5] test-tool: add a "historian" subcommand for building merge fixtures
Date: Sun, 17 May 2026 13:40:03 +0200 (CEST)	[thread overview]
Message-ID: <13abccc6-60f7-64ea-db38-e61abb42c159@gmx.de> (raw)
In-Reply-To: <87lddooq2t.fsf@toon--20250203-5JQV3.mail-host-address-is-not-set>

Hi Toon,

On Tue, 12 May 2026, Toon Claes wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
> > diff --git a/t/helper/test-historian.c b/t/helper/test-historian.c
> > new file mode 100644
> > index 0000000000..2250d420c0
> > --- /dev/null
> > +++ b/t/helper/test-historian.c
> > @@ -0,0 +1,189 @@
> > +/*
> > + * Build a small history out of a tiny declarative input. Used by tests
> > + * that need specific merge topologies without long sequences of
> > + * plumbing commands or fragile shell helpers.
> > + *
> > + * The historian reads stdin line by line and emits an equivalent
> > + * stream to a `git fast-import` child process. It also allocates marks
> > + * for named objects so tests can refer to commits and blobs by name.
> 
> Really appreciate you're introducing this command. I'm actually
> surprised no else did before.

Heh. I am not surprised, though. Given that it is _really_ hard to come up
with a decent Domain-Specific Language to describe commit history for
defining test fixtures (testament to which are your comments below), I was
debating whether to go for range-diff's/libgit2's approach and simply
adding a bare repository or a fast-import script as a fixture. But that
would make the test code even harder to follow! And I did not want to add
to the amount of hard-to-follow test code.

> > + *
> > + * Input directives (one per line, shell-style quoting):
> > + *
> > + *	blob NAME LINE1 LINE2 ...
> > + *	    Each LINE becomes a content line in the blob; lines are
> > + *	    joined with '\n' and the blob ends with a final '\n'. With
> > + *	    no LINEs, the blob is empty.
> > + *
> > + *	commit NAME BRANCH SUBJECT [from=PARENT] [merge=PARENT]... [PATH=BLOB]...
> 
> I'm not sure how I feel about mixing named arguments (like `from=PARENT`) with
> the `PATH=BLOB` arguments? Obviously this tool isn't made for anything
> that's even close to production, but still feels strange. How about
> putting a double dash (`--`) before the paths, or using the `PATH:BLOB`
> syntax instead?

Okay, I can see that's a better design. To be honest, I did not really
optimize for unambiguity here, but for precision of defining a test
fixture. As such, I am mostly interested in keeping the definition as
small as possible without losing readability. Changing that `=` to a `:`
to disambiguate keeps the same length while clarifying the structure. I
like it!

> > + *	    Creates a commit on refs/heads/BRANCH using the listed
> > + *	    file=blob mappings as the entire tree (no inheritance from
> > + *	    parents). Up to one `from=` and any number of `merge=`
> > + *	    parents may be given. `from=` defaults to the current branch
> > + *	    tip; if BRANCH has no tip yet, the commit becomes a root.
> 
> At GitLab in our Gitaly suite we have a similar tool as what you're
> introducing here, but there you have to specify the parent(s) for each
> commit and if you want to assign a ref to a commit, you have to be
> explicit about it. So I would replace `from=` and `merge=` with
> `parent=` and allow that to be occur zero or more times (this would also
> allow creating unrelated histories). And remove the mandatory argument
> BRANCH, and instead allow the command to accept a `branch=` argument.
> 
> If we'd take an example from the follow-up commit:
> 
>         # Setup:
>         #       A (a) --- C (a, h) ----+--- M (a, g, h)
>         #        \                    /
>         #         +-- B (a, g) ------+
>         #
>         # Topic touches `g` only; main touches `h` only. The auto-merge
>         # at M is clean.
>         blob a "shared content"
>         blob g guarded
>         blob h host
>         commit A main "A" a=a
>         commit B topic "B (introduces g)" from=A a=a g=g
>         commit C main "C (introduces h)" a=a h=h
>         commit M main "Merge topic" merge=B a=a g=g h=h
> 
> I would suggest to rewrite that to:
> 
>         blob a "shared content"
>         blob g guarded
>         blob h host
>         commit A "A" a:a
>         commit B "B (introduces g)" parent=A branch=topic a:a g:g
>         commit C "C (introduces h)" parent=A a:a h:h
>         commit M "Merge topic" parent=A parent=B ref=main a:a g:g h:h
> 
> I realize this is less alike to git-fast-import(1), so I'd understand if
> you'd reject this idea.

That makes sense to me!

I'm not interested in keeping the `historian` code as small as possible, I
am interested in reducing the cognitive load required to read and write
those test fixtures. Therefore, the `parent=` way is much preferable.

Thank you!
Johannes

  reply	other threads:[~2026-05-17 11:41 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-06 22:43 [PATCH/RFC 0/5] replay: support replaying 2-parent merges Johannes Schindelin via GitGitGadget
2026-05-06 22:43 ` [PATCH/RFC 1/5] " Johannes Schindelin via GitGitGadget
2026-05-08  9:36   ` Phillip Wood
2026-05-08 10:05     ` Phillip Wood
2026-05-17 14:33       ` Johannes Schindelin
2026-05-17 14:32     ` Johannes Schindelin
2026-05-06 22:43 ` [PATCH/RFC 2/5] replay: short-circuit merge replay when parent and base trees are unchanged Johannes Schindelin via GitGitGadget
2026-05-06 22:43 ` [PATCH/RFC 3/5] history.adoc: describe merge-replay support and its limits Johannes Schindelin via GitGitGadget
2026-05-06 22:43 ` [PATCH/RFC 4/5] test-tool: add a "historian" subcommand for building merge fixtures Johannes Schindelin via GitGitGadget
2026-05-12 10:54   ` Toon Claes
2026-05-17 11:40     ` Johannes Schindelin [this message]
2026-05-06 22:43 ` [PATCH/RFC 5/5] t3454: cover merge-replay scenarios with the historian helper Johannes Schindelin via GitGitGadget
2026-05-07 14:14 ` [PATCH/RFC 0/5] replay: support replaying 2-parent merges D. Ben Knoble
2026-05-07 15:06   ` Johannes Schindelin
2026-05-07 15:39     ` Ben Knoble
2026-05-17 11:33       ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=13abccc6-60f7-64ea-db38-e61abb42c159@gmx.de \
    --to=johannes.schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=newren@gmail.com \
    --cc=ps@pks.im \
    --cc=toon@iotcl.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox