<feed xmlns='http://www.w3.org/2005/Atom'>
<title>git/t/t4020-diff-external.sh, branch jch</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/git/git.git/
</subtitle>
<id>https://git.shady.money/git/atom?h=jch</id>
<link rel='self' href='https://git.shady.money/git/atom?h=jch'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/'/>
<updated>2025-10-24T17:15:21Z</updated>
<entry>
<title>diff: send external diff output to diff_options.file</title>
<updated>2025-10-24T17:15:21Z</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2025-10-24T17:06:49Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=57c2b6cc86edd29fa2d30bc53b4a476e0621619c'/>
<id>urn:sha1:57c2b6cc86edd29fa2d30bc53b4a476e0621619c</id>
<content type='text'>
Diff output usually goes to the process stdout, but it can be redirected
with the "--output" option. We store this in the "file" pointer of
diff_options, and all of the diff code should write there instead of to
stdout.

But there's one spot we missed: running an external diff cmd. We don't
redirect its output at all, so it just defaults to the stdout of the
parent process. We should instead point its stdout at our output file.
There are a few caveats to watch out for when doing so:

  - The stdout field takes a descriptor, not a FILE pointer. We can pull
    out the descriptor with fileno().

  - The run-command API always closes the stdout descriptor we pass to
    it. So we must duplicate it (otherwise we break the FILE pointer,
    since it now points to a closed descriptor).

  - We don't need to worry about closing our dup'd descriptor, since the
    point is that run-command will do it for us (even in the case of an
    error). But we do need to make sure we skip the dup() if we set
    no_stdout (because then run-command will not look at it at all).

  - When the output is going to stdout, it would not be wrong to dup()
    the descriptor, but we don't need to. We can skip that extra work
    with a simple pointer comparison.

  - It seems like you'd need to fflush() the descriptor before handing
    off a copy to the child process to prevent out-of-order writes. But
    that was true even before this patch! It works because run-command
    always calls fflush(NULL) before running the child.

The new test shows the breakage (and fix). The need for duplicating the
descriptor doesn't need a new test; that is covered by the later test
"GIT_EXTERNAL_DIFF with more than one changed files".

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t: refactor tests depending on Perl transliteration operator</title>
<updated>2025-04-07T21:47:38Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2025-04-03T05:06:01Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=db8ff64a3a5244b44e27e0d46a48a304a2e36456'/>
<id>urn:sha1:db8ff64a3a5244b44e27e0d46a48a304a2e36456</id>
<content type='text'>
We have a bunch of tests that use Perl to perform character
transliteration via the "y/" or "tr/" operator. These usecases can be
trivially replaced with tr(1).

Refactor the tests accordingly so that we can drop a couple of
PERL_TEST_HELPERS prerequisites.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t: introduce PERL_TEST_HELPERS prerequisite</title>
<updated>2025-04-07T21:47:37Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2025-04-03T05:05:57Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=23e21a58d5c7b5ae7b4b5532933e0f82e24024fe'/>
<id>urn:sha1:23e21a58d5c7b5ae7b4b5532933e0f82e24024fe</id>
<content type='text'>
In the early days of Git, Perl was used quite prominently throughout the
project. This has changed significantly as almost all of the executables
we ship nowadays have eventually been rewritten in C. Only a handful of
subsystems remain that require Perl:

  - gitweb, a read-only web interface.

  - A couple of scripts that allow importing repositories from GNU Arch,
    CVS and Subversion.

  - git-send-email(1), which can be used to send mails.

  - git-request-pull(1), which is used to request somebody to pull from
    a URL by sending an email.

  - git-filter-branch(1), which uses Perl with the `--state-branch`
    option. This command is typically recommended against nowadays in
    favor of git-filter-repo(1).

  - Our Perl bindings for Git.

  - The netrc Git credential helper.

None of these subsystems can really be considered to be part of the
"core" of Git, and an installation without them is fully functional.
It is more likely than not that an end user wouldn't even notice that
any features are missing if those tools weren't installed. But while
Perl nowadays very much is an optional dependency of Git, there is a
significant limitation when Perl isn't available: developers cannot run
our test suite.

Preceding commits have started to lift this restriction by removing the
strict dependency on Perl in many central parts of the test library. But
there are still many tests that rely on small Perl helpers to do various
different things.

Introduce a new PERL_TEST_HELPERS prerequisite that guards all tests
that require Perl. This prerequisite is explicitly different than the
preexisting PERL prerequisite:

  - PERL records whether or not features depending on the Perl
    interpreter are built.

  - PERL_TEST_HELPERS records whether or not a Perl interpreter is
    available for our tests.

By having these two separate prerequisites we can thus distinguish
between tests that inherently depend on Perl because the underlying
feature does, and those tests that depend on Perl because the test
itself is using Perl.

Adapt all tests to set the PERL_TEST_HELPERS prerequisite as needed.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t: remove TEST_PASSES_SANITIZE_LEAK annotations</title>
<updated>2024-11-20T23:23:48Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-11-20T13:39:56Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=fc1ddf42af6742fae7e770cae20e30d7902014c0'/>
<id>urn:sha1:fc1ddf42af6742fae7e770cae20e30d7902014c0</id>
<content type='text'>
Now that the default value for TEST_PASSES_SANITIZE_LEAK is `true` there
is no longer a need to have that variable declared in all of our tests.
Drop it.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t: remove unneeded !SANITIZE_LEAK prerequisites</title>
<updated>2024-11-20T23:23:47Z</updated>
<author>
<name>Patrick Steinhardt</name>
<email>ps@pks.im</email>
</author>
<published>2024-11-20T13:39:54Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=0b7f0ce751d1326abe1aba8ed700a8d46cdf9f7a'/>
<id>urn:sha1:0b7f0ce751d1326abe1aba8ed700a8d46cdf9f7a</id>
<content type='text'>
We have a couple of !SANITIZE_LEAK prerequisites for tests that used to
fail due to memory leaks. These have all been fixed by now, so let's
drop the prerequisite.

Signed-off-by: Patrick Steinhardt &lt;ps@pks.im&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>diff: let external diffs report that changes are uninteresting</title>
<updated>2024-06-10T16:20:46Z</updated>
<author>
<name>René Scharfe</name>
<email>l.s.r@web.de</email>
</author>
<published>2024-06-09T07:41:44Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=d7b97b7185521e3b9364b3abc6553df2480da173'/>
<id>urn:sha1:d7b97b7185521e3b9364b3abc6553df2480da173</id>
<content type='text'>
The options --exit-code and --quiet instruct git diff to indicate
whether it found any significant changes by exiting with code 1 if it
did and 0 if there were none.  Currently this doesn't work if external
diff programs are involved, as we have no way to learn what they found.

Add that ability in the form of the new configuration options
diff.trustExitCode and diff.&lt;driver&gt;.trustExitCode and the environment
variable GIT_EXTERNAL_DIFF_TRUST_EXIT_CODE.  They pair with the config
options diff.external and diff.&lt;driver&gt;.command and the environment
variable GIT_EXTERNAL_DIFF, respectively.

The new options are off by default, keeping the old behavior.  Enabling
them indicates that the external diff returns exit code 1 if it finds
significant changes and 0 if it doesn't, like diff(1).

The name of the new options is taken from the git difftool and mergetool
options of similar purpose.  (There they enable passing on the exit code
of a diff tool and to infer whether a merge done by a merge tool is
successful.)

The new feature sets the diff flag diff_from_contents in
diff_setup_done() if we need the exit code and are allowed to call
external diffs.  This disables the optimization that avoids calling the
program with --quiet.  Add it back by skipping the call if the external
diff is not able to report empty diffs.  We can only do that check after
evaluating the file-specific attributes in run_external_diff().

If we do run the external diff with --quiet, send its output to
/dev/null.

I considered checking the output of the external diff to check whether
its empty.  It was added as 11be65cfa4 (diff: fix --exit-code with
external diff, 2024-05-05) and quickly reverted, as it does not work
with external diffs that do not write to stdout.  There's no reason why
a graphical diff tool would even need to write anything there at all.

I also considered using a non-zero exit code for empty diffs, which
could be done without adding new configuration options.  We'd need to
disable the optimization that allows git diff --quiet to skip calling
external diffs, though -- that might be quite surprising if graphical
diff programs are involved.  And assigning the opposite meaning of the
exit codes compared to diff(1) and git diff --exit-code to the external
diff can cause unnecessary confusion.

Suggested-by: Phillip Wood &lt;phillip.wood123@gmail.com&gt;
Signed-off-by: René Scharfe &lt;l.s.r@web.de&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>t4020: test exit code with external diffs</title>
<updated>2024-06-10T16:19:20Z</updated>
<author>
<name>René Scharfe</name>
<email>l.s.r@web.de</email>
</author>
<published>2024-06-09T07:38:24Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=33be6cf51acf74e623fb3c4e287f7aebbedf5c09'/>
<id>urn:sha1:33be6cf51acf74e623fb3c4e287f7aebbedf5c09</id>
<content type='text'>
Add tests to check the exit code of git diff with its options --quiet
and --exit-code when using an external diff program.  Currently we
cannot tell whether it found significant changes or not.

While at it, document briefly that --quiet turns off execution of
external diff programs because that behavior surprised me for a moment
while writing the tests.

Signed-off-by: René Scharfe &lt;l.s.r@web.de&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
</entry>
<entry>
<title>Merge branch 'rs/external-diff-with-exit-code'</title>
<updated>2024-05-16T17:09:23Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-05-16T17:09:23Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=db271e7bb60d42f3d6eadce99ee7cd8749b49754'/>
<id>urn:sha1:db271e7bb60d42f3d6eadce99ee7cd8749b49754</id>
<content type='text'>
* rs/external-diff-with-exit-code:
  Revert "diff: fix --exit-code with external diff"
</content>
</entry>
<entry>
<title>Revert "diff: fix --exit-code with external diff"</title>
<updated>2024-05-16T17:08:35Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-05-16T17:08:35Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=e37423f081bb6e21eb1b77851ab06d72f30aee57'/>
<id>urn:sha1:e37423f081bb6e21eb1b77851ab06d72f30aee57</id>
<content type='text'>
This reverts commit 11be65cfa43416219e85384a3a80d672b65b76ba, per
original author's request to come up with a better strategy.
</content>
</entry>
<entry>
<title>Merge branch 'rs/external-diff-with-exit-code'</title>
<updated>2024-05-15T16:52:54Z</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2024-05-15T16:52:54Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/git/commit/?id=068df18c90c335ebe28bda285e742a6408eec3b5'/>
<id>urn:sha1:068df18c90c335ebe28bda285e742a6408eec3b5</id>
<content type='text'>
The "--exit-code" option of "git diff" command learned to work with
the "--ext-diff" option.

* rs/external-diff-with-exit-code:
  diff: fix --exit-code with external diff
  diff: report unmerged paths as changes in run_diff_cmd()
</content>
</entry>
</feed>
