From: "Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>
To: git@vger.kernel.org
Subject: Re: git-diff-tree(1) can already do the important parts of git-format-rev(1)
Date: Sat, 17 Oct 2026 18:34:13 +0200 [thread overview]
Message-ID: <238e5652-e95b-4d44-a900-e16aa6ab81f0@app.fastmail.com> (raw)
In-Reply-To: <2c1656e2-a054-43c2-94cc-31625f8c69e9@app.fastmail.com>
On Thu, Oct 15, 2026, at 20:42, Kristoffer Haugsbakk wrote:
> On Thu, Oct 15, 2026, at 12:35, Kristoffer Haugsbakk wrote:
>>[snip]
>>
>> git rev-list HEAD |
>> git diff-tree --stdin --format=medium --no-patch -m
>>
>> You have “on-demand pretty formatting”
>
> But for multiline pretties you need NUL termination. And this is what
> `-z` says:
>
> When --raw, --numstat, --name-only or --name-status has been given,
> do not munge pathnames and use NULs as output field terminators.
>
> Without this option, pathnames with "unusual" characters are quoted
> as explained for the configuration variable core.quotePath (see
> git-config(1)).
>
> So `-z` only applies to some primitive and name-centric diff
> formats. And that’s why my later footnote is wrong:
>
>>[snip]
>>
>> † 1: git-format-rev(1) also supports NUL-terminated input in order to
>> deal with multiline revision expressions.[3] And `-Z` for
>> git-cat-file(1) does that too (both input and output), so the pair
>> git-cat-file(1)/git-diff-tree(1) is equally expressive.
>>
>> 🔗 3: https://lore.kernel.org/git/e8bb57a2-8eff-4f72-96ca-72d8880901e0@gmail.com/
But I was wrong again. git-diff-tree(1) supports NUL for pretty printing
(`-v`). I was only looking at one single output. But with “separator”
delimiters (either newline or NUL) there is no delimiter for one single
record (output). That’s why it didn’t show up for me. (thanks `cat -A`)
But the separator behavior is a problem. Because when consuming input
piecemeal (like reading from a shell coproc) you need a terminator. But
the `log-tree.c` functionality very diligently keeps itself to using
separators:
1. You feed one commit: you get the output with no delimiter
2. You feed another one: now there are two output records so a delimiter
is needed. *Then* a separator is printed right before the record
3. Repeat
4. Of course the final record will not have a delimiter at the end
I experimented with forcing terminator behavior but it seems that
git-diff-tree(1) is just unwilling.
But it seems that one can just add a `--use-terminator` option
commands that use `tree-log.c` (I think by adding it to `revision.c:
handle_revision_opt`). Then I can use a git-diff-tree(1) that acts like
git-format-rev(1) with `--stdin-mode=revs`... and in fact a bit better
(see previous).
All of this for pretty-printing (`-z`). For `--patch` (cf. raw diff)
there is no NUL delimiter support.
THE CONTEXT
I am working on a shell script that needs to construct a git-log(1)/
git-format-patch(1)-like output. Each commit message describes a range
of commits. And the optional patch/diff output is the interdiff between
each range if they happen to share the same base. This is like
git-format-patch(1) with `--interdiff`. So what I need for each
record/entry in the log:
1. A commit message
2. An interdiff if wanted and if it can be produced
What I have done, respectively:
1. A coproc for `git format-rev --stdin-mode=revs`
2. Individual calls to git-diff-tree(1) (not `--stdin`)
Somewhat incidental to this, I figured out that git-diff-tree(1) can
almost replace `git format-rev --stdin`.
But when I turned to git-diff-tree(1) and tried to transform (2) into a
coproc. But that seems to not be feasible, since it seems that
NUL-termination is not supported for diffs that a person would want
to look at.
prev parent reply other threads:[~2026-10-17 16:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 10:35 git-diff-tree(1) can already do the important parts of git-format-rev(1) Kristoffer Haugsbakk
2026-10-15 18:42 ` Kristoffer Haugsbakk
2026-10-17 16:34 ` Kristoffer Haugsbakk [this message]
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=238e5652-e95b-4d44-a900-e16aa6ab81f0@app.fastmail.com \
--to=kristofferhaugsbakk@fastmail.com \
--cc=git@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.