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

Re: [PATCH] diff: handle negative status in diff_result_code()

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 21, 2023, 15:56 UTC
Message-ID
<xmqqlee4s82d.fsf@gitster.g>
In-Reply-To
<20230821003532.GA1113755@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
> Thanks for your report. And I'm impressed you managed to find such an
> ancient bug. :)
Indeed.  Thanks, both.
Show 22 quoted lines
> Most programs which run a diff (porcelain git-diff, diff-tree, etc) run
> their result through diff_result_code() before presenting it to the user
> as a program return code. That result generally comes from a library
> function like builtin_diff_files(), etc, and may be "-1" if the function
> bailed with an error.
>
>
> There are two problems here:
>
>   - if --exit-code is not in use, then we pass the code along as-is.
>     Even though Unix exit codes are unsigned, this usually works OK
>     because the integer representation, and "-1" ends up as "255". But
>     it's not something we should rely on, and we've tried to avoid it
>     elsewhere. E.g. in 5391e94813 (branch: remove negative exit code,
>     2022-03-29) and 246f0edec0 (execv_dashed_external: stop exiting with
>     negative code, 2017-01-06) and probably others.
>
>   - when --exit-code is in use, we ignore the incoming "status" variable
>     entirely, and rely on the "has_changes" field. But if we saw an
>     error, this field is almost certainly invalid, and means we'd likely
>     just say "no changes", which is completely bogus. Likewise for
>     the "--check" format.

Inspecting some callers of diff_result_code() further finds curiosities. wt-status.c for example feeds results form run_diff_index() and run_diff_files() to the function, neither of which returns anything other than 0. They die or exit(128) themselves, though, so they are OK without this fix. builtin/describe.c is also in the same boat with its use of run_diff_index().

But of course the presense of such codepaths does not invalidate the fix in your patch.

> So let's intercept the negative value here and return an appropriate
> code before even considering --exit-code, etc. And while doing so, we
> can swap out the negative value for a more normal exit code.

Good. As you said, this is not an ungent regression fix, but I'd prefer to see us look at all the current callers, as I wonder if there are positive non-zero numbers coming from some callers, and possibly design how this code should react to such "result" coming in.

Again, thanks, both.
Previous: Jeff KingNext: Junio C Hamano
Message 3 of 19 in “"git diff --no-pager --exit-code" errors out but returns zero exit code”
  1. Romain ChossartAug 20, 2023
  2. diff: handle negative status in diff_result_code()Jeff King, Aug 21, 2023
  3. Junio C HamanoAug 21, 2023
  4. diff: spell DIFF_INDEX_CACHED out when calling run_diff_index()Junio C Hamano, Aug 21, 2023
  5. Jeff KingAug 21, 2023
  6. Junio C HamanoAug 21, 2023
  7. Jeff KingAug 21, 2023
  8. Junio C HamanoAug 21, 2023
  9. 0/7 cleaning up diff_result_code()Jeff King, Aug 21, 2023
  10. 1/7 diff: spell DIFF_INDEX_CACHED out when calling run_diff_index()Jeff King, Aug 21, 2023
  11. 2/7 diff-files: avoid negative exit valueJeff King, Aug 21, 2023
  12. 3/7 diff: show usage for unknown builtin_diff_files() optionsJeff King, Aug 21, 2023
  13. 4/7 diff: die when failing to read index in git-diff builtinJeff King, Aug 21, 2023
  14. Junio C HamanoAug 22, 2023
  15. 5/7 diff: drop useless return from run_diff_{files,index} functionsJeff King, Aug 21, 2023
  16. 6/7 diff: drop useless return values in git-diff helpersJeff King, Aug 21, 2023
  17. 7/7 diff: drop useless "status" parameter from diff_result_code()Jeff King, Aug 21, 2023
  18. Junio C HamanoAug 22, 2023
  19. Jeff KingAug 23, 2023

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.