Re: [PATCH v2] diff: fix interaction between the "-s" option and other options
- From
Eric Sunshine <sunshine@sunshineco.com>
- Date
- May 5, 2023, 17:41 UTC
- Message-ID
- <CAPig+cT=3dmtEEApiPUvB9+5ZHx+uwc1NXhYsf4peYiSwPYPsQ@mail.gmail.com>
- In-Reply-To
- <20230505165952.335256-1-gitster@pobox.com>
On Fri, May 5, 2023 at 1:02 PM Junio C Hamano <gitster@pobox.com> wrote:
Show 26 quoted lines
> Sergey Organov noticed and reported "--patch --no-patch --raw" > behaves differently from just "--raw". It turns out that there are > a few interesting bugs in the implementation and documentation. > > * First, the documentation for "--no-patch" was unclear that it > could be read to mean "--no-patch" countermands an earlier > "--patch" but not other things. The intention of "--no-patch" > ever since it was introduced at d09cd15d (diff: allow --no-patch > as synonym for -s, 2013-07-16) was to serve as a synonym for > "-s", so "--raw --patch --no-patch" should have produced no > output, but it can be (mis)read to allow showing only "--raw" > output. > > * Then the interaction between "-s" and other format options were > poorly implemented. Modern versions of Git uses one bit each to > represent formatting options like "--patch", "--stat" in a single > output_format word, but for historical reasons, "-s" also is > represented as another bit in the same word. This allows two > interesting bugs to happen, and we have both X-<. > > (1) After setting a format bit, then setting NO_OUTPUT with "-s", > the code to process another "--<format>" option drops the > NO_OUTPUT bit to allow output to be shown again. However, > the code to handle "-s" only set NO_OUTPUT without unsetting > format bits set earlier, so the earlier format bit got > revealed upon seeing the second "--<format>" option. This is
Glad to see "THis" from v1 fixed.
Show 23 quoted lines
> the problem Sergey observed. > > (2) After setting NO_OUTPUT with "-s", code to process > "--<format>" option can forget to unset NO_OUTPUT, leaving > the command still silent. > > It is tempting to change the meaning of "--no-patch" to mean > "disable only the patch format output" and reimplement "-s" as "not > showing anything", but it would be an end-user visible change in > behavior. Let's fix the interactions of these bits to first make > "-s" work as intended. > > The fix is conceptually very simple. > > * Whenever we set DIFF_FORMAT_FOO because we saw the "--foo" > option (e.g. DIFF_FORMAT_RAW is set when the "--raw" option is > given), we make sure we drop DIFF_FORMAT_NO_OUTPUT. We forgot to > do so in some of the options and caused (2) above. > > * When processing "-s" option, we should not just set > DIFF_FORMAT_NO_OUTPUT bit, but clear other DIFF_FORMAT_* bits. > We didn't do so and retained format bits set by options > previously seen, causing (1) above.
The above description is very clear and well stated, even to someone like me who didn't follow the discussion which culminated in this patch.
Show 28 quoted lines
> It is even more tempting to lose NO_OUTPUT bit and instead take > output_format word being 0 as its replacement, but that would break > the mechanism "git show" uses to default to "--patch" output, where > the distinction between telling the command to be silent with "-s" > and having no output format specified on the command line matters, > and an explicit output format given on the command line should not > be "combined" with the default "--patch" format. > > So, while we cannot lose the NO_OUTPUT bit, as a follow-up work, we > may want to replace it with OPTION_GIVEN bit, and > > * make "--patch", "--raw", etc. set DIFF_FORMAT_$format bit and > DIFF_FORMAT_OPTION_GIVEN bit on for each format. "--no-raw", > etc. will set off DIFF_FORMAT_$format bit but still record the > fact that we saw an option from the command line by setting > DIFF_FORMAT_OPTION_GIVEN bit. > > * make "-s" (and its synonym "--no-patch") clear all other bits > and set only the DIFF_FORMAT_OPTION_GIVEN bit on. > > which I suspect would make the code much cleaner without breaking > any end-user expectations. > > Once that is in place, transitioning "--no-patch" to mean the > counterpart of "--patch", just like "--no-raw" only defeats an > earlier "--raw", would be quite simple at the code level. The > social cost of migrating the end-user expectations might be too > great for it to be worth, but at least the "GIVEN" bit clean-up
s/worth/worthwhile/
> alone may be worth it.
And this final part addresses the big question which v1 left dangling (specifically, "why the proposed patch doesn't eliminate NO_OUTPUT altogether). Good.
> Signed-off-by: Junio C Hamano <gitster@pobox.com>