* [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting
@ 2025-08-27 16:29 kristofferhaugsbakk
2025-08-27 16:29 ` [PATCH 1/4] usage: help the user help themselves kristofferhaugsbakk
` (5 more replies)
0 siblings, 6 replies; 102+ messages in thread
From: kristofferhaugsbakk @ 2025-08-27 16:29 UTC (permalink / raw)
To: git; +Cc: Kristoffer Haugsbakk
From: Kristoffer Haugsbakk <code@khaugsbakk.name>
Based on the recent i-still-use-that reports about whatchanged, improve
the error reporting with this command in mind:
1. Give more possible actions instead of just (only) asking them to send
an email
2. Hint how to replace their git-whatchanged(1) use with git-log(1)
3. Minor documentation changes
I don’t know how much does matters now that 2.51.0 is out. I guess it
depends on when the next maintenance release is and how many platforms
will upgrade it? I don’t know anything about that. (But maybe they
will do it straight away since they are releasing for the latest
version?)
Kristoffer Haugsbakk (4):
usage: help the user help themselves
whatchanged: tell users the git-log(1) equivalent
whatchanged: remove not-even-shorter clause
BreakingChanges: remove claim about whatchanged reports
Documentation/BreakingChanges.adoc | 2 +-
Documentation/git-whatchanged.adoc | 8 ++++++--
builtin/log.c | 8 ++++++--
builtin/pack-redundant.c | 2 +-
git-compat-util.h | 2 +-
usage.c | 31 +++++++++++++++++++++++-------
6 files changed, 39 insertions(+), 14 deletions(-)
base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0
--
2.51.0.11.g23cedd8a747
^ permalink raw reply [flat|nested] 102+ messages in thread* [PATCH 1/4] usage: help the user help themselves 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk @ 2025-08-27 16:29 ` kristofferhaugsbakk 2025-08-27 20:36 ` Kristoffer Haugsbakk 2025-08-27 16:29 ` [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk ` (4 subsequent siblings) 5 siblings, 1 reply; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-27 16:29 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: git-scm has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): An alternative to linking to git-scm is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..29988395f19 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,22 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org>\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.11.g23cedd8a747 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 16:29 ` [PATCH 1/4] usage: help the user help themselves kristofferhaugsbakk @ 2025-08-27 20:36 ` Kristoffer Haugsbakk 2025-08-27 21:02 ` Eric Sunshine 2025-08-27 21:14 ` Junio C Hamano 0 siblings, 2 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-08-27 20:36 UTC (permalink / raw) To: Kristoffer Haugsbakk, git > usage: help the user help themselves I think I’ll change the area to the more pointed: you-still-use-that??: On Wed, Aug 27, 2025, at 18:29, kristofferhaugsbakk@fastmail.com wrote: > @@ -377,12 +378,22 @@ void bug_fl(const char *file, int line, const char *fmt, ...) > > NORETURN void you_still_use_that(const char *command_name) > { > + struct strbuf percent_encoded = STRBUF_INIT; > + strbuf_add_percentencode(&percent_encoded, > + command_name, > + STRBUF_ENCODE_SLASH); > + > fprintf(stderr, > _("'%s' is nominated for removal.\n" > - "If you still use this command, please add an extra\n" > - "option, '--i-still-use-this', on the command line\n" > - "and let us know you still use it by sending an e-mail\n" > - "to <git@vger.kernel.org>. Thanks.\n"), > - command_name); > + "If you still use this command, here's what you can do:\n" > + "\n" > + "- read https://git-scm.com/docs/BreakingChanges.html\n" > + "- check if anyone has discussed this on the mailing\n" > + " list and if they came up with something that can\n" > + " help you: https://lore.kernel.org/git/?q=%s\n" > + "- send an email to <git@vger.kernel.org>\n" Maybe (thinking out loud) this should retain some part of the “let us know you still use this” spirit: - send an email to <git@vger.kernel.org> and let us know that you still use this command > + "\n"), > + command_name, percent_encoded.buf); > + strbuf_release(&percent_encoded); > die(_("refusing to run without --i-still-use-this")); > } > -- > 2.51.0.11.g23cedd8a747 ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 20:36 ` Kristoffer Haugsbakk @ 2025-08-27 21:02 ` Eric Sunshine 2025-08-27 21:20 ` Junio C Hamano 2025-08-27 21:14 ` Junio C Hamano 1 sibling, 1 reply; 102+ messages in thread From: Eric Sunshine @ 2025-08-27 21:02 UTC (permalink / raw) To: Kristoffer Haugsbakk; +Cc: Kristoffer Haugsbakk, git On Wed, Aug 27, 2025 at 4:36 PM Kristoffer Haugsbakk <code@khaugsbakk.name> wrote: > On Wed, Aug 27, 2025, at 18:29, kristofferhaugsbakk@fastmail.com wrote: > > fprintf(stderr, > > _("'%s' is nominated for removal.\n" > > + "If you still use this command, here's what you can do:\n" > > + "\n" > > + "- read https://git-scm.com/docs/BreakingChanges.html\n" > > + "- check if anyone has discussed this on the mailing\n" > > + " list and if they came up with something that can\n" > > + " help you: https://lore.kernel.org/git/?q=%s\n" > > + "- send an email to <git@vger.kernel.org>\n" > > Maybe (thinking out loud) this should retain some part of the “let us > know you still use this” spirit: > > - send an email to <git@vger.kernel.org> and let us know > that you still use this command That's still inviting unnecessary emails, isn't it? It would probably be better add the qualification that people should send the email only if they were unable to find any workable replacement. Perhaps: - send an email to <git@...> to let us know that you still use this command and were unable to determine a suitable replacement ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 21:02 ` Eric Sunshine @ 2025-08-27 21:20 ` Junio C Hamano 2025-08-27 21:27 ` Eric Sunshine 0 siblings, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 21:20 UTC (permalink / raw) To: Eric Sunshine; +Cc: Kristoffer Haugsbakk, Kristoffer Haugsbakk, git Eric Sunshine <sunshine@sunshineco.com> writes: > That's still inviting unnecessary emails, isn't it? It would probably > be better add the qualification that people should send the email only > if they were unable to find any workable replacement. Perhaps: > > - send an email to <git@...> to let us know > that you still use this command and were unable > to determine a suitable replacement In practice, people will respond to such an instruction by always sending an e-mail. Asking others who sound as if they are promising to give answers when asked is cheaper than investigating themselves ;-). ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 21:20 ` Junio C Hamano @ 2025-08-27 21:27 ` Eric Sunshine 2025-08-27 22:26 ` Junio C Hamano 2025-09-03 16:50 ` Eric Sunshine 0 siblings, 2 replies; 102+ messages in thread From: Eric Sunshine @ 2025-08-27 21:27 UTC (permalink / raw) To: Junio C Hamano; +Cc: Kristoffer Haugsbakk, Kristoffer Haugsbakk, git On Wed, Aug 27, 2025 at 5:20 PM Junio C Hamano <gitster@pobox.com> wrote: > Eric Sunshine <sunshine@sunshineco.com> writes: > > That's still inviting unnecessary emails, isn't it? It would probably > > be better add the qualification that people should send the email only > > if they were unable to find any workable replacement. Perhaps: > > > > - send an email to <git@...> to let us know > > that you still use this command and were unable > > to determine a suitable replacement > > In practice, people will respond to such an instruction by always > sending an e-mail. Asking others who sound as if they are promising > to give answers when asked is cheaper than investigating themselves Thanks for pointing out that my final editing made my suggested wording too succinct. What I really had in mind -- in conjunction with Kristoffer's patch [2/4] which provides hint(s) for replacing the command being retired -- was to reference the provided hints. So, something like this: - send an email to <...> to let us know that you still use this command and were unable to determine a suitable replacement using the hints provided here ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 21:27 ` Eric Sunshine @ 2025-08-27 22:26 ` Junio C Hamano 2025-08-28 6:39 ` Kristoffer Haugsbakk 2025-09-03 16:50 ` Eric Sunshine 1 sibling, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 22:26 UTC (permalink / raw) To: Eric Sunshine; +Cc: Kristoffer Haugsbakk, Kristoffer Haugsbakk, git Eric Sunshine <sunshine@sunshineco.com> writes: > command being retired -- was to reference the provided hints. So, > something like this: > > - send an email to <...> to let us know > that you still use this command and were unable > to determine a suitable replacement using the hints > provided here Ah, of course, yes, with Kristoffer's update to tell what the alternative is, your phrasing is perfect. Thanks. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 22:26 ` Junio C Hamano @ 2025-08-28 6:39 ` Kristoffer Haugsbakk 2025-08-28 15:09 ` Junio C Hamano 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-08-28 6:39 UTC (permalink / raw) To: Junio C Hamano, Eric Sunshine; +Cc: Kristoffer Haugsbakk, git On Thu, Aug 28, 2025, at 00:26, Junio C Hamano wrote: > Eric Sunshine <sunshine@sunshineco.com> writes: > >> command being retired -- was to reference the provided hints. So, >> something like this: >> >> - send an email to <...> to let us know >> that you still use this command and were unable >> to determine a suitable replacement using the hints >> provided here > > Ah, of course, yes, with Kristoffer's update to tell what the > alternative is, your phrasing is perfect. I think so too. Just keep in mind that pack-redundant does not have that part. I think I’ll use that suggestion verbatim. -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-28 6:39 ` Kristoffer Haugsbakk @ 2025-08-28 15:09 ` Junio C Hamano 0 siblings, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-08-28 15:09 UTC (permalink / raw) To: Kristoffer Haugsbakk; +Cc: Eric Sunshine, Kristoffer Haugsbakk, git "Kristoffer Haugsbakk" <code@khaugsbakk.name> writes: > On Thu, Aug 28, 2025, at 00:26, Junio C Hamano wrote: >> Eric Sunshine <sunshine@sunshineco.com> writes: >> >>> command being retired -- was to reference the provided hints. So, >>> something like this: >>> >>> - send an email to <...> to let us know >>> that you still use this command and were unable >>> to determine a suitable replacement using the hints >>> provided here >> >> Ah, of course, yes, with Kristoffer's update to tell what the >> alternative is, your phrasing is perfect. > > I think so too. Just keep in mind that pack-redundant does not have > that part. For pack-redundant, isn't it because there is no need to find suitable replacement? That is, instead of finding a redundant pack, all of whose objects are contained in some other packs, which practically is impossible to exist in a non-toy repository, and deal with it yourself, you can let the normal "repack" to eject redundant objects from all the non-kept packs. > I think I’ll use that suggestion verbatim. Sounds good. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 21:27 ` Eric Sunshine 2025-08-27 22:26 ` Junio C Hamano @ 2025-09-03 16:50 ` Eric Sunshine 2025-09-03 17:53 ` Kristoffer Haugsbakk 2025-09-09 20:01 ` Kristoffer Haugsbakk 1 sibling, 2 replies; 102+ messages in thread From: Eric Sunshine @ 2025-09-03 16:50 UTC (permalink / raw) To: Junio C Hamano; +Cc: Kristoffer Haugsbakk, Kristoffer Haugsbakk, git On Wed, Aug 27, 2025 at 5:27 PM Eric Sunshine <sunshine@sunshineco.com> wrote: > On Wed, Aug 27, 2025 at 5:20 PM Junio C Hamano <gitster@pobox.com> wrote: > > Eric Sunshine <sunshine@sunshineco.com> writes: > > > That's still inviting unnecessary emails, isn't it? It would probably > > > be better add the qualification that people should send the email only > > > if they were unable to find any workable replacement. Perhaps: > > > > > > - send an email to <git@...> to let us know > > > that you still use this command and were unable > > > to determine a suitable replacement > > > > In practice, people will respond to such an instruction by always > > sending an e-mail. Asking others who sound as if they are promising > > to give answers when asked is cheaper than investigating themselves > > Thanks for pointing out that my final editing made my suggested > wording too succinct. What I really had in mind -- in conjunction with > Kristoffer's patch [2/4] which provides hint(s) for replacing the > command being retired -- was to reference the provided hints. So, > something like this: > > - send an email to <...> to let us know > that you still use this command and were unable > to determine a suitable replacement using the hints > provided here I realize that the changes made by this series are not in any released version yet, but from reading the emails still arriving which argue for retaining the command for reasons of muscle memory or because of its (strong) mnemonic value, I suspect that the hint(s) this series adds may not be complete enough. In particular, the advice this series adds (use `git log --raw --no-merges`) seems to be primarily aimed at scripted use of the command. But the muscle memory and mnemonic arguments suggest that advice should be given for interactive use, as well, such as proposing that the user can create an alias. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 16:50 ` Eric Sunshine @ 2025-09-03 17:53 ` Kristoffer Haugsbakk 2025-09-03 21:21 ` Eric Sunshine 2025-09-09 20:01 ` Kristoffer Haugsbakk 1 sibling, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-03 17:53 UTC (permalink / raw) To: Eric Sunshine, Junio C Hamano; +Cc: Kristoffer Haugsbakk, git (Sent from mobile, might have mistakes) On Wed, Sep 3, 2025, at 18:50, Eric Sunshine wrote: > I realize that the changes made by this series are not in any released > version yet, but from reading the emails still arriving which argue > for retaining the command for reasons of muscle memory or because of > its (strong) mnemonic value, I suspect that the hint(s) this series > adds may not be complete enough. In particular, the advice this series > adds (use `git log --raw --no-merges`) seems to be primarily aimed at > scripted use of the command. But the muscle memory and mnemonic > arguments suggest that advice should be given for interactive use, as > well, such as proposing that the user can create an alias. Good point. I would suggest discussing it in the breaking changes doc under a new "For Users" section. I would like to avoid expanding the error message too much due to the already mentioned fear of overwhelming folks. I've seen "troubleshooting" questions from git users who got one of those long and well-described Hints like e.g. detached head and default git init branch when either the msg already spelled eveything out or the msg was purely informational. Cheers ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 17:53 ` Kristoffer Haugsbakk @ 2025-09-03 21:21 ` Eric Sunshine 2025-09-03 21:41 ` Kristoffer Haugsbakk 2025-09-03 21:44 ` Jeff King 0 siblings, 2 replies; 102+ messages in thread From: Eric Sunshine @ 2025-09-03 21:21 UTC (permalink / raw) To: Kristoffer Haugsbakk; +Cc: Junio C Hamano, Kristoffer Haugsbakk, git On Wed, Sep 3, 2025 at 1:54 PM Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> wrote: > On Wed, Sep 3, 2025, at 18:50, Eric Sunshine wrote: > > I realize that the changes made by this series are not in any released > > version yet, but from reading the emails still arriving which argue > > for retaining the command for reasons of muscle memory or because of > > its (strong) mnemonic value, I suspect that the hint(s) this series > > adds may not be complete enough. In particular, the advice this series > > adds (use `git log --raw --no-merges`) seems to be primarily aimed at > > scripted use of the command. But the muscle memory and mnemonic > > arguments suggest that advice should be given for interactive use, as > > well, such as proposing that the user can create an alias. > > Good point. I would suggest discussing it in the > breaking changes doc under a new "For Users" > section. I would like to avoid expanding the error > message too much due to the already mentioned > fear of overwhelming folks. I have doubts that users will consult a document when presented with the message. > I've seen "troubleshooting" questions from git users > who got one of those long and well-described Hints > like e.g. detached head and default git init branch > when either the msg already spelled eveything out > or the msg was purely informational. I didn't spell it out above, but what I had in mind was something very simple... not at all ong and detailed; for instance: For interactive use, define a Git alias `git whatchanged` which runs `git log --raw --no-merges`. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 21:21 ` Eric Sunshine @ 2025-09-03 21:41 ` Kristoffer Haugsbakk 2025-09-03 21:44 ` Jeff King 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-03 21:41 UTC (permalink / raw) To: Eric Sunshine; +Cc: Junio C Hamano, Kristoffer Haugsbakk, git On Wed, Sep 3, 2025, at 23:21, Eric Sunshine wrote: >> I've seen "troubleshooting" questions from git users >> who got one of those long and well-described Hints >> like e.g. detached head and default git init branch >> when either the msg already spelled eveything out >> or the msg was purely informational. > > I didn't spell it out above, but what I had in mind was something very > simple... not at all ong and detailed; for instance: > > For interactive use, define a Git alias `git whatchanged` > which runs `git log --raw --no-merges`. But that won’t work since git-whatchanged(1) is a builtin and you cannot use an alias to shadow a builtin. Now you can suggest minor variations like `whatchange`. But then people will go back to talking about their finger memory.[1][2][3] You would need Peff’s: https://lore.kernel.org/git/20250830022718.GB567900@coredump.intra.peff.net/ > I wonder if we should loosen the "aliases cannot override builtins" rule > for deprecated commands. Perhaps something like the patch below. † 1: If people are adamant about a command staying exactly as it is for interactive use, I don’t imagine their tolerance for a slightly different invocation will be much higher. † 2: And I wonder about the audience who has been using a command which was deprecated for twelve years who also need to be reminded about aliases. † 3: But there is one `whatchange` conversion: https://lore.kernel.org/git/CAAn3O_2iHVt5TctvwLLSXm5Nw2wS8e9Xk0is1=k=-qRS=gHVMQ@mail.gmail.com/ -- Kristoffer Haugsbakk ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 21:21 ` Eric Sunshine 2025-09-03 21:41 ` Kristoffer Haugsbakk @ 2025-09-03 21:44 ` Jeff King 2025-09-03 22:11 ` Eric Sunshine 1 sibling, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-03 21:44 UTC (permalink / raw) To: Eric Sunshine Cc: Kristoffer Haugsbakk, Junio C Hamano, Kristoffer Haugsbakk, git On Wed, Sep 03, 2025 at 05:21:47PM -0400, Eric Sunshine wrote: > > I've seen "troubleshooting" questions from git users > > who got one of those long and well-described Hints > > like e.g. detached head and default git init branch > > when either the msg already spelled eveything out > > or the msg was purely informational. > > I didn't spell it out above, but what I had in mind was something very > simple... not at all ong and detailed; for instance: > > For interactive use, define a Git alias `git whatchanged` > which runs `git log --raw --no-merges`. I think that is good advice, but... it won't do anything until we actually drop the whatchanged command, since until then we'll refuse to override the command (even the crippled --i-still-use-this one). We'd need something like the patch here: https://lore.kernel.org/git/20250830022718.GB567900@coredump.intra.peff.net/ -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 21:44 ` Jeff King @ 2025-09-03 22:11 ` Eric Sunshine 2025-09-04 6:57 ` Kristoffer Haugsbakk 2025-09-05 13:11 ` Jeff King 0 siblings, 2 replies; 102+ messages in thread From: Eric Sunshine @ 2025-09-03 22:11 UTC (permalink / raw) To: Jeff King; +Cc: Kristoffer Haugsbakk, Junio C Hamano, Kristoffer Haugsbakk, git On Wed, Sep 3, 2025 at 5:44 PM Jeff King <peff@peff.net> wrote: > On Wed, Sep 03, 2025 at 05:21:47PM -0400, Eric Sunshine wrote: > > > I've seen "troubleshooting" questions from git users > > > who got one of those long and well-described Hints > > > like e.g. detached head and default git init branch > > > when either the msg already spelled eveything out > > > or the msg was purely informational. > > > > I didn't spell it out above, but what I had in mind was something very > > simple... not at all ong and detailed; for instance: > > > > For interactive use, define a Git alias `git whatchanged` > > which runs `git log --raw --no-merges`. > > I think that is good advice, but... it won't do anything until we > actually drop the whatchanged command, since until then we'll refuse to > override the command (even the crippled --i-still-use-this one). > > We'd need something like the patch here: > > https://lore.kernel.org/git/20250830022718.GB567900@coredump.intra.peff.net/ Indeed. I saw your patch in the other thread and had it in mind when composing my earlier email, even though I didn't specifically mention it (though I probably should have) since I was more focused on raising the point that -- given the recent spate of muscle-memory / mnemonic-value argument emails -- the existing hints in Kristoffer's patch series may be insufficient to quell future emails. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 22:11 ` Eric Sunshine @ 2025-09-04 6:57 ` Kristoffer Haugsbakk 2025-09-05 13:11 ` Jeff King 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-04 6:57 UTC (permalink / raw) To: Eric Sunshine, Jeff King; +Cc: Junio C Hamano, git On Thu, Sep 4, 2025, at 00:11, Eric Sunshine wrote: > , even though I didn't specifically mention it (though I probably > should have) I thought Sunshine was supposed to illuminate. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 22:11 ` Eric Sunshine 2025-09-04 6:57 ` Kristoffer Haugsbakk @ 2025-09-05 13:11 ` Jeff King 1 sibling, 0 replies; 102+ messages in thread From: Jeff King @ 2025-09-05 13:11 UTC (permalink / raw) To: Eric Sunshine Cc: Kristoffer Haugsbakk, Junio C Hamano, Kristoffer Haugsbakk, git On Wed, Sep 03, 2025 at 06:11:30PM -0400, Eric Sunshine wrote: > > > I didn't spell it out above, but what I had in mind was something very > > > simple... not at all ong and detailed; for instance: > > > > > > For interactive use, define a Git alias `git whatchanged` > > > which runs `git log --raw --no-merges`. > > > > I think that is good advice, but... it won't do anything until we > > actually drop the whatchanged command, since until then we'll refuse to > > override the command (even the crippled --i-still-use-this one). > > > > We'd need something like the patch here: > > > > https://lore.kernel.org/git/20250830022718.GB567900@coredump.intra.peff.net/ > > Indeed. I saw your patch in the other thread and had it in mind when > composing my earlier email, even though I didn't specifically mention > it (though I probably should have) since I was more focused on raising > the point that -- given the recent spate of muscle-memory / > mnemonic-value argument emails -- the existing hints in Kristoffer's > patch series may be insufficient to quell future emails. Heh, I should have figured. I didn't see any response in that thread, so this was my attempt to pawn it off on folks who are more interested in the topic (and working on the advice half). ;) -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-09-03 16:50 ` Eric Sunshine 2025-09-03 17:53 ` Kristoffer Haugsbakk @ 2025-09-09 20:01 ` Kristoffer Haugsbakk 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-09 20:01 UTC (permalink / raw) To: Eric Sunshine, Junio C Hamano; +Cc: Kristoffer Haugsbakk, git On Wed, Sep 3, 2025, at 18:50, Eric Sunshine wrote: > I realize that the changes made by this series are not in any released > version yet, but from reading the emails still arriving which argue > for retaining the command for reasons of muscle memory or because of > its (strong) mnemonic value, I suspect that the hint(s) this series > adds may not be complete enough. In particular, the advice this series > adds (use `git log --raw --no-merges`) seems to be primarily aimed at > scripted use of the command. But the muscle memory and mnemonic > arguments suggest that advice should be given for interactive use, as > well,[—] > > such as proposing that the user can create an alias. Sorry, I completely missed the part (now a week ago) where you clearly were alluding to making a whatchanged-alias to begin with, which made my initial response here quite beside the point. I shouldn’t respond to this list on mobile. -- Kristoffer Haugsbakk ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 1/4] usage: help the user help themselves 2025-08-27 20:36 ` Kristoffer Haugsbakk 2025-08-27 21:02 ` Eric Sunshine @ 2025-08-27 21:14 ` Junio C Hamano 1 sibling, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 21:14 UTC (permalink / raw) To: Kristoffer Haugsbakk; +Cc: Kristoffer Haugsbakk, git "Kristoffer Haugsbakk" <code@khaugsbakk.name> writes: >> usage: help the user help themselves > > I think I’ll change the area to the more pointed: > > you-still-use-that??: Ah, that makes sense. > On Wed, Aug 27, 2025, at 18:29, kristofferhaugsbakk@fastmail.com wrote: >> @@ -377,12 +378,22 @@ void bug_fl(const char *file, int line, const char *fmt, ...) >> >> NORETURN void you_still_use_that(const char *command_name) >> { >> + struct strbuf percent_encoded = STRBUF_INIT; >> + strbuf_add_percentencode(&percent_encoded, >> + command_name, >> + STRBUF_ENCODE_SLASH); >> + >> fprintf(stderr, >> _("'%s' is nominated for removal.\n" >> - "If you still use this command, please add an extra\n" >> - "option, '--i-still-use-this', on the command line\n" >> - "and let us know you still use it by sending an e-mail\n" >> - "to <git@vger.kernel.org>. Thanks.\n"), >> - command_name); >> + "If you still use this command, here's what you can do:\n" >> + "\n" >> + "- read https://git-scm.com/docs/BreakingChanges.html\n" >> + "- check if anyone has discussed this on the mailing\n" >> + " list and if they came up with something that can\n" >> + " help you: https://lore.kernel.org/git/?q=%s\n" >> + "- send an email to <git@vger.kernel.org>\n" > > Maybe (thinking out loud) this should retain some part of the “let us > know you still use this” spirit: > > - send an email to <git@vger.kernel.org> and let us know > that you still use this command We do not actually want to bother individual users about reporting. We may want to catch third-party tools (like we heard a problem with Jenkins from its users), so - notify <git@vger.kernel.org> mailing list if you are a lead developer of a widely used tool, especially if you heard a breakage report on your tool from your users due to this message. perhaps? If we know that version A of tool X (or older) hasn't migrated, users of the same tool will see the same breakage, and some of them may come to this list. If we know about their problem ahead of time, we'd be better prepared to give them a definitive "Yes, we know version A of tool X (or older) still uses it, and the developer of tool X is aware of the problem." Hopefully ;-) ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 1/4] usage: help the user help themselves kristofferhaugsbakk @ 2025-08-27 16:29 ` kristofferhaugsbakk 2025-08-27 16:45 ` Junio C Hamano 2025-08-28 12:07 ` Kristoffer Haugsbakk 2025-08-27 16:29 ` [PATCH 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (3 subsequent siblings) 5 siblings, 2 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-27 16:29 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1). That template produces almost the same output[3] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2] The error message on 2.51.0 does tell them to report it, unconditionally [3]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 8 ++++++-- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..2f9e5e5a898 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -542,8 +542,12 @@ int cmd_whatchanged(int argc, opt.revarg_opt = REVARG_COMMITTISH; cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); - if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + if (!cfg.i_still_use_this) + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + " git log <opts> --raw --no-merges\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 29988395f19..c661561b149 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -393,7 +399,7 @@ NORETURN void you_still_use_that(const char *command_name) " help you: https://lore.kernel.org/git/?q=%s\n" "- send an email to <git@vger.kernel.org>\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.11.g23cedd8a747 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-27 16:29 ` [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk @ 2025-08-27 16:45 ` Junio C Hamano 2025-08-27 16:48 ` Junio C Hamano 2025-08-28 12:07 ` Kristoffer Haugsbakk 1 sibling, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 16:45 UTC (permalink / raw) To: kristofferhaugsbakk; +Cc: git, Kristoffer Haugsbakk kristofferhaugsbakk@fastmail.com writes: > - if (!cfg.i_still_use_this) > - you_still_use_that("git whatchanged"); > + if (!cfg.i_still_use_this) > + you_still_use_that("git whatchanged", I spot a whitespace breakage here. I didn't check if there are other instances. Please check your editor settings (or run "git diff --check --cached" before committing yoru changes, or both). Thanks. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-27 16:45 ` Junio C Hamano @ 2025-08-27 16:48 ` Junio C Hamano 2025-08-27 17:08 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 16:48 UTC (permalink / raw) To: kristofferhaugsbakk; +Cc: git, Kristoffer Haugsbakk Junio C Hamano <gitster@pobox.com> writes: > kristofferhaugsbakk@fastmail.com writes: > >> - if (!cfg.i_still_use_this) >> - you_still_use_that("git whatchanged"); >> + if (!cfg.i_still_use_this) >> + you_still_use_that("git whatchanged", > > I spot a whitespace breakage here. I didn't check if there are Sorry, I read the patch backwards. You are fixing an existing whitespace breakage, which is very much appreciated, as this is immediate vicinity of the real change of this topic. Thanks. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-27 16:48 ` Junio C Hamano @ 2025-08-27 17:08 ` Kristoffer Haugsbakk 0 siblings, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-08-27 17:08 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, Kristoffer Haugsbakk On Wed, Aug 27, 2025, at 18:48, Junio C Hamano wrote: > Junio C Hamano <gitster@pobox.com> writes: > >> kristofferhaugsbakk@fastmail.com writes: >> >>> - if (!cfg.i_still_use_this) >>> - you_still_use_that("git whatchanged"); >>> + if (!cfg.i_still_use_this) >>> + you_still_use_that("git whatchanged", >> >> I spot a whitespace breakage here. I didn't check if there are > > Sorry, I read the patch backwards. You are fixing an existing > whitespace breakage, which is very much appreciated, as this is > immediate vicinity of the real change of this topic. No, I did inadvertently replace the tab indents with spaces. I’ll have to configure my editor better. I’ll fix it. (`ci/check-whitespace.sh v2.51.0` turned out to be helpful for me here) -- Kristoffer Haugsbakk ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-27 16:29 ` [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk 2025-08-27 16:45 ` Junio C Hamano @ 2025-08-28 12:07 ` Kristoffer Haugsbakk 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-08-28 12:07 UTC (permalink / raw) To: Kristoffer Haugsbakk, git On Wed, Aug 27, 2025, at 18:29, kristofferhaugsbakk@fastmail.com wrote: > From: Kristoffer Haugsbakk <code@khaugsbakk.name> >[snip] > [1]: E.g., > • > https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ > • > https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t > • > https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t > • > https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ > [2] The error message on 2.51.0 does tell them to report it, unconditionally Missing colon. > [3]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ I’ll expand on this. [3]: You only get different outputs if you happen to have empty commits (no changes)[4] [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH 3/4] whatchanged: remove not-even-shorter clause 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 1/4] usage: help the user help themselves kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk @ 2025-08-27 16:29 ` kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk ` (2 subsequent siblings) 5 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-27 16:29 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.11.g23cedd8a747 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH 4/4] BreakingChanges: remove claim about whatchanged reports 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (2 preceding siblings ...) 2025-08-27 16:29 ` [PATCH 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-08-27 16:29 ` kristofferhaugsbakk 2025-08-27 16:43 ` [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk 5 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-27 16:29 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.11.g23cedd8a747 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (3 preceding siblings ...) 2025-08-27 16:29 ` [PATCH 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-08-27 16:43 ` Junio C Hamano 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk 5 siblings, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-08-27 16:43 UTC (permalink / raw) To: kristofferhaugsbakk; +Cc: git, Kristoffer Haugsbakk kristofferhaugsbakk@fastmail.com writes: > From: Kristoffer Haugsbakk <code@khaugsbakk.name> > > Based on the recent i-still-use-that reports about whatchanged, improve > the error reporting with this command in mind: > > 1. Give more possible actions instead of just (only) asking them to send > an email > 2. Hint how to replace their git-whatchanged(1) use with git-log(1) > 3. Minor documentation changes Nice. Especially the attention to minor details shown in [3/4] and [4/4] is very much appreciated. ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v2 0/4] you-still-use-that??: improve breaking changes troubleshooting 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (4 preceding siblings ...) 2025-08-27 16:43 ` [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano @ 2025-08-29 15:21 ` kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 1/4] you-still-use-that??: help the user help themselves kristofferhaugsbakk ` (4 more replies) 5 siblings, 5 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-29 15:21 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine From: Kristoffer Haugsbakk <code@khaugsbakk.name> Based on the recent i-still-use-that reports about whatchanged, improve the error reporting with this command in mind: 1. Give more possible actions instead of just (only) asking them to send an email 2. Hint how to replace their git-whatchanged(1) use with git-log(1) 3. Minor documentation changes Also:[1] an alternative to linking to www.git-scm.com (in patch 1/4) is to move this document to a regular installed man page: gitbreaking-changes(7) [1]: Not mentioned on the v1 cover letter § What the errors now look like $ ./git pack-redundant 'git pack-redundant' is nominated for removal. If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20pack-redundant - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this $ ./git whatchanged 'git whatchanged' is nominated for removal. hint: You can replace 'git whatchanged <opts>' with: git log <opts> --raw --no-merges If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20whatchanged - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this § Changes in v2 These are also posted on the patches. • Patch 1/4: • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm • Patch 2/4: • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Kristoffer Haugsbakk (4): you-still-use-that??: help the user help themselves whatchanged: tell users the git-log(1) equivalent whatchanged: remove not-even-shorter clause BreakingChanges: remove claim about whatchanged reports Documentation/BreakingChanges.adoc | 2 +- Documentation/git-whatchanged.adoc | 8 ++++++-- builtin/log.c | 6 +++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 33 +++++++++++++++++++++++------- 6 files changed, 40 insertions(+), 13 deletions(-) Interdiff against v1: diff --git a/builtin/log.c b/builtin/log.c index 2f9e5e5a898..5dbb90c014d 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -542,7 +542,7 @@ int cmd_whatchanged(int argc, opt.revarg_opt = REVARG_COMMITTISH; cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); - if (!cfg.i_still_use_this) + if (!cfg.i_still_use_this) you_still_use_that("git whatchanged", _("\n" "hint: You can replace 'git whatchanged <opts>' with:\n" diff --git a/usage.c b/usage.c index c661561b149..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -397,7 +397,9 @@ NORETURN void you_still_use_that(const char *command_name, const char *hint) "- check if anyone has discussed this on the mailing\n" " list and if they came up with something that can\n" " help you: https://lore.kernel.org/git/?q=%s\n" - "- send an email to <git@vger.kernel.org>\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" "\n"), percent_encoded.buf); strbuf_release(&percent_encoded); Range-diff against v1: 1: e81023edb2d ! 1: 6803e2cc6c3 usage: help the user help themselves @@ Metadata Author: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Commit message ## - usage: help the user help themselves + you-still-use-that??: help the user help themselves Give the user a list of suggestions for what to do when they run a deprecated command. @@ Commit message Also drop “Thanks” since it now would require a new paragraph. - [1]: git-scm has a disclaimer for these internal documents that says - that “This information is specific to the Git project”. That’s + [1]: www.git-scm.com has a disclaimer for these internal documents that + says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get - discouraged from reading about why they (or their programs) cannot - run a command any more; it clearly concerns them. + discouraged from reading about why they (or their programs) cannot run a + command any more; it clearly concerns them. + Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## - An alternative to linking to git-scm is to move this document to a - regular installed man page: + v2: + + I had second thoughts about the bullet point about send-an-email. + Change it to the one Eric Sunshine proposed;[1] make sure to spell + out that you can send an email conditioned on not finding a suitable + replacement. + + Also change the area to something more pointed. + + And also use a clear URL to refer to www.git-scm.com. + + [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ + + • Change send-an-email bullet point + • Change the area + • Use www.git-scm.com, not simply git-scm + + v1: + + An alternative to linking to www.git-scm.com is to move this document to + a regular installed man page: gitbreaking-changes(7) @@ usage.c: void bug_fl(const char *file, int line, const char *fmt, ...) + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" -+ "- send an email to <git@vger.kernel.org>\n" ++ "- send an email to <git@vger.kernel.org> to let us\n" ++ " know that you still use this command and were unable\n" ++ " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); 2: 5407c0955af ! 2: 2f3ac952980 whatchanged: tell users the git-log(1) equivalent @@ Commit message • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ - [2] The error message on 2.51.0 does tell them to report it, unconditionally - [3]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ + [2]: The error message on 2.51.0 does tell them to report it, unconditionally + [3]: You only get different outputs if you happen to have empty + commits (no changes)[4] + [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> + + ## Notes (series) ## + v2: + + Review found a whitespace error in the prev. patch version. I found a + broken footnote and wanted to expand on the last footnote. + + • Fix whitespace error (I should have used `ci/check-whitespace.sh + v2.51.0`) + • Add missing colon (:) to footnote + • Expand on footnote; a sentence is enough to summarize the difference + ## Documentation/git-whatchanged.adoc ## @@ Documentation/git-whatchanged.adoc: Shows commit logs and diff output each commit introduces. @@ Documentation/git-whatchanged.adoc: Shows commit logs and diff output each commi ## builtin/log.c ## @@ builtin/log.c: int cmd_whatchanged(int argc, - opt.revarg_opt = REVARG_COMMITTISH; cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); -- if (!cfg.i_still_use_this) + if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); -+ if (!cfg.i_still_use_this) + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" @@ usage.c: NORETURN void you_still_use_that(const char *command_name) "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ usage.c: NORETURN void you_still_use_that(const char *command_name) - " help you: https://lore.kernel.org/git/?q=%s\n" - "- send an email to <git@vger.kernel.org>\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); 3: 5fad164d7d1 = 3: a074e7be422 whatchanged: remove not-even-shorter clause 4: f1bf0ea3846 = 4: 9196c3c7e33 BreakingChanges: remove claim about whatchanged reports base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0 -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v2 1/4] you-still-use-that??: help the user help themselves 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk @ 2025-08-29 15:21 ` kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk ` (3 subsequent siblings) 4 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-29 15:21 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: www.git-scm.com has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: I had second thoughts about the bullet point about send-an-email. Change it to the one Eric Sunshine proposed;[1] make sure to spell out that you can send an email conditioned on not finding a suitable replacement. Also change the area to something more pointed. And also use a clear URL to refer to www.git-scm.com. [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm v1: An alternative to linking to www.git-scm.com is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..35dc57eb07e 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,24 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v2 2/4] whatchanged: tell users the git-log(1) equivalent 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 1/4] you-still-use-that??: help the user help themselves kristofferhaugsbakk @ 2025-08-29 15:21 ` kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (2 subsequent siblings) 4 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-29 15:21 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1). That template produces almost the same output[3] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally [3]: You only get different outputs if you happen to have empty commits (no changes)[4] [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: Review found a whitespace error in the prev. patch version. I found a broken footnote and wanted to expand on the last footnote. • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 6 +++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..5dbb90c014d 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -543,7 +543,11 @@ int cmd_whatchanged(int argc, cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + " git log <opts> --raw --no-merges\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 35dc57eb07e..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -395,7 +401,7 @@ NORETURN void you_still_use_that(const char *command_name) " know that you still use this command and were unable\n" " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v2 3/4] whatchanged: remove not-even-shorter clause 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 1/4] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk @ 2025-08-29 15:21 ` kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 4 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-29 15:21 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v2 4/4] BreakingChanges: remove claim about whatchanged reports 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk ` (2 preceding siblings ...) 2025-08-29 15:21 ` [PATCH v2 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-08-29 15:21 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 4 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-08-29 15:21 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk ` (3 preceding siblings ...) 2025-08-29 15:21 ` [PATCH v2 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk ` (8 more replies) 4 siblings, 9 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> Based on the recent i-still-use-that reports about whatchanged, improve the error reporting with this command in mind: 1. Give more possible actions instead of just (only) asking them to send an email 2. Hint how to replace their git-whatchanged(1) use with git-log(1) or an alias `whatchanged` (you can alias deprecated commands now) 3. Minor documentation changes 4. Add `deprecated` to `git --list-cmds` § What the errors now look like $ /git whatchanged 'git whatchanged' is nominated for removal. hint: You can replace 'git whatchanged <opts>' with: hint: git log <opts> --raw --no-merges hint: Or make an alias: hint: git config set --global alias.whatchanged 'log --raw --no-merges' If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20whatchanged - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this $ git pack-redundant 'git pack-redundant' is nominated for removal. If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20pack-redundant - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this § Changes in v3 Patches 1–4 are new: • Make aliases which shadow deprecated builtins possible (based on Peff’s patch) • This was based on Eric’s prompt[1] • Add `deprecated` category to `git --list-cmds` Then the patch “whatchanged: tell users the git-log(1) equivalent” is changed to add the now-possible aliasing. 🔗 1: https://lore.kernel.org/git/CAPig+cSL=-gD5+WomF7-hYjVJ_PH0m+0i8g3F=E_U3k=QNHr8Q@mail.gmail.com/ Kristoffer Haugsbakk (8): git: add `deprecated` category to --list-cmds git: make the two loops look more symmetric git: allow alias-shadowing deprecated builtins t0014: test shadowing of aliases for a sample of builtins you-still-use-that??: help the user help themselves whatchanged: tell users the git-log(1) equivalent whatchanged: remove not-even-shorter clause BreakingChanges: remove claim about whatchanged reports Documentation/BreakingChanges.adoc | 2 +- Documentation/config/alias.adoc | 3 +- Documentation/git-whatchanged.adoc | 8 +++-- Documentation/git.adoc | 3 +- builtin/log.c | 8 ++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- git.c | 55 ++++++++++++++++++++++++------ t/t0014-alias.sh | 34 ++++++++++++++++++ usage.c | 33 ++++++++++++++---- 10 files changed, 124 insertions(+), 26 deletions(-) Interdiff against v2: diff --git a/Documentation/config/alias.adoc b/Documentation/config/alias.adoc index 2c5db0ad842..3c8fab3a95c 100644 --- a/Documentation/config/alias.adoc +++ b/Documentation/config/alias.adoc @@ -3,7 +3,8 @@ alias.*:: after defining `alias.last = cat-file commit HEAD`, the invocation `git last` is equivalent to `git cat-file commit HEAD`. To avoid confusion and troubles with script usage, aliases that - hide existing Git commands are ignored. Arguments are split by + hide existing Git commands are ignored except for deprecated + commands. Arguments are split by spaces, the usual shell quoting and escaping are supported. A quote pair or a backslash can be used to quote them. + diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4d..a2f0838b168 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -219,7 +219,8 @@ If you just want to run git as if it was started in `<path>` then use List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options), main (all commands in libexec directory), + parse-options), deprecated (deprecated builtins), + main (all commands in libexec directory), others (all other commands in `$PATH` that have git- prefix), list-<category> (see categories in command-list.txt), nohelpers (exclude helper commands), alias and config diff --git a/builtin/log.c b/builtin/log.c index 5dbb90c014d..1d1e6e9130a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -546,7 +546,9 @@ int cmd_whatchanged(int argc, you_still_use_that("git whatchanged", _("\n" "hint: You can replace 'git whatchanged <opts>' with:\n" - " git log <opts> --raw --no-merges\n" + "hint:\tgit log <opts> --raw --no-merges\n" + "hint: Or make an alias:\n" + "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" "\n")); if (!rev.diffopt.output_format) diff --git a/git.c b/git.c index 83eac0aeab7..a452ce3f9e9 100644 --- a/git.c +++ b/git.c @@ -28,6 +28,7 @@ #define NEED_WORK_TREE (1<<3) #define DELAY_PAGER_CONFIG (1<<4) #define NO_PARSEOPT (1<<5) /* parse-options is not used */ +#define DEPRECATED (1<<6) struct cmd_struct { const char *cmd; @@ -51,7 +52,13 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +/* + * 'include_option' and 'exclude_option' are mutually exclusive. + * + * The default ('!include_option') is to include everything + * except those filtered out by 'exclude_option'. + */ +static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -88,7 +95,7 @@ static int list_cmds(const char *spec) int len = sep - spec; if (match_token(spec, len, "builtins")) - list_builtins(&list, 0); + list_builtins(&list, 0, 0); else if (match_token(spec, len, "main")) list_all_main_cmds(&list); else if (match_token(spec, len, "others")) @@ -99,6 +106,8 @@ static int list_cmds(const char *spec) list_aliases(&list); else if (match_token(spec, len, "config")) list_cmds_by_config(&list); + else if (match_token(spec, len, "deprecated")) + list_builtins(&list, DEPRECATED, 0); else if (len > 5 && !strncmp(spec, "list-", 5)) { struct strbuf sb = STRBUF_INIT; @@ -322,7 +331,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - list_builtins(&list, NO_PARSEOPT); + list_builtins(&list, 0, NO_PARSEOPT); for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); @@ -590,7 +599,7 @@ static struct cmd_struct commands[] = { { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, #ifndef WITH_BREAKING_CHANGES - { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED }, #endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -647,7 +656,7 @@ static struct cmd_struct commands[] = { { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, #ifndef WITH_BREAKING_CHANGES - { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED }, #endif { "worktree", cmd_worktree, RUN_SETUP }, { "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,13 +677,18 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) { - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) - continue; - string_list_append(out, commands[i].cmd); + if (include_option && exclude_option) + BUG("'include_option' and 'exclude_option' are mutually exclusive"); + if (include_option) { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) + if (commands[i].option & include_option) + string_list_append(out, commands[i].cmd); + } else { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) + if (!(commands[i].option & exclude_option)) + string_list_append(out, commands[i].cmd); } } @@ -793,6 +807,12 @@ static void execv_dashed_external(const char **argv) exit(128); } +static int is_deprecated_command(const char *cmd) +{ + return !strcmp(cmd, "whatchanged") || + !strcmp(cmd, "pack-redundant"); +} + static int run_argv(struct strvec *args) { int done_alias = 0; @@ -800,6 +820,19 @@ static int run_argv(struct strvec *args) struct string_list_item *seen; while (1) { + /* + * Allow deprecated commands to be overridden by aliases. This + * creates a seamless path forward for people who want to keep + * using the name after it is gone, but want to skip the + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && + alias_lookup(args->v[0])) { + if (!handle_alias(args)) + break; + done_alias = 1; + continue; + } /* * If we tried alias and futzed with our environment, * it no longer is safe to invoke builtins directly in diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 854d59ec58c..bf7e6512bb1 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -55,4 +55,38 @@ test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' +can_alias_deprecated_builtin () { + cmd="$1" && + # some git(1) commands will fail for `-h` (the case for + # git-status as of 2025-09-07) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'can alias-shadow deprecated builtins' ' + for cmd in $(git --list-cmds=deprecated) + do + can_alias_deprecated_builtin "$cmd" || return 1 + done +' + +cannot_alias_regular_builtin () { + cmd="$1" && + # some git(1) commands will fail... (see above) + test_might_fail git "$cmd" -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'cannot alias-shadow a sample of regular builtins' ' + for cmd in grep check-ref-format interpret-trailers \ + checkout-index fast-import diagnose rev-list prune + do + cannot_alias_regular_builtin "$cmd" || return 1 + done +' + test_done Range-diff against v2: -: ----------- > 1: bdc683a92b3 git: add `deprecated` category to --list-cmds -: ----------- > 2: 183dd68d09d git: make the two loops look more symmetric -: ----------- > 3: eec01cbac16 git: allow alias-shadowing deprecated builtins -: ----------- > 4: 80fb02caeeb t0014: test shadowing of aliases for a sample of builtins 1: 6803e2cc6c3 = 5: d25ee26f989 you-still-use-that??: help the user help themselves 2: 2f3ac952980 ! 6: 50621a0748f whatchanged: tell users the git-log(1) equivalent @@ Commit message ## Notes (series) ## + v3: + + Add an alias hint now that that is possible. Also prefix each hint-line + with `hint: `. + v2: Review found a whitespace error in the prev. patch version. I found a @@ builtin/log.c: int cmd_whatchanged(int argc, + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" -+ " git log <opts> --raw --no-merges\n" ++ "hint:\tgit log <opts> --raw --no-merges\n" ++ "hint: Or make an alias:\n" ++ "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" + "\n")); if (!rev.diffopt.output_format) 3: a074e7be422 = 7: 812c9870f1b whatchanged: remove not-even-shorter clause 4: 9196c3c7e33 = 8: 0d23a4badf0 BreakingChanges: remove claim about whatchanged reports base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0 -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 1/8] git: add `deprecated` category to --list-cmds 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-09 6:43 ` Patrick Steinhardt 2025-09-08 15:36 ` [PATCH v3 2/8] git: make the two loops look more symmetric kristofferhaugsbakk ` (7 subsequent siblings) 8 siblings, 1 reply; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> With 145 builtin commands (according to `git --list-cmds=builtins`), users are probably not keeping on top of which ones (if any) are deprecated. Let’s expand the experimental `--list-cmds`[1] to allow users and programs to query for this information. We will also use this in an upcoming commit to assert that all deprecated commands will have been covered in some manner. [1]: Using something which is experimental to query for deprecations is perhaps not the most ideal approach, but it is simple to implement and better than having to scan the documentation Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): This is something I wanted to submit independently until the point about aliasing builtins was brought up.[1] It will help (in a small way) with the upcoming patch “git: allow alias-shadowing deprecated builtins”. By the way: should `command-list.txt` be updated in some way (I didn’t know what way?) 🔗 1: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#mee19f8d39572f9021f9d3000758e87b6c32c967c Documentation/git.adoc | 3 ++- git.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4d..a2f0838b168 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -219,7 +219,8 @@ If you just want to run git as if it was started in `<path>` then use List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options), main (all commands in libexec directory), + parse-options), deprecated (deprecated builtins), + main (all commands in libexec directory), others (all other commands in `$PATH` that have git- prefix), list-<category> (see categories in command-list.txt), nohelpers (exclude helper commands), alias and config diff --git a/git.c b/git.c index 83eac0aeab7..87d61f12594 100644 --- a/git.c +++ b/git.c @@ -28,6 +28,7 @@ #define NEED_WORK_TREE (1<<3) #define DELAY_PAGER_CONFIG (1<<4) #define NO_PARSEOPT (1<<5) /* parse-options is not used */ +#define DEPRECATED (1<<6) struct cmd_struct { const char *cmd; @@ -51,7 +52,13 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +/* + * 'include_option' and 'exclude_option' are mutually exclusive. + * + * The default ('!include_option') is to include everything + * except those filtered out by 'exclude_option'. + */ +static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -88,7 +95,7 @@ static int list_cmds(const char *spec) int len = sep - spec; if (match_token(spec, len, "builtins")) - list_builtins(&list, 0); + list_builtins(&list, 0, 0); else if (match_token(spec, len, "main")) list_all_main_cmds(&list); else if (match_token(spec, len, "others")) @@ -99,6 +106,8 @@ static int list_cmds(const char *spec) list_aliases(&list); else if (match_token(spec, len, "config")) list_cmds_by_config(&list); + else if (match_token(spec, len, "deprecated")) + list_builtins(&list, DEPRECATED, 0); else if (len > 5 && !strncmp(spec, "list-", 5)) { struct strbuf sb = STRBUF_INIT; @@ -322,7 +331,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - list_builtins(&list, NO_PARSEOPT); + list_builtins(&list, 0, NO_PARSEOPT); for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); @@ -590,7 +599,7 @@ static struct cmd_struct commands[] = { { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, #ifndef WITH_BREAKING_CHANGES - { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED }, #endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -647,7 +656,7 @@ static struct cmd_struct commands[] = { { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, #ifndef WITH_BREAKING_CHANGES - { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED }, #endif { "worktree", cmd_worktree, RUN_SETUP }, { "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,13 +677,20 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) { - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) - continue; - string_list_append(out, commands[i].cmd); + if (include_option && exclude_option) + BUG("'include_option' and 'exclude_option' are mutually exclusive"); + if (include_option) { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) + if (commands[i].option & include_option) + string_list_append(out, commands[i].cmd); + } else { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { + if (commands[i].option & exclude_option) + continue; + string_list_append(out, commands[i].cmd); + } } } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v3 1/8] git: add `deprecated` category to --list-cmds 2025-09-08 15:36 ` [PATCH v3 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-09 6:43 ` Patrick Steinhardt 2025-09-09 8:02 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Patrick Steinhardt @ 2025-09-09 6:43 UTC (permalink / raw) To: kristofferhaugsbakk; +Cc: git, Kristoffer Haugsbakk, Eric Sunshine, peff On Mon, Sep 08, 2025 at 05:36:12PM +0200, kristofferhaugsbakk@fastmail.com wrote: > Notes (series): > v3 (new): > > This is something I wanted to submit independently until the point about > aliasing builtins was brought up.[1] It will help (in a small way) with > the upcoming patch “git: allow alias-shadowing deprecated builtins”. > > By the way: should `command-list.txt` be updated in some way (I didn’t > know what way?) I think it would be a good idea to introduce a new category for deprecated commands. After all, next to planning for the removal we should also actively discourage the use of such commands. But if they are still prominently featured in git(1) then people might be misled and use them, only to get a deprecation warning thrown at them. > diff --git a/git.c b/git.c > index 83eac0aeab7..87d61f12594 100644 > --- a/git.c > +++ b/git.c > @@ -51,7 +52,13 @@ const char git_more_info_string[] = > > static int use_pager = -1; > > -static void list_builtins(struct string_list *list, unsigned int exclude_option); > +/* > + * 'include_option' and 'exclude_option' are mutually exclusive. > + * > + * The default ('!include_option') is to include everything > + * except those filtered out by 'exclude_option'. > + */ > +static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); Nit: let's wrap this overly long line. > @@ -668,13 +677,20 @@ int is_builtin(const char *s) > return !!get_builtin(s); > } > > -static void list_builtins(struct string_list *out, unsigned int exclude_option) > +static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) Same here. > { > - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { > - if (exclude_option && > - (commands[i].option & exclude_option)) > - continue; > - string_list_append(out, commands[i].cmd); > + if (include_option && exclude_option) > + BUG("'include_option' and 'exclude_option' are mutually exclusive"); > + if (include_option) { > + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) > + if (commands[i].option & include_option) > + string_list_append(out, commands[i].cmd); > + } else { > + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { > + if (commands[i].option & exclude_option) > + continue; > + string_list_append(out, commands[i].cmd); > + } > } > } We could combine these two loops into one: for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { if (include_option && !(commands[i].option & include_option)) continue; if (exclude_option && (commands[i].option & exclude_option)) continue; string_list_append(out, commands[i].cmd); } Which results in a bit less code duplication. patrick ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v3 1/8] git: add `deprecated` category to --list-cmds 2025-09-09 6:43 ` Patrick Steinhardt @ 2025-09-09 8:02 ` Kristoffer Haugsbakk 0 siblings, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-09 8:02 UTC (permalink / raw) To: Patrick Steinhardt, Kristoffer Haugsbakk; +Cc: git, Eric Sunshine, Jeff King On Tue, Sep 9, 2025, at 08:43, Patrick Steinhardt wrote: > On Mon, Sep 08, 2025 at 05:36:12PM +0200, > kristofferhaugsbakk@fastmail.com wrote: >> Notes (series): >> v3 (new): >> >> This is something I wanted to submit independently until the point about >> aliasing builtins was brought up.[1] It will help (in a small way) with >> the upcoming patch “git: allow alias-shadowing deprecated builtins”. >> >> By the way: should `command-list.txt` be updated in some way (I didn’t >> know what way?) > > I think it would be a good idea to introduce a new category for > deprecated commands. After all, next to planning for the removal we > should also actively discourage the use of such commands. But if they > are still prominently featured in git(1) then people might be misled and > use them, only to get a deprecation warning thrown at them. Thanks. I’ll add your Ack if that’s okay. >>[snip] >> +static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); > > Nit: let's wrap this overly long line. I’ll do both of these, thanks. In the same commit/patch I think. >[snip] > Same here. >[snip] >> { >> - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { >> - if (exclude_option && >> - (commands[i].option & exclude_option)) >> - continue; >> - string_list_append(out, commands[i].cmd); >> + if (include_option && exclude_option) >> + BUG("'include_option' and 'exclude_option' are mutually exclusive"); >> + if (include_option) { >> + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) >> + if (commands[i].option & include_option) >> + string_list_append(out, commands[i].cmd); >> + } else { >> + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { >> + if (commands[i].option & exclude_option) >> + continue; >> + string_list_append(out, commands[i].cmd); >> + } >> } >> } > > We could combine these two loops into one: > > for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { > if (include_option && !(commands[i].option & include_option)) > continue; > if (exclude_option && (commands[i].option & exclude_option)) > continue; > string_list_append(out, commands[i].cmd); > } > > Which results in a bit less code duplication. That’s more elegant. I’ll use that. And I’ll remove the function doc now that it won’t be relevant. Cheers -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v3 2/8] git: make the two loops look more symmetric 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk ` (6 subsequent siblings) 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> Rewrite the original conditional here to match the new sibling loop in structure. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): This is just a refactor commit to avoid having to add a “while at it” for such small tweaks for the new context. git.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/git.c b/git.c index 87d61f12594..39dc9f8ec0f 100644 --- a/git.c +++ b/git.c @@ -686,11 +686,9 @@ static void list_builtins(struct string_list *out, unsigned int include_option, if (commands[i].option & include_option) string_list_append(out, commands[i].cmd); } else { - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (commands[i].option & exclude_option) - continue; - string_list_append(out, commands[i].cmd); - } + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) + if (!(commands[i].option & exclude_option)) + string_list_append(out, commands[i].cmd); } } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 2/8] git: make the two loops look more symmetric kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 20:47 ` Junio C Hamano 2025-09-08 15:36 ` [PATCH v3 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk ` (5 subsequent siblings) 8 siblings, 1 reply; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> git-whatchanged(1) is deprecated and you need to pass `--i-still-use-this` in order to force it to work as before. There are two affected users, or usages: 1. people who use the command in scripts; and 2. people who are used to using it interactively. For (1) the replacement is straightforward.[1] But people in (2) might like the name or be really used to typing it.[3] An obvious first thought is to suggest aliasing `whatchanged` to the git-log(1) equivalent.[1] But this doesn’t work and is awkward since you cannot shadow builtins via aliases. Now you are left in an uncomfortable limbo; your alias won’t work until the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be shadowed by aliases. The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all deprecated commands the same. [1]: git log --raw --no-merges With a minor caveat: you get different outputs if you happen to have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): Prerequisite for telling the user that they can alias `whatchanged` to `git log --raw --no-merged`. Link: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#md434b0968f499263262fb1805d82b788b8349d9a > I think that is good advice, but... it won't do anything until we > actually drop the whatchanged command, since until then we'll refuse to > override the command (even the crippled --i-still-use-this one). > > We'd need something like the patch here: ❦ The test_file_not_empty expect is here because the git(1) command could fail. Make sure that it did indeed output anyhing on stdout. (Or if a previous redirect to `expect` outputted something it should be completely different to `actual` in any case) I don’t know if this is just a waste. Documentation/config/alias.adoc | 3 ++- git.c | 19 +++++++++++++++++++ t/t0014-alias.sh | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Documentation/config/alias.adoc b/Documentation/config/alias.adoc index 2c5db0ad842..3c8fab3a95c 100644 --- a/Documentation/config/alias.adoc +++ b/Documentation/config/alias.adoc @@ -3,7 +3,8 @@ alias.*:: after defining `alias.last = cat-file commit HEAD`, the invocation `git last` is equivalent to `git cat-file commit HEAD`. To avoid confusion and troubles with script usage, aliases that - hide existing Git commands are ignored. Arguments are split by + hide existing Git commands are ignored except for deprecated + commands. Arguments are split by spaces, the usual shell quoting and escaping are supported. A quote pair or a backslash can be used to quote them. + diff --git a/git.c b/git.c index 39dc9f8ec0f..a452ce3f9e9 100644 --- a/git.c +++ b/git.c @@ -807,6 +807,12 @@ static void execv_dashed_external(const char **argv) exit(128); } +static int is_deprecated_command(const char *cmd) +{ + return !strcmp(cmd, "whatchanged") || + !strcmp(cmd, "pack-redundant"); +} + static int run_argv(struct strvec *args) { int done_alias = 0; @@ -814,6 +820,19 @@ static int run_argv(struct strvec *args) struct string_list_item *seen; while (1) { + /* + * Allow deprecated commands to be overridden by aliases. This + * creates a seamless path forward for people who want to keep + * using the name after it is gone, but want to skip the + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && + alias_lookup(args->v[0])) { + if (!handle_alias(args)) + break; + done_alias = 1; + continue; + } /* * If we tried alias and futzed with our environment, * it no longer is safe to invoke builtins directly in diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 854d59ec58c..89bedb9f73b 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -55,4 +55,21 @@ test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' +can_alias_deprecated_builtin () { + cmd="$1" && + # some git(1) commands will fail for `-h` (the case for + # git-status as of 2025-09-07) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'can alias-shadow deprecated builtins' ' + for cmd in $(git --list-cmds=deprecated) + do + can_alias_deprecated_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins 2025-09-08 15:36 ` [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-08 20:47 ` Junio C Hamano 2025-09-08 21:11 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-09-08 20:47 UTC (permalink / raw) To: kristofferhaugsbakk; +Cc: git, Kristoffer Haugsbakk, Eric Sunshine, peff kristofferhaugsbakk@fastmail.com writes: > +static int is_deprecated_command(const char *cmd) > +{ > + return !strcmp(cmd, "whatchanged") || > + !strcmp(cmd, "pack-redundant"); > +} This is somewhat a shame as you introduced the DEPRECATED bit to annotate entries in "struct cmd_struct commands[]" array. Shouldn't this be moved to git.c and taught to consult that array instead? ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins 2025-09-08 20:47 ` Junio C Hamano @ 2025-09-08 21:11 ` Jeff King 2025-09-08 21:55 ` Junio C Hamano 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-08 21:11 UTC (permalink / raw) To: Junio C Hamano Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, Eric Sunshine On Mon, Sep 08, 2025 at 01:47:57PM -0700, Junio C Hamano wrote: > kristofferhaugsbakk@fastmail.com writes: > > > +static int is_deprecated_command(const char *cmd) > > +{ > > + return !strcmp(cmd, "whatchanged") || > > + !strcmp(cmd, "pack-redundant"); > > +} > > This is somewhat a shame as you introduced the DEPRECATED bit to > annotate entries in "struct cmd_struct commands[]" array. Shouldn't > this be moved to git.c and taught to consult that array instead? Hmm, I did not see the original patch, as it does not seem to have hit the list (or maybe vger is just slow today). But yeah, if we have a bit in the cmd_struct array, that might be a nicer spot to match. It may or may not be trivial. When I posted my "something like this" patch I first tried to do it that way, but there are a lot of ordering constraints and the parts where we resolved the cmd_struct were not the right spots. OTOH, it would probably not be that hard to just do: static int is_deprecated_command(const char *cmd) { struct cmd_struct *builtin = get_builtin(cmd); return builtin && (builtin->flags & DEPRECATED); } In theory we could also have a deprecated non-builtin (i.e., implemented as an external program). And then we really would have to match by name. But I kind of doubt that will happen in practice (and it would still be possible to add a string match later if it did). -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins 2025-09-08 21:11 ` Jeff King @ 2025-09-08 21:55 ` Junio C Hamano 2025-09-09 6:25 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-09-08 21:55 UTC (permalink / raw) To: Jeff King; +Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, Eric Sunshine Jeff King <peff@peff.net> writes: > cmd_struct were not the right spots. OTOH, it would probably not be that > hard to just do: > > static int is_deprecated_command(const char *cmd) > { > struct cmd_struct *builtin = get_builtin(cmd); > return builtin && (builtin->flags & DEPRECATED); > > } That was exactly what I had in mind. Thanks. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins 2025-09-08 21:55 ` Junio C Hamano @ 2025-09-09 6:25 ` Kristoffer Haugsbakk 0 siblings, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-09 6:25 UTC (permalink / raw) To: Junio C Hamano, Jeff King; +Cc: git, Kristoffer Haugsbakk, Eric Sunshine On Mon, Sep 8, 2025, at 23:55, Junio C Hamano wrote: > Jeff King <peff@peff.net> writes: > >> cmd_struct were not the right spots. OTOH, it would probably not be that >> hard to just do: >> >> static int is_deprecated_command(const char *cmd) >> { >> struct cmd_struct *builtin = get_builtin(cmd); >> return builtin && (builtin->flags & DEPRECATED); >> >> } > > That was exactly what I had in mind. Thanks to both. I’ll use that suggestion. -- Kristoffer Haugsbakk ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v3 4/8] t0014: test shadowing of aliases for a sample of builtins 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (2 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk ` (4 subsequent siblings) 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> The previous commit added a test for shadowing deprecated builtins. Let’s make the test suite more complete by exercising a sample of the builtins and in turn test the documentation for git-config(1): To avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored except for deprecated commands. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): Only a sample of builtins since the test file takes about 600ms longer if I test all of them. t/t0014-alias.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 89bedb9f73b..bf7e6512bb1 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -72,4 +72,21 @@ test_expect_success 'can alias-shadow deprecated builtins' ' done ' +cannot_alias_regular_builtin () { + cmd="$1" && + # some git(1) commands will fail... (see above) + test_might_fail git "$cmd" -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'cannot alias-shadow a sample of regular builtins' ' + for cmd in grep check-ref-format interpret-trailers \ + checkout-index fast-import diagnose rev-list prune + do + cannot_alias_regular_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 5/8] you-still-use-that??: help the user help themselves 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (3 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 6/8] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk ` (3 subsequent siblings) 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: www.git-scm.com has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: I had second thoughts about the bullet point about send-an-email. Change it to the one Eric Sunshine proposed;[1] make sure to spell out that you can send an email conditioned on not finding a suitable replacement. Also change the area to something more pointed. And also use a clear URL to refer to www.git-scm.com. [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm v1: An alternative to linking to www.git-scm.com is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..35dc57eb07e 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,24 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 6/8] whatchanged: tell users the git-log(1) equivalent 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (4 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (2 subsequent siblings) 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1). That template produces almost the same output[3] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally [3]: You only get different outputs if you happen to have empty commits (no changes)[4] [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3: Add an alias hint now that that is possible. Also prefix each hint-line with `hint: `. v2: Review found a whitespace error in the prev. patch version. I found a broken footnote and wanted to expand on the last footnote. • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 8 +++++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..1d1e6e9130a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -543,7 +543,13 @@ int cmd_whatchanged(int argc, cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + "hint:\tgit log <opts> --raw --no-merges\n" + "hint: Or make an alias:\n" + "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 35dc57eb07e..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -395,7 +401,7 @@ NORETURN void you_still_use_that(const char *command_name) " know that you still use this command and were unable\n" " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 7/8] whatchanged: remove not-even-shorter clause 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (5 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 6/8] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v3 8/8] BreakingChanges: remove claim about whatchanged reports 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (6 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-09-08 15:36 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 8 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-08 15:36 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (7 preceding siblings ...) 2025-09-08 15:36 ` [PATCH v3 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 1/7] git: add `deprecated` category to --list-cmds kristofferhaugsbakk ` (7 more replies) 8 siblings, 8 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Based on the recent i-still-use-that reports about whatchanged, improve the error reporting with this command in mind: 1. Give more possible actions instead of just (only) asking them to send an email 2. Hint how to replace their git-whatchanged(1) use with git-log(1) or an alias `whatchanged` (you can alias deprecated commands now) 3. Minor documentation changes 4. Add `deprecated` to `git --list-cmds` § What the errors now look like $ /git whatchanged 'git whatchanged' is nominated for removal. hint: You can replace 'git whatchanged <opts>' with: hint: git log <opts> --raw --no-merges hint: Or make an alias: hint: git config set --global alias.whatchanged 'log --raw --no-merges' If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20whatchanged - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this $ git pack-redundant 'git pack-redundant' is nominated for removal. If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20pack-redundant - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this § Changes in v4 • Patch 1: updated with suggestion from Patrick • Patch 2: better `is_deprecated_command` implementation suggested by Junio and Peff • Minor adjustments based on the previous Kristoffer Haugsbakk (7): git: add `deprecated` category to --list-cmds git: allow alias-shadowing deprecated builtins t0014: test shadowing of aliases for a sample of builtins you-still-use-that??: help the user help themselves whatchanged: tell users the git-log(1) equivalent whatchanged: remove not-even-shorter clause BreakingChanges: remove claim about whatchanged reports Documentation/BreakingChanges.adoc | 2 +- Documentation/config/alias.adoc | 3 ++- Documentation/git-whatchanged.adoc | 8 ++++-- Documentation/git.adoc | 3 ++- builtin/log.c | 8 +++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- git.c | 43 ++++++++++++++++++++++++------ t/t0014-alias.sh | 34 +++++++++++++++++++++++ usage.c | 33 ++++++++++++++++++----- 10 files changed, 115 insertions(+), 23 deletions(-) Interdiff against v3: diff --git a/git.c b/git.c index a452ce3f9e9..b3aafebfe4c 100644 --- a/git.c +++ b/git.c @@ -52,13 +52,9 @@ const char git_more_info_string[] = static int use_pager = -1; -/* - * 'include_option' and 'exclude_option' are mutually exclusive. - * - * The default ('!include_option') is to include everything - * except those filtered out by 'exclude_option'. - */ -static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); +static void list_builtins(struct string_list *list, + unsigned int include_option, + unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -677,18 +673,16 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) +static void list_builtins(struct string_list *out, + unsigned int include_option, + unsigned int exclude_option) { - if (include_option && exclude_option) - BUG("'include_option' and 'exclude_option' are mutually exclusive"); - if (include_option) { - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) - if (commands[i].option & include_option) - string_list_append(out, commands[i].cmd); - } else { - for (size_t i = 0; i < ARRAY_SIZE(commands); i++) - if (!(commands[i].option & exclude_option)) - string_list_append(out, commands[i].cmd); + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { + if (include_option && !(commands[i].option & include_option)) + continue; + if (exclude_option && (commands[i].option & exclude_option)) + continue; + string_list_append(out, commands[i].cmd); } } @@ -809,8 +803,8 @@ static void execv_dashed_external(const char **argv) static int is_deprecated_command(const char *cmd) { - return !strcmp(cmd, "whatchanged") || - !strcmp(cmd, "pack-redundant"); + struct cmd_struct *builtin = get_builtin(cmd); + return builtin && (builtin->option & DEPRECATED); } static int run_argv(struct strvec *args) Range-diff against v3: 1: bdc683a92b3 ! 1: 66e6a9554b1 git: add `deprecated` category to --list-cmds @@ Commit message Let’s expand the experimental `--list-cmds`[1] to allow users and programs to query for this information. We will also use this in an - upcoming commit to assert that all deprecated commands will have been - covered in some manner. + upcoming commit to implement `is_deprecated_command`. [1]: Using something which is experimental to query for deprecations is perhaps not the most ideal approach, but it is simple to implement and better than having to scan the documentation + Acked-by: Patrick Steinhardt <ps@pks.im> + Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## + v4: + + Incorporate Patrick’s suggestions about the for-loop refactor and + formatting the overlong lines. Now drop the function doc since it + doesn’t apply anymore. + + Also adjust the commit message now that we use it in the C source in an + upcoming commit, not just/only as an assert-helper (in an upcoming + commit). + v3 (new): This is something I wanted to submit independently until the point about @@ git.c: const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); -+/* -+ * 'include_option' and 'exclude_option' are mutually exclusive. -+ * -+ * The default ('!include_option') is to include everything -+ * except those filtered out by 'exclude_option'. -+ */ -+static void list_builtins(struct string_list *list, unsigned int include_option, unsigned int exclude_option); ++static void list_builtins(struct string_list *list, ++ unsigned int include_option, ++ unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ git.c: int is_builtin(const char *s) } -static void list_builtins(struct string_list *out, unsigned int exclude_option) -+static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) ++static void list_builtins(struct string_list *out, ++ unsigned int include_option, ++ unsigned int exclude_option) { -- for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) -- continue; -- string_list_append(out, commands[i].cmd); -+ if (include_option && exclude_option) -+ BUG("'include_option' and 'exclude_option' are mutually exclusive"); -+ if (include_option) { -+ for (size_t i = 0; i < ARRAY_SIZE(commands); i++) -+ if (commands[i].option & include_option) -+ string_list_append(out, commands[i].cmd); -+ } else { -+ for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { -+ if (commands[i].option & exclude_option) -+ continue; -+ string_list_append(out, commands[i].cmd); -+ } ++ if (include_option && !(commands[i].option & include_option)) ++ continue; ++ if (exclude_option && (commands[i].option & exclude_option)) + continue; + string_list_append(out, commands[i].cmd); } - } - 2: 183dd68d09d < -: ----------- git: make the two loops look more symmetric 3: eec01cbac16 ! 2: 672253e0e71 git: allow alias-shadowing deprecated builtins @@ Commit message ## Notes (series) ## + v4: + + Better `is_deprecated_command` implementation. + v3 (new): Prerequisite for telling the user that they can alias `whatchanged` to @@ git.c: static void execv_dashed_external(const char **argv) +static int is_deprecated_command(const char *cmd) +{ -+ return !strcmp(cmd, "whatchanged") || -+ !strcmp(cmd, "pack-redundant"); ++ struct cmd_struct *builtin = get_builtin(cmd); ++ return builtin && (builtin->option & DEPRECATED); +} + static int run_argv(struct strvec *args) 4: 80fb02caeeb = 3: 00108f28f82 t0014: test shadowing of aliases for a sample of builtins 5: d25ee26f989 = 4: 6bdcaf7f80f you-still-use-that??: help the user help themselves 6: 50621a0748f = 5: 58de9767b22 whatchanged: tell users the git-log(1) equivalent 7: 812c9870f1b = 6: 407b430d02c whatchanged: remove not-even-shorter clause 8: 0d23a4badf0 = 7: fee752d2fb0 BreakingChanges: remove claim about whatchanged reports base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0 -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 21:44 ` Junio C Hamano 2025-09-09 19:45 ` [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk ` (6 subsequent siblings) 7 siblings, 1 reply; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> With 145 builtin commands (according to `git --list-cmds=builtins`), users are probably not keeping on top of which ones (if any) are deprecated. Let’s expand the experimental `--list-cmds`[1] to allow users and programs to query for this information. We will also use this in an upcoming commit to implement `is_deprecated_command`. [1]: Using something which is experimental to query for deprecations is perhaps not the most ideal approach, but it is simple to implement and better than having to scan the documentation Acked-by: Patrick Steinhardt <ps@pks.im> Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v4: Incorporate Patrick’s suggestions about the for-loop refactor and formatting the overlong lines. Now drop the function doc since it doesn’t apply anymore. Also adjust the commit message now that we use it in the C source in an upcoming commit, not just/only as an assert-helper (in an upcoming commit). v3 (new): This is something I wanted to submit independently until the point about aliasing builtins was brought up.[1] It will help (in a small way) with the upcoming patch “git: allow alias-shadowing deprecated builtins”. By the way: should `command-list.txt` be updated in some way (I didn’t know what way?) 🔗 1: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#mee19f8d39572f9021f9d3000758e87b6c32c967c Documentation/git.adoc | 3 ++- git.c | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4d..a2f0838b168 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -219,7 +219,8 @@ If you just want to run git as if it was started in `<path>` then use List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options), main (all commands in libexec directory), + parse-options), deprecated (deprecated builtins), + main (all commands in libexec directory), others (all other commands in `$PATH` that have git- prefix), list-<category> (see categories in command-list.txt), nohelpers (exclude helper commands), alias and config diff --git a/git.c b/git.c index 83eac0aeab7..fca6ebfce3d 100644 --- a/git.c +++ b/git.c @@ -28,6 +28,7 @@ #define NEED_WORK_TREE (1<<3) #define DELAY_PAGER_CONFIG (1<<4) #define NO_PARSEOPT (1<<5) /* parse-options is not used */ +#define DEPRECATED (1<<6) struct cmd_struct { const char *cmd; @@ -51,7 +52,9 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +static void list_builtins(struct string_list *list, + unsigned int include_option, + unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -88,7 +91,7 @@ static int list_cmds(const char *spec) int len = sep - spec; if (match_token(spec, len, "builtins")) - list_builtins(&list, 0); + list_builtins(&list, 0, 0); else if (match_token(spec, len, "main")) list_all_main_cmds(&list); else if (match_token(spec, len, "others")) @@ -99,6 +102,8 @@ static int list_cmds(const char *spec) list_aliases(&list); else if (match_token(spec, len, "config")) list_cmds_by_config(&list); + else if (match_token(spec, len, "deprecated")) + list_builtins(&list, DEPRECATED, 0); else if (len > 5 && !strncmp(spec, "list-", 5)) { struct strbuf sb = STRBUF_INIT; @@ -322,7 +327,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - list_builtins(&list, NO_PARSEOPT); + list_builtins(&list, 0, NO_PARSEOPT); for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); @@ -590,7 +595,7 @@ static struct cmd_struct commands[] = { { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, #ifndef WITH_BREAKING_CHANGES - { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED }, #endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -647,7 +652,7 @@ static struct cmd_struct commands[] = { { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, #ifndef WITH_BREAKING_CHANGES - { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED }, #endif { "worktree", cmd_worktree, RUN_SETUP }, { "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,11 +673,14 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, + unsigned int include_option, + unsigned int exclude_option) { for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) + if (include_option && !(commands[i].option & include_option)) + continue; + if (exclude_option && (commands[i].option & exclude_option)) continue; string_list_append(out, commands[i].cmd); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-09 19:45 ` [PATCH v4 1/7] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-09 21:44 ` Junio C Hamano 2025-09-10 11:41 ` Patrick Steinhardt ` (2 more replies) 0 siblings, 3 replies; 102+ messages in thread From: Junio C Hamano @ 2025-09-09 21:44 UTC (permalink / raw) To: kristofferhaugsbakk Cc: git, Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt kristofferhaugsbakk@fastmail.com writes: > Incorporate Patrick’s suggestions about the for-loop refactor and > formatting the overlong lines. Now drop the function doc since it > doesn’t apply anymore. So, if "include" is specified, a command that does not match any of criteria given by those flags is not included, and if "exclude" is specified, a command that matches any of the criteria given is not included. Which probably makes sense. The only user of "include" uses the DEPRECATED flag bit without any exclude option, so it is yet to be seen which one between the previous and the current design gives an easier-to-use behaviour, but I have no objection to the updated design presented here. Nicely done. Will replace. I guess we can mark this round as ready for 'next'? Thanks. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-09 21:44 ` Junio C Hamano @ 2025-09-10 11:41 ` Patrick Steinhardt 2025-09-10 15:50 ` Jeff King 2025-09-10 20:23 ` Kristoffer Haugsbakk 2 siblings, 0 replies; 102+ messages in thread From: Patrick Steinhardt @ 2025-09-10 11:41 UTC (permalink / raw) To: Junio C Hamano Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, Eric Sunshine, peff On Tue, Sep 09, 2025 at 02:44:21PM -0700, Junio C Hamano wrote: > kristofferhaugsbakk@fastmail.com writes: > > > Incorporate Patrick’s suggestions about the for-loop refactor and > > formatting the overlong lines. Now drop the function doc since it > > doesn’t apply anymore. > > So, if "include" is specified, a command that does not match any of > criteria given by those flags is not included, and if "exclude" is > specified, a command that matches any of the criteria given is not > included. Which probably makes sense. The only user of "include" > uses the DEPRECATED flag bit without any exclude option, so it is > yet to be seen which one between the previous and the current design > gives an easier-to-use behaviour, but I have no objection to the > updated design presented here. > > Nicely done. > > Will replace. I guess we can mark this round as ready for 'next'? I guess so. All my review feedback was addressed, so I don't have anything else to add. Thanks! Patrick ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-09 21:44 ` Junio C Hamano 2025-09-10 11:41 ` Patrick Steinhardt @ 2025-09-10 15:50 ` Jeff King 2025-09-10 21:40 ` Junio C Hamano 2025-09-10 20:23 ` Kristoffer Haugsbakk 2 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-10 15:50 UTC (permalink / raw) To: Junio C Hamano Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, Eric Sunshine, Patrick Steinhardt On Tue, Sep 09, 2025 at 02:44:21PM -0700, Junio C Hamano wrote: > Will replace. I guess we can mark this round as ready for 'next'? There's a small leak issue in patch 2. It should be a small fix, but worth doing as it is caught in CI. -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-10 15:50 ` Jeff King @ 2025-09-10 21:40 ` Junio C Hamano 0 siblings, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-09-10 21:40 UTC (permalink / raw) To: Jeff King Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, Eric Sunshine, Patrick Steinhardt Jeff King <peff@peff.net> writes: > On Tue, Sep 09, 2025 at 02:44:21PM -0700, Junio C Hamano wrote: > >> Will replace. I guess we can mark this round as ready for 'next'? > > There's a small leak issue in patch 2. It should be a small fix, but > worth doing as it is caught in CI. > > -Peff Thanks for being careful, as always. Very much appreciated. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 1/7] git: add `deprecated` category to --list-cmds 2025-09-09 21:44 ` Junio C Hamano 2025-09-10 11:41 ` Patrick Steinhardt 2025-09-10 15:50 ` Jeff King @ 2025-09-10 20:23 ` Kristoffer Haugsbakk 2 siblings, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-10 20:23 UTC (permalink / raw) To: Junio C Hamano, Kristoffer Haugsbakk Cc: git, Eric Sunshine, Jeff King, Patrick Steinhardt On Tue, Sep 9, 2025, at 23:44, Junio C Hamano wrote: > kristofferhaugsbakk@fastmail.com writes: > >> Incorporate Patrick’s suggestions about the for-loop refactor and >> formatting the overlong lines. Now drop the function doc since it >> doesn’t apply anymore. > > So, if "include" is specified, a command that does not match any of > criteria given by those flags is not included, and if "exclude" is > specified, a command that matches any of the criteria given is not > included. Which probably makes sense. On second thought I want to add back the “mutually exclusive” check since using both still doesn’t make sense. (Dunno why I thought otherwise. Patrick’s change was strictly a refactoring.) > The only user of "include" uses the DEPRECATED flag bit without any > exclude option, so it is yet to be seen which one between the previous > and the current design gives an easier-to-use behaviour, but I have no > objection to the updated design presented here. I’m happy with it. :) But people can suggest an alternative if they would like only one of the include/exclude. Us Java app. programmers are only permitted to practice bitfields in our spare time. -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 1/7] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-10 5:13 ` Jeff King 2025-09-09 19:45 ` [PATCH v4 3/7] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk ` (5 subsequent siblings) 7 siblings, 1 reply; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> git-whatchanged(1) is deprecated and you need to pass `--i-still-use-this` in order to force it to work as before. There are two affected users, or usages: 1. people who use the command in scripts; and 2. people who are used to using it interactively. For (1) the replacement is straightforward.[1] But people in (2) might like the name or be really used to typing it.[3] An obvious first thought is to suggest aliasing `whatchanged` to the git-log(1) equivalent.[1] But this doesn’t work and is awkward since you cannot shadow builtins via aliases. Now you are left in an uncomfortable limbo; your alias won’t work until the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be shadowed by aliases. The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all deprecated commands the same. [1]: git log --raw --no-merges With a minor caveat: you get different outputs if you happen to have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v4: Better `is_deprecated_command` implementation. v3 (new): Prerequisite for telling the user that they can alias `whatchanged` to `git log --raw --no-merged`. Link: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#md434b0968f499263262fb1805d82b788b8349d9a > I think that is good advice, but... it won't do anything until we > actually drop the whatchanged command, since until then we'll refuse to > override the command (even the crippled --i-still-use-this one). > > We'd need something like the patch here: ❦ The test_file_not_empty expect is here because the git(1) command could fail. Make sure that it did indeed output anyhing on stdout. (Or if a previous redirect to `expect` outputted something it should be completely different to `actual` in any case) I don’t know if this is just a waste. Documentation/config/alias.adoc | 3 ++- git.c | 19 +++++++++++++++++++ t/t0014-alias.sh | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Documentation/config/alias.adoc b/Documentation/config/alias.adoc index 2c5db0ad842..3c8fab3a95c 100644 --- a/Documentation/config/alias.adoc +++ b/Documentation/config/alias.adoc @@ -3,7 +3,8 @@ alias.*:: after defining `alias.last = cat-file commit HEAD`, the invocation `git last` is equivalent to `git cat-file commit HEAD`. To avoid confusion and troubles with script usage, aliases that - hide existing Git commands are ignored. Arguments are split by + hide existing Git commands are ignored except for deprecated + commands. Arguments are split by spaces, the usual shell quoting and escaping are supported. A quote pair or a backslash can be used to quote them. + diff --git a/git.c b/git.c index fca6ebfce3d..b3aafebfe4c 100644 --- a/git.c +++ b/git.c @@ -801,6 +801,12 @@ static void execv_dashed_external(const char **argv) exit(128); } +static int is_deprecated_command(const char *cmd) +{ + struct cmd_struct *builtin = get_builtin(cmd); + return builtin && (builtin->option & DEPRECATED); +} + static int run_argv(struct strvec *args) { int done_alias = 0; @@ -808,6 +814,19 @@ static int run_argv(struct strvec *args) struct string_list_item *seen; while (1) { + /* + * Allow deprecated commands to be overridden by aliases. This + * creates a seamless path forward for people who want to keep + * using the name after it is gone, but want to skip the + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && + alias_lookup(args->v[0])) { + if (!handle_alias(args)) + break; + done_alias = 1; + continue; + } /* * If we tried alias and futzed with our environment, * it no longer is safe to invoke builtins directly in diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 854d59ec58c..89bedb9f73b 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -55,4 +55,21 @@ test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' +can_alias_deprecated_builtin () { + cmd="$1" && + # some git(1) commands will fail for `-h` (the case for + # git-status as of 2025-09-07) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'can alias-shadow deprecated builtins' ' + for cmd in $(git --list-cmds=deprecated) + do + can_alias_deprecated_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-09 19:45 ` [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-10 5:13 ` Jeff King 2025-09-10 15:48 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-10 5:13 UTC (permalink / raw) To: kristofferhaugsbakk Cc: git, Kristoffer Haugsbakk, Eric Sunshine, Patrick Steinhardt On Tue, Sep 09, 2025 at 09:45:52PM +0200, kristofferhaugsbakk@fastmail.com wrote: > + if (is_deprecated_command(args->v[0]) && > + alias_lookup(args->v[0])) { > + if (!handle_alias(args)) > + break; > + done_alias = 1; > + continue; > + } I think this is failing the SANITIZE=leak jobs, because alias_lookup() returns an allocated string with the alias. You need to capture and free it, or introduce an alias_exists() wrapper to do so. There might also be a way to do it just by calling handle_alias() and checking its return value (it seems to indicate whether an alias was found, but I didn't look through the whole function carefully, or think about the implications of how the done_alias flag works). -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-10 5:13 ` Jeff King @ 2025-09-10 15:48 ` Jeff King 2025-09-10 17:58 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-10 15:48 UTC (permalink / raw) To: kristofferhaugsbakk Cc: git, Kristoffer Haugsbakk, Eric Sunshine, Patrick Steinhardt On Wed, Sep 10, 2025 at 01:13:47AM -0400, Jeff King wrote: > On Tue, Sep 09, 2025 at 09:45:52PM +0200, kristofferhaugsbakk@fastmail.com wrote: > > > + if (is_deprecated_command(args->v[0]) && > > + alias_lookup(args->v[0])) { > > + if (!handle_alias(args)) > > + break; > > + done_alias = 1; > > + continue; > > + } > > I think this is failing the SANITIZE=leak jobs, because alias_lookup() > returns an allocated string with the alias. You need to capture and free > it, or introduce an alias_exists() wrapper to do so. > > There might also be a way to do it just by calling handle_alias() and > checking its return value (it seems to indicate whether an alias was > found, but I didn't look through the whole function carefully, or think > about the implications of how the done_alias flag works). I _think_ this is correct: diff --git a/git.c b/git.c index 47857d280f..ea9ec77a88 100644 --- a/git.c +++ b/git.c @@ -823,9 +823,7 @@ static int run_argv(struct strvec *args) * deprecation complaint in the meantime. */ if (is_deprecated_command(args->v[0]) && - alias_lookup(args->v[0])) { - if (!handle_alias(args)) - break; + handle_alias(args)) { done_alias = 1; continue; } The handle_alias() function will either: - return 0 if it does not find an alias - return 1 if it finds an alias and we should loop again to run that command (but set done_alias so we know to suppress in-process builtins below). The "args" array will have been updated with the new command name. - exit itself if it's a "!" shell alias that we exec So we just need to loop again when it told us that it found an alias (it is tempting to just continue in the loop body, but that would miss the case of a deprecated alias that resolves to another deprecated alias). Anyway, I believe that is correct and solves the leak issue (because handle_alias() does the lookup and takes care of cleanup itself). -Peff ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-10 15:48 ` Jeff King @ 2025-09-10 17:58 ` Kristoffer Haugsbakk 2025-09-10 18:34 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-10 17:58 UTC (permalink / raw) To: Jeff King, Kristoffer Haugsbakk; +Cc: git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 10, 2025, at 17:48, Jeff King wrote: >>[snip] >> There might also be a way to do it just by calling handle_alias() and >> checking its return value (it seems to indicate whether an alias was >> found, but I didn't look through the whole function carefully, or think >> about the implications of how the done_alias flag works). > > I _think_ this is correct: > >[diff snip] Thank you. The best I could come up was making `alias.c:alias_exists`. Which must be redundant given the call to `handlke_alias()` that you mention later here. > The handle_alias() function will either: > > - return 0 if it does not find an alias > > - return 1 if it finds an alias and we should loop again to run that > command (but set done_alias so we know to suppress in-process > builtins below). The "args" array will have been updated with the > new command name. This case and the `continue` seemed to make sense to me eventually. Not the `break` case though. > - exit itself if it's a "!" shell alias that we exec Yep. > So we just need to loop again when it told us that it found an alias (it > is tempting to just continue in the loop body, but that would miss the > case of a deprecated alias that resolves to another deprecated alias). Yeah, that’s subtle. Do you think this should be a test case? I guess it doesn’t hurt. > Anyway, I believe that is correct and solves the leak issue (because > handle_alias() does the lookup and takes care of cleanup itself). Thanks again. My local test suite passes. (Except `t5801-remote-helpers.sh` which never works for me.) And thanks for pointing this out to begin with. -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-10 17:58 ` Kristoffer Haugsbakk @ 2025-09-10 18:34 ` Jeff King 2025-09-11 17:31 ` Kristoffer Haugsbakk 2025-09-13 21:50 ` Kristoffer Haugsbakk 0 siblings, 2 replies; 102+ messages in thread From: Jeff King @ 2025-09-10 18:34 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 10, 2025 at 07:58:32PM +0200, Kristoffer Haugsbakk wrote: > > So we just need to loop again when it told us that it found an alias (it > > is tempting to just continue in the loop body, but that would miss the > > case of a deprecated alias that resolves to another deprecated alias). > > Yeah, that’s subtle. > > Do you think this should be a test case? I guess it doesn’t hurt. Yeah, probably would be easy to add. We need two deprecated command names, but it looks like we do have that at this point. :) > > Anyway, I believe that is correct and solves the leak issue (because > > handle_alias() does the lookup and takes care of cleanup itself). > > Thanks again. My local test suite passes. (Except > `t5801-remote-helpers.sh` which never works for me.) I sometimes see failures there because I've checked out and built an old version which creates git-remote-testgit as a built script. That was later moved into t/t5801 via 5afb2ce4cd (remote-testgit: move it into the support directory for t5801, 2019-04-12). But if you have an old built copy lying around in the project root, then "git fetch" will find that old version first (because it prepends the root GIT_EXEC_PATH to PATH when it runs). So we run the old version, which may or may not support what the more modern test needs. And deleting "git-remote-testgit" (or just running "git clean") makes it go away. That may or may not be your problem, of course. ;) -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-10 18:34 ` Jeff King @ 2025-09-11 17:31 ` Kristoffer Haugsbakk 2025-09-11 20:32 ` Jeff King 2025-09-13 21:50 ` Kristoffer Haugsbakk 1 sibling, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-11 17:31 UTC (permalink / raw) To: Jeff King; +Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 10, 2025, at 20:34, Jeff King wrote: > On Wed, Sep 10, 2025 at 07:58:32PM +0200, Kristoffer Haugsbakk wrote: > >> > So we just need to loop again when it told us that it found an alias (it >> > is tempting to just continue in the loop body, but that would miss the >> > case of a deprecated alias that resolves to another deprecated alias). >> >> Yeah, that’s subtle. >> >> Do you think this should be a test case? I guess it doesn’t hurt. > > Yeah, probably would be easy to add. We need two deprecated command > names, but it looks like we do have that at this point. :) Thanks. That works fine: test_expect_success 'can alias-shadow via two deprecated builtins' ' # some git(1) commands will fail... (see above) test_might_fail git status -h >expect && test_file_not_empty expect && test_might_fail git -c alias.whatchanged=pack-redundant \ -c alias.pack-redundant=status whatchanged -h >actual && test_cmp expect actual ' But it turns out there is a regression in my code with the recursion detection. Compare: $ ./git -c alias.one=two -c alias.two=two one -h 'one' is aliased to 'two' 'two' is aliased to 'two' fatal: recursive alias: two with: $ ./git -c alias.whatchanged=pack-redundant -c alias.pack-redundant=whatchanged whatchanged -h 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' [forever] Both for your suggested change and my v4. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-11 17:31 ` Kristoffer Haugsbakk @ 2025-09-11 20:32 ` Jeff King 2025-09-11 20:43 ` Jeff King 2025-09-11 20:44 ` Jeff King 0 siblings, 2 replies; 102+ messages in thread From: Jeff King @ 2025-09-11 20:32 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Thu, Sep 11, 2025 at 07:31:04PM +0200, Kristoffer Haugsbakk wrote: > But it turns out there is a regression in my code with the recursion > detection. Compare: > > $ ./git -c alias.one=two -c alias.two=two one -h > 'one' is aliased to 'two' > 'two' is aliased to 'two' > fatal: recursive alias: two Your example there is a little funny; "two" is recursive to itself, even without "one". We detect that case in handle_alias(), and we would still detect: git -c alias.whatchanged=whatchanged whatchanged -h in the same spot. I assume what you meant was: $ ./git -c alias.one=two -c alias.two=one one -h 'one' is aliased to 'two' 'two' is aliased to 'one' fatal: alias loop detected: expansion of 'one' does not terminate: one <== two ==> which is handled in the caller. And indeed... > $ ./git -c alias.whatchanged=pack-redundant -c alias.pack-redundant=whatchanged whatchanged -h > 'whatchanged' is aliased to 'pack-redundant' > 'pack-redundant' is aliased to 'whatchanged' > 'whatchanged' is aliased to 'pack-redundant' > 'pack-redundant' is aliased to 'whatchanged' > 'whatchanged' is aliased to 'pack-redundant' > 'pack-redundant' is aliased to 'whatchanged' > 'whatchanged' is aliased to 'pack-redundant' > 'pack-redundant' is aliased to 'whatchanged' > [forever] ...that cannot work with where we've placed the new conditional, because it continues the loop before hitting the alias check. If we move that to the top, like the patch below, it works. It is a little funny to do it up front even when we're going to directly run a builtin, but I don't think it harms much. OTOH I find the whole placement a little odd in the first place. We are speculatively adding to the cmd list before even finding out if we have an alias. It kind of feels like this should be part of handle_alias() in the first place. We'd need to pass in the cmd_list variable for it to add to and check. -Peff --- diff --git a/git.c b/git.c index ca66e24639..17c566a802 100644 --- a/git.c +++ b/git.c @@ -814,6 +814,24 @@ static int run_argv(struct strvec *args) struct string_list_item *seen; while (1) { + seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < cmd_list.nr; i++) { + struct string_list_item *item = &cmd_list.items[i]; + + strbuf_addf(&sb, "\n %s", item->string); + if (item == seen) + strbuf_addstr(&sb, " <=="); + else if (i == cmd_list.nr - 1) + strbuf_addstr(&sb, " ==>"); + } + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), cmd_list.items[0].string, sb.buf); + } + + string_list_append(&cmd_list, args->v[0]); + /* * Allow deprecated commands to be overridden by aliases. This * creates a seamless path forward for people who want to keep @@ -874,24 +892,6 @@ static int run_argv(struct strvec *args) /* .. then try the external ones */ execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); - if (seen) { - struct strbuf sb = STRBUF_INIT; - for (size_t i = 0; i < cmd_list.nr; i++) { - struct string_list_item *item = &cmd_list.items[i]; - - strbuf_addf(&sb, "\n %s", item->string); - if (item == seen) - strbuf_addstr(&sb, " <=="); - else if (i == cmd_list.nr - 1) - strbuf_addstr(&sb, " ==>"); - } - die(_("alias loop detected: expansion of '%s' does" - " not terminate:%s"), cmd_list.items[0].string, sb.buf); - } - - string_list_append(&cmd_list, args->v[0]); - /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-11 20:32 ` Jeff King @ 2025-09-11 20:43 ` Jeff King 2025-09-13 14:10 ` Kristoffer Haugsbakk 2025-09-11 20:44 ` Jeff King 1 sibling, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-11 20:43 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Thu, Sep 11, 2025 at 04:32:56PM -0400, Jeff King wrote: > It is a little funny to do it up front even when we're going to directly > run a builtin, but I don't think it harms much. OTOH I find the whole > placement a little odd in the first place. We are speculatively adding > to the cmd list before even finding out if we have an alias. It kind of > feels like this should be part of handle_alias() in the first place. > We'd need to pass in the cmd_list variable for it to add to and check. IOW, something like this (perhaps as a preparatory patch): diff --git a/git.c b/git.c index ca66e24639..06de0bacf3 100644 --- a/git.c +++ b/git.c @@ -365,7 +365,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) return (*argv) - orig_argv; } -static int handle_alias(struct strvec *args) +static int handle_alias(struct strvec *args, struct string_list *cmd_list) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; @@ -376,6 +376,8 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { + struct string_list_item *seen; + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); @@ -423,6 +425,24 @@ static int handle_alias(struct strvec *args) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); + seen = unsorted_string_list_lookup(cmd_list, args->v[0]); + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < cmd_list->nr; i++) { + struct string_list_item *item = &cmd_list->items[i]; + + strbuf_addf(&sb, "\n %s", item->string); + if (item == seen) + strbuf_addstr(&sb, " <=="); + else if (i == cmd_list->nr - 1) + strbuf_addstr(&sb, " ==>"); + } + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), cmd_list->items[0].string, sb.buf); + } + + string_list_append(cmd_list, args->v[0]); + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); @@ -811,7 +831,6 @@ static int run_argv(struct strvec *args) { int done_alias = 0; struct string_list cmd_list = STRING_LIST_INIT_DUP; - struct string_list_item *seen; while (1) { /* @@ -821,7 +840,7 @@ static int run_argv(struct strvec *args) * deprecation complaint in the meantime. */ if (is_deprecated_command(args->v[0]) && - handle_alias(args)) { + handle_alias(args, &cmd_list)) { done_alias = 1; continue; } @@ -874,30 +893,12 @@ static int run_argv(struct strvec *args) /* .. then try the external ones */ execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); - if (seen) { - struct strbuf sb = STRBUF_INIT; - for (size_t i = 0; i < cmd_list.nr; i++) { - struct string_list_item *item = &cmd_list.items[i]; - - strbuf_addf(&sb, "\n %s", item->string); - if (item == seen) - strbuf_addstr(&sb, " <=="); - else if (i == cmd_list.nr - 1) - strbuf_addstr(&sb, " ==>"); - } - die(_("alias loop detected: expansion of '%s' does" - " not terminate:%s"), cmd_list.items[0].string, sb.buf); - } - - string_list_append(&cmd_list, args->v[0]); - /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having * alias.log = show */ - if (!handle_alias(args)) + if (!handle_alias(args, &cmd_list)) break; done_alias = 1; } And then along with that: - a new test at least of the looping deprecated case (we have an existing test for non-deprecated looping aliases) - while we are moving all this code, I might consider calling cmd_list something more obvious like "expanded_aliases" or something. - the placement above puts it next to the direct-recursion check in handle_alias(). But it does change the output a bit, since we now do the check after the "-h" expansion. So Before we'd print: $ git -c alias.one=two -c alias.two=one one -h 'one' is aliased to 'two' 'two' is aliased to 'one' fatal: alias loop detected: expansion of 'one' does not terminate: one <== two ==> And now we'll print: $ ./git -c alias.one=two -c alias.two=one one -h 'one' is aliased to 'two' 'two' is aliased to 'one' 'one' is aliased to 'two' fatal: alias loop detected: expansion of 'one' does not terminate: one <== two ==> with one extra "-h" line. Probably not a big deal, but that perhaps points to the fact that we could be detecting the cycle one loop sooner. I.e., as soon as we see that "two" points to "one" we know we have cycled. We could probably be checking new_argv there instead, after adding the current name to cmd_list (and in fact that would catch the direct-recursion case automatically and we would not need to do so manually, though maybe people prefer the more specific message it produces). I'll leave that as an exercise for the reader. ;) -Peff ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-11 20:43 ` Jeff King @ 2025-09-13 14:10 ` Kristoffer Haugsbakk 2025-09-13 22:06 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-13 14:10 UTC (permalink / raw) To: Jeff King, Kristoffer Haugsbakk; +Cc: git, Eric Sunshine, Patrick Steinhardt On Thu, Sep 11, 2025, at 22:43, Jeff King wrote: > On Thu, Sep 11, 2025 at 04:32:56PM -0400, Jeff King wrote: > >> It is a little funny to do it up front even when we're going to directly >> run a builtin, but I don't think it harms much. OTOH I find the whole >> placement a little odd in the first place. We are speculatively adding >> to the cmd list before even finding out if we have an alias. It kind of >> feels like this should be part of handle_alias() in the first place. >> We'd need to pass in the cmd_list variable for it to add to and check. > > IOW, something like this (perhaps as a preparatory patch): >[snip diff] > And then along with that: > > - a new test at least of the looping deprecated case (we have an > existing test for non-deprecated looping aliases) > > - while we are moving all this code, I might consider calling cmd_list > something more obvious like "expanded_aliases" or something. > > - the placement above puts it next to the direct-recursion check in > handle_alias(). But it does change the output a bit, since we now do > the check after the "-h" expansion. So Before we'd print: > > $ git -c alias.one=two -c alias.two=one one -h > 'one' is aliased to 'two' > 'two' is aliased to 'one' > fatal: alias loop detected: expansion of 'one' does not terminate: > one <== > two ==> > > And now we'll print: > > $ ./git -c alias.one=two -c alias.two=one one -h > 'one' is aliased to 'two' > 'two' is aliased to 'one' > 'one' is aliased to 'two' > fatal: alias loop detected: expansion of 'one' does not terminate: > one <== > two ==> > > with one extra "-h" line. Probably not a big deal, but that perhaps > points to the fact that we could be detecting the cycle one loop > sooner. I.e., as soon as we see that "two" points to "one" we know > we have cycled. We could probably be checking new_argv there > instead, after adding the current name to cmd_list (and in fact that > would catch the direct-recursion case automatically and we would not > need to do so manually, though maybe people prefer the more specific > message it produces). > > I'll leave that as an exercise for the reader. ;) That’s great, thanks. I’ve added it as a preparatory patch/commit with this message. ----- git: move seen-command bookkeeping into handle_alias(...) We are about to complicate the command handling by allowing *deprecated* builtins to be shadowed by aliases. We need to organize the code in order to facilitate that.[1] The code in the `while(1)` speculatively adds commands to the list before finding out if it’s an alias. Let’s instead move it inside `handle_alias(...)` and in turn only run this logic when we have found an alias. This is not a refactor since the error output is changed; we will now print '<cmd1>' is aliased to '<cmd2>' while iterating in addition to the final `fatal` message. [1]: We will do that by an additional call to `handle_alias(1)` inside the loop. *Not* moving this code leaves a blind spot; we still detect regular alias looping/recursion but we miss it when it is done using deprecated builtins. -- Kris ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-13 14:10 ` Kristoffer Haugsbakk @ 2025-09-13 22:06 ` Jeff King 2025-09-14 17:24 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-13 22:06 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Sat, Sep 13, 2025 at 04:10:57PM +0200, Kristoffer Haugsbakk wrote: > The code in the `while(1)` speculatively adds commands to the list > before finding out if it’s an alias. Let’s instead move it inside > `handle_alias(...)` and in turn only run this logic when we have found > an alias. > > This is not a refactor since the error output is changed; we will > now print > > '<cmd1>' is aliased to '<cmd2>' > > while iterating in addition to the final `fatal` message. If you want to get rid of that last paragraph, I think it really is as simple as checking the expanded alias new_argv[0] as soon as we see it, like: diff --git a/git.c b/git.c index 06de0bacf3..f11ce416a3 100644 --- a/git.c +++ b/git.c @@ -425,7 +425,9 @@ static int handle_alias(struct strvec *args, struct string_list *cmd_list) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); - seen = unsorted_string_list_lookup(cmd_list, args->v[0]); + string_list_append(cmd_list, args->v[0]); + + seen = unsorted_string_list_lookup(cmd_list, new_argv[0]); if (seen) { struct strbuf sb = STRBUF_INIT; for (size_t i = 0; i < cmd_list->nr; i++) { @@ -441,8 +443,6 @@ static int handle_alias(struct strvec *args, struct string_list *cmd_list) " not terminate:%s"), cmd_list->items[0].string, sb.buf); } - string_list_append(cmd_list, args->v[0]); - trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); It is important to move the append of args->v[0] up (though arguably it should be alias_command here, which is a local-variable alias that the rest of the function uses). Adding it up-front is not needed for loop detection, but it is shown as part of the output when we do find a loop. You could _also_ ditch the "recursive alias" check above at that point, though I think it produces a slightly nicer message: $ ./git -c alias.foo=foo foo fatal: recursive alias: foo vs: $ ./git -c alias.foo=foo foo fatal: alias loop detected: expansion of 'foo' does not terminate: foo <== Though perhaps if the output code marked it as both the start and end of the loop it would be more sensible. Maybe like: diff --git a/git.c b/git.c index f11ce416a3..f1a83f2e6a 100644 --- a/git.c +++ b/git.c @@ -422,9 +422,6 @@ static int handle_alias(struct strvec *args, struct string_list *cmd_list) if (count < 1) die(_("empty alias for %s"), alias_command); - if (!strcmp(alias_command, new_argv[0])) - die(_("recursive alias: %s"), alias_command); - string_list_append(cmd_list, args->v[0]); seen = unsorted_string_list_lookup(cmd_list, new_argv[0]); @@ -436,8 +433,8 @@ static int handle_alias(struct strvec *args, struct string_list *cmd_list) strbuf_addf(&sb, "\n %s", item->string); if (item == seen) strbuf_addstr(&sb, " <=="); - else if (i == cmd_list->nr - 1) - strbuf_addstr(&sb, " ==>"); + if (i == cmd_list->nr - 1) + strbuf_addstr(&sb, item == seen ? ">" : " ==>"); } die(_("alias loop detected: expansion of '%s' does" " not terminate:%s"), cmd_list->items[0].string, sb.buf); I dunno. Maybe it is not worth tinkering with too much. But the "this changes the output" justification from your proposed message seems to me an indication that the refactor is a little iffy. -Peff ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-13 22:06 ` Jeff King @ 2025-09-14 17:24 ` Kristoffer Haugsbakk 2025-09-15 1:44 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-14 17:24 UTC (permalink / raw) To: Jeff King; +Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Sun, Sep 14, 2025, at 00:06, Jeff King wrote: > On Sat, Sep 13, 2025 at 04:10:57PM +0200, Kristoffer Haugsbakk wrote: > >> The code in the `while(1)` speculatively adds commands to the list >> before finding out if it’s an alias. Let’s instead move it inside >> `handle_alias(...)` and in turn only run this logic when we have found >> an alias. >> >> This is not a refactor since the error output is changed; we will >> now print >> >> '<cmd1>' is aliased to '<cmd2>' >> >> while iterating in addition to the final `fatal` message. > > If you want to get rid of that last paragraph, I think it really is as > simple as checking the expanded alias new_argv[0] as soon as we see it, > like: I tried using both of these changes (the patches) but the `alias...` test suite started failing. >[snip] > You could _also_ ditch the "recursive alias" check above at that point, > though I think it produces a slightly nicer message: > > $ ./git -c alias.foo=foo foo > fatal: recursive alias: foo > > vs: > > $ ./git -c alias.foo=foo foo > fatal: alias loop detected: expansion of 'foo' does not terminate: > foo <== I didn’t try these. >[snip] > I dunno. Maybe it is not worth tinkering with too much. But the "this > changes the output" justification from your proposed message seems to me > an indication that the refactor is a little iffy. I ended up with not changing it for v5. I missed the first time around that this informational message is only “logged” in the specific case of `<git cmd> -h`. In turn you only get one more line of output when you are (1) chaining deprecated aliases, and (2) making a loop. v5 still mentions this but I try to put it off to the side, in other words a footnote. Thanks ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-14 17:24 ` Kristoffer Haugsbakk @ 2025-09-15 1:44 ` Jeff King 2025-09-15 6:27 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-15 1:44 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Sun, Sep 14, 2025 at 07:24:14PM +0200, Kristoffer Haugsbakk wrote: > > If you want to get rid of that last paragraph, I think it really is as > > simple as checking the expanded alias new_argv[0] as soon as we see it, > > like: > > I tried using both of these changes (the patches) but the `alias...` > test suite started failing. Hmm, it still passes for me. If I do just this on top of your v5, it likewise passes (except for your new test which expects the redundant line). diff --git a/git.c b/git.c index 10315742f8..c5fad56813 100644 --- a/git.c +++ b/git.c @@ -425,7 +425,10 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); - seen = unsorted_string_list_lookup(expanded_aliases, args->v[0]); + string_list_append(expanded_aliases, alias_command); + seen = unsorted_string_list_lookup(expanded_aliases, + new_argv[0]); + if (seen) { struct strbuf sb = STRBUF_INIT; for (size_t i = 0; i < expanded_aliases->nr; i++) { @@ -441,8 +444,6 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); } - string_list_append(expanded_aliases, args->v[0]); - trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); > I ended up with not changing it for v5. I missed the first time around > that this informational message is only “logged” in the specific case of > `<git cmd> -h`. In turn you only get one more line of output when you > are (1) chaining deprecated aliases, and (2) making a loop. I don't think (1) is necessary. With your v5 I get: $ ./git -c alias.one=two -c alias.two=one one -h 'one' is aliased to 'two' 'two' is aliased to 'one' 'one' is aliased to 'two' fatal: alias loop detected: expansion of 'one' does not terminate: one <== two ==> So the extra line is printed even without deprecated aliases. -Peff ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-15 1:44 ` Jeff King @ 2025-09-15 6:27 ` Kristoffer Haugsbakk 0 siblings, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-15 6:27 UTC (permalink / raw) To: Jeff King; +Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Mon, Sep 15, 2025, at 03:44, Jeff King wrote: > On Sun, Sep 14, 2025 at 07:24:14PM +0200, Kristoffer Haugsbakk wrote: > >> > If you want to get rid of that last paragraph, I think it really is as >> > simple as checking the expanded alias new_argv[0] as soon as we see it, >> > like: >> >> I tried using both of these changes (the patches) but the `alias...` >> test suite started failing. > > Hmm, it still passes for me. If I do just this on top of your v5, it > likewise passes (except for your new test which expects the redundant > line). > >[snip diff] That works for me. Thanks! I will send the next round this evening or tomorrow. It will be good to get rid of those footnotes. >> I ended up with not changing it for v5. I missed the first time around >> that this informational message is only “logged” in the specific case of >> `<git cmd> -h`. In turn you only get one more line of output when you >> are (1) chaining deprecated aliases, and (2) making a loop. > > I don't think (1) is necessary. With your v5 I get: > > $ ./git -c alias.one=two -c alias.two=one one -h > 'one' is aliased to 'two' > 'two' is aliased to 'one' > 'one' is aliased to 'two' > fatal: alias loop detected: expansion of 'one' does not terminate: > one <== > two ==> > > So the extra line is printed even without deprecated aliases. That’s right, that part’s in error. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-11 20:32 ` Jeff King 2025-09-11 20:43 ` Jeff King @ 2025-09-11 20:44 ` Jeff King 2025-09-11 21:19 ` Junio C Hamano 1 sibling, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-11 20:44 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Thu, Sep 11, 2025 at 04:32:56PM -0400, Jeff King wrote: > On Thu, Sep 11, 2025 at 07:31:04PM +0200, Kristoffer Haugsbakk wrote: > > > But it turns out there is a regression in my code with the recursion > > detection. Compare: > > > > $ ./git -c alias.one=two -c alias.two=two one -h > > 'one' is aliased to 'two' > > 'two' is aliased to 'two' > > fatal: recursive alias: two > > Your example there is a little funny; "two" is recursive to itself, even > without "one". We detect that case in handle_alias(), and we would still > detect: Also, I meant to say: good catch. :) I did not even think about loop detection at all in my suggestions. -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-11 20:44 ` Jeff King @ 2025-09-11 21:19 ` Junio C Hamano 0 siblings, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-09-11 21:19 UTC (permalink / raw) To: Jeff King Cc: Kristoffer Haugsbakk, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt Jeff King <peff@peff.net> writes: > On Thu, Sep 11, 2025 at 04:32:56PM -0400, Jeff King wrote: > >> On Thu, Sep 11, 2025 at 07:31:04PM +0200, Kristoffer Haugsbakk wrote: >> >> > But it turns out there is a regression in my code with the recursion >> > detection. Compare: >> > >> > $ ./git -c alias.one=two -c alias.two=two one -h >> > 'one' is aliased to 'two' >> > 'two' is aliased to 'two' >> > fatal: recursive alias: two >> >> Your example there is a little funny; "two" is recursive to itself, even >> without "one". We detect that case in handle_alias(), and we would still >> detect: > > Also, I meant to say: good catch. :) I did not even think about loop > detection at all in my suggestions. Neither did I. I am very glad that you two are very efficiently and effectively collaborating on this topic together. Thank you very much and kudos for both of you. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins 2025-09-10 18:34 ` Jeff King 2025-09-11 17:31 ` Kristoffer Haugsbakk @ 2025-09-13 21:50 ` Kristoffer Haugsbakk 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-13 21:50 UTC (permalink / raw) To: Jeff King; +Cc: Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 10, 2025, at 20:34, Jeff King wrote: >> Thanks again. My local test suite passes. (Except >> `t5801-remote-helpers.sh` which never works for me.) > > I sometimes see failures there because I've checked out and built an old > version which creates git-remote-testgit as a built script. That was > later moved into t/t5801 via 5afb2ce4cd (remote-testgit: move it into > the support directory for t5801, 2019-04-12). But if you have an old > built copy lying around in the project root, then "git fetch" will find > that old version first (because it prepends the root GIT_EXEC_PATH to > PATH when it runs). So we run the old version, which may or may not > support what the more modern test needs. > > And deleting "git-remote-testgit" (or just running "git clean") makes it > go away. > > That may or may not be your problem, of course. ;) Thanks—that was exactly it.:) ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v4 3/7] t0014: test shadowing of aliases for a sample of builtins 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 1/7] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 4/7] you-still-use-that??: help the user help themselves kristofferhaugsbakk ` (4 subsequent siblings) 7 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The previous commit added a test for shadowing deprecated builtins. Let’s make the test suite more complete by exercising a sample of the builtins and in turn test the documentation for git-config(1): To avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored except for deprecated commands. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): Only a sample of builtins since the test file takes about 600ms longer if I test all of them. t/t0014-alias.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 89bedb9f73b..bf7e6512bb1 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -72,4 +72,21 @@ test_expect_success 'can alias-shadow deprecated builtins' ' done ' +cannot_alias_regular_builtin () { + cmd="$1" && + # some git(1) commands will fail... (see above) + test_might_fail git "$cmd" -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'cannot alias-shadow a sample of regular builtins' ' + for cmd in grep check-ref-format interpret-trailers \ + checkout-index fast-import diagnose rev-list prune + do + cannot_alias_regular_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 4/7] you-still-use-that??: help the user help themselves 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (2 preceding siblings ...) 2025-09-09 19:45 ` [PATCH v4 3/7] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 5/7] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk ` (3 subsequent siblings) 7 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: www.git-scm.com has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: I had second thoughts about the bullet point about send-an-email. Change it to the one Eric Sunshine proposed;[1] make sure to spell out that you can send an email conditioned on not finding a suitable replacement. Also change the area to something more pointed. And also use a clear URL to refer to www.git-scm.com. [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm v1: An alternative to linking to www.git-scm.com is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..35dc57eb07e 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,24 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 5/7] whatchanged: tell users the git-log(1) equivalent 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (3 preceding siblings ...) 2025-09-09 19:45 ` [PATCH v4 4/7] you-still-use-that??: help the user help themselves kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 6/7] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (2 subsequent siblings) 7 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1). That template produces almost the same output[3] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally [3]: You only get different outputs if you happen to have empty commits (no changes)[4] [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3: Add an alias hint now that that is possible. Also prefix each hint-line with `hint: `. v2: Review found a whitespace error in the prev. patch version. I found a broken footnote and wanted to expand on the last footnote. • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 8 +++++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..1d1e6e9130a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -543,7 +543,13 @@ int cmd_whatchanged(int argc, cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + "hint:\tgit log <opts> --raw --no-merges\n" + "hint: Or make an alias:\n" + "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 35dc57eb07e..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -395,7 +401,7 @@ NORETURN void you_still_use_that(const char *command_name) " know that you still use this command and were unable\n" " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 6/7] whatchanged: remove not-even-shorter clause 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (4 preceding siblings ...) 2025-09-09 19:45 ` [PATCH v4 5/7] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 7/7] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 7 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v4 7/7] BreakingChanges: remove claim about whatchanged reports 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (5 preceding siblings ...) 2025-09-09 19:45 ` [PATCH v4 6/7] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-09-09 19:45 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 7 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-09 19:45 UTC (permalink / raw) To: git; +Cc: Kristoffer Haugsbakk, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (6 preceding siblings ...) 2025-09-09 19:45 ` [PATCH v4 7/7] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk ` (9 more replies) 7 siblings, 10 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Based on the recent i-still-use-that reports about whatchanged, improve the error reporting with this command in mind: 1. Give more possible actions instead of just (only) asking them to send an email 2. Hint how to replace their git-whatchanged(1) use with git-log(1) or an alias `whatchanged` (you can alias deprecated commands now) 3. Minor documentation changes 4. Add `deprecated` to `git --list-cmds` § What the errors now look like $ ./git whatchanged 'git whatchanged' is nominated for removal. hint: You can replace 'git whatchanged <opts>' with: hint: git log <opts> --raw --no-merges hint: Or make an alias: hint: git config set --global alias.whatchanged 'log --raw --no-merges' If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20whatchanged - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this $ ./git pack-redundant 'git pack-redundant' is nominated for removal. If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20pack-redundant - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this § Changes in v5 Fix the leak that Peff found (with Peff’s suggestion). Also fix (with Peff’s help) a regression where you were able to get into an infinite alias loop specifically when using deprecated builtin names. Link: https://lore.kernel.org/git/20250910051347.GA556174@coredump.intra.peff.net/ Also bring back the `BUG` check. Cheers Kristoffer Haugsbakk (8): git: add `deprecated` category to --list-cmds git: move seen-alias bookkeeping into handle_alias(...) git: allow alias-shadowing deprecated builtins t0014: test shadowing of aliases for a sample of builtins you-still-use-that??: help the user help themselves whatchanged: hint about git-log(1) and aliasing whatchanged: remove not-even-shorter clause BreakingChanges: remove claim about whatchanged reports Documentation/BreakingChanges.adoc | 2 +- Documentation/config/alias.adoc | 3 +- Documentation/git-whatchanged.adoc | 8 ++- Documentation/git.adoc | 3 +- builtin/log.c | 8 ++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- git.c | 90 ++++++++++++++++++++---------- t/t0014-alias.sh | 58 +++++++++++++++++++ usage.c | 33 ++++++++--- 10 files changed, 163 insertions(+), 46 deletions(-) Interdiff against v4: diff --git a/git.c b/git.c index b3aafebfe4c..1310363e5c4 100644 --- a/git.c +++ b/git.c @@ -365,7 +365,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) return (*argv) - orig_argv; } -static int handle_alias(struct strvec *args) +static int handle_alias(struct strvec *args, struct string_list *expanded_aliases) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; @@ -376,6 +376,8 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { + struct string_list_item *seen; + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); @@ -423,6 +425,24 @@ static int handle_alias(struct strvec *args) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); + seen = unsorted_string_list_lookup(expanded_aliases, args->v[0]); + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < expanded_aliases->nr; i++) { + struct string_list_item *item = &expanded_aliases->items[i]; + + strbuf_addf(&sb, "\n %s", item->string); + if (item == seen) + strbuf_addstr(&sb, " <=="); + else if (i == expanded_aliases->nr - 1) + strbuf_addstr(&sb, " ==>"); + } + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); + } + + string_list_append(expanded_aliases, args->v[0]); + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); @@ -677,6 +697,8 @@ static void list_builtins(struct string_list *out, unsigned int include_option, unsigned int exclude_option) { + if (include_option && exclude_option) + BUG("'include_option' and 'exclude_option' are mutually exclusive"); for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { if (include_option && !(commands[i].option & include_option)) continue; @@ -810,8 +832,7 @@ static int is_deprecated_command(const char *cmd) static int run_argv(struct strvec *args) { int done_alias = 0; - struct string_list cmd_list = STRING_LIST_INIT_DUP; - struct string_list_item *seen; + struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { /* @@ -821,9 +842,7 @@ static int run_argv(struct strvec *args) * deprecation complaint in the meantime. */ if (is_deprecated_command(args->v[0]) && - alias_lookup(args->v[0])) { - if (!handle_alias(args)) - break; + handle_alias(args, &expanded_aliases)) { done_alias = 1; continue; } @@ -876,35 +895,17 @@ static int run_argv(struct strvec *args) /* .. then try the external ones */ execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); - if (seen) { - struct strbuf sb = STRBUF_INIT; - for (size_t i = 0; i < cmd_list.nr; i++) { - struct string_list_item *item = &cmd_list.items[i]; - - strbuf_addf(&sb, "\n %s", item->string); - if (item == seen) - strbuf_addstr(&sb, " <=="); - else if (i == cmd_list.nr - 1) - strbuf_addstr(&sb, " ==>"); - } - die(_("alias loop detected: expansion of '%s' does" - " not terminate:%s"), cmd_list.items[0].string, sb.buf); - } - - string_list_append(&cmd_list, args->v[0]); - /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having * alias.log = show */ - if (!handle_alias(args)) + if (!handle_alias(args, &expanded_aliases)) break; done_alias = 1; } - string_list_clear(&cmd_list, 0); + string_list_clear(&expanded_aliases, 0); return done_alias; } diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index bf7e6512bb1..1ac739a2737 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -27,6 +27,21 @@ test_expect_success 'looping aliases - internal execution' ' test_grep "^fatal: alias loop detected: expansion of" output ' +test_expect_success 'looping aliases - deprecated builtins' ' + test_config alias.whatchanged pack-redundant && + test_config alias.pack-redundant whatchanged && + cat >expect <<-EOF && + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: + whatchanged <== + pack-redundant ==> + EOF + test_must_fail git whatchanged -h 2>actual && + test_cmp expect actual +' + # This test is disabled until external loops are fixed, because would block # the test suite for a full minute. # @@ -72,6 +87,15 @@ test_expect_success 'can alias-shadow deprecated builtins' ' done ' +test_expect_success 'can alias-shadow via two deprecated builtins' ' + # some git(1) commands will fail... (see above) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias.whatchanged=pack-redundant \ + -c alias.pack-redundant=status whatchanged -h >actual && + test_cmp expect actual +' + cannot_alias_regular_builtin () { cmd="$1" && # some git(1) commands will fail... (see above) Range-diff against v4: 1: 66e6a9554b1 ! 1: 13682553018 git: add `deprecated` category to --list-cmds @@ Commit message ## Notes (series) ## + v5: + + Add back the `BUG` check from v3 because I think it makes sense to only + populate one of the two options. + + Link: https://lore.kernel.org/git/cover.1757345711.git.code@khaugsbakk.name/T/#m922b852384911511c45afd458051f52b50dce62f + v4: Incorporate Patrick’s suggestions about the for-loop refactor and @@ git.c: int is_builtin(const char *s) + unsigned int include_option, + unsigned int exclude_option) { ++ if (include_option && exclude_option) ++ BUG("'include_option' and 'exclude_option' are mutually exclusive"); for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) -: ----------- > 2: 7f82ef6e96f git: move seen-alias bookkeeping into handle_alias(...) 2: 672253e0e71 ! 3: 4bfe36cccd0 git: allow alias-shadowing deprecated builtins @@ Commit message the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be - shadowed by aliases. + shadowed by aliases.[4] The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all @@ Commit message have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ + [4]: The test “looping aliases - deprecated builtins” covers the + case of the extra output mentioned in footnote number 3 of the + previous commit Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## + v5: + + Fix a leak caused by calling `alias_lookup(...)` without freeing the + return value by not calling that function. + + Add tests for deprecated builtins for infinite alias looping as well as + simple chaining. This is to exercise all code paths that we could think + of. + + Expand on the infinite alias looping test on the whole error + output (compared to the one above). Link this change to the + previous patch/commit by mentioning it in a footnote. + + See the last footnote and the note on the previous commit/patch. I have + opted not to get rid of this redundant line. But this documents the + change and future changes that affect it will trigger this + assertion (say if they remove the redundant line). + v4: Better `is_deprecated_command` implementation. @@ git.c: static void execv_dashed_external(const char **argv) static int run_argv(struct strvec *args) { int done_alias = 0; -@@ git.c: static int run_argv(struct strvec *args) - struct string_list_item *seen; + struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { + /* @@ git.c: static int run_argv(struct strvec *args) + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && -+ alias_lookup(args->v[0])) { -+ if (!handle_alias(args)) -+ break; ++ handle_alias(args, &expanded_aliases)) { + done_alias = 1; + continue; + } @@ git.c: static int run_argv(struct strvec *args) * it no longer is safe to invoke builtins directly in ## t/t0014-alias.sh ## +@@ t/t0014-alias.sh: test_expect_success 'looping aliases - internal execution' ' + test_grep "^fatal: alias loop detected: expansion of" output + ' + ++test_expect_success 'looping aliases - deprecated builtins' ' ++ test_config alias.whatchanged pack-redundant && ++ test_config alias.pack-redundant whatchanged && ++ cat >expect <<-EOF && ++ ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} ++ ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} ++ ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} ++ fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: ++ whatchanged <== ++ pack-redundant ==> ++ EOF ++ test_must_fail git whatchanged -h 2>actual && ++ test_cmp expect actual ++' ++ + # This test is disabled until external loops are fixed, because would block + # the test suite for a full minute. + # @@ t/t0014-alias.sh: test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' @@ t/t0014-alias.sh: test_expect_success 'tracing a shell alias with arguments show + can_alias_deprecated_builtin "$cmd" || return 1 + done +' ++ ++test_expect_success 'can alias-shadow via two deprecated builtins' ' ++ # some git(1) commands will fail... (see above) ++ test_might_fail git status -h >expect && ++ test_file_not_empty expect && ++ test_might_fail git -c alias.whatchanged=pack-redundant \ ++ -c alias.pack-redundant=status whatchanged -h >actual && ++ test_cmp expect actual ++' + test_done 3: 00108f28f82 ! 4: a04c6ae968e t0014: test shadowing of aliases for a sample of builtins @@ Metadata ## Commit message ## t0014: test shadowing of aliases for a sample of builtins - The previous commit added a test for shadowing deprecated builtins. + The previous commit added tests for shadowing deprecated builtins. Let’s make the test suite more complete by exercising a sample of the builtins and in turn test the documentation for git-config(1): @@ Notes (series) if I test all of them. ## t/t0014-alias.sh ## -@@ t/t0014-alias.sh: test_expect_success 'can alias-shadow deprecated builtins' ' - done +@@ t/t0014-alias.sh: test_expect_success 'can alias-shadow via two deprecated builtins' ' + test_cmp expect actual ' +cannot_alias_regular_builtin () { 4: 6bdcaf7f80f = 5: 2f78ab2e28c you-still-use-that??: help the user help themselves 5: 58de9767b22 ! 6: 34443066645 whatchanged: tell users the git-log(1) equivalent @@ Metadata Author: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Commit message ## - whatchanged: tell users the git-log(1) equivalent + whatchanged: hint about git-log(1) and aliasing There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. - Tell them what options to plug into git-log(1). That template produces - almost the same output[3] and is arguably a plug-in replacement. - Concretely, add an optional `hint` argument so that we can use it right - after the initial error line. + Tell them what options to plug into git-log(1), either as a replacement + command or as an alias.[3] That template produces almost the same + output[4] and is arguably a plug-in replacement. Concretely, add + an optional `hint` argument so that we can use it right after the + initial error line. Also mention the same concrete options in the documentation while we’re at it. @@ Commit message • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally - [3]: You only get different outputs if you happen to have empty + [3]: We allow aliasing deprecated builtins now for people who are very + used to the command name or just like it a lot + [4]: You only get different outputs if you happen to have empty commits (no changes)[4] - [4]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ + [5]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## + v5: + + Mention the aliasing hint in the commit message. + v3: Add an alias hint now that that is possible. Also prefix each hint-line 6: 407b430d02c = 7: b0aabd793f0 whatchanged: remove not-even-shorter clause 7: fee752d2fb0 = 8: 5021647c245 BreakingChanges: remove claim about whatchanged reports base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0 -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 1/8] git: add `deprecated` category to --list-cmds 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 2/8] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk ` (8 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> With 145 builtin commands (according to `git --list-cmds=builtins`), users are probably not keeping on top of which ones (if any) are deprecated. Let’s expand the experimental `--list-cmds`[1] to allow users and programs to query for this information. We will also use this in an upcoming commit to implement `is_deprecated_command`. [1]: Using something which is experimental to query for deprecations is perhaps not the most ideal approach, but it is simple to implement and better than having to scan the documentation Acked-by: Patrick Steinhardt <ps@pks.im> Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5: Add back the `BUG` check from v3 because I think it makes sense to only populate one of the two options. Link: https://lore.kernel.org/git/cover.1757345711.git.code@khaugsbakk.name/T/#m922b852384911511c45afd458051f52b50dce62f v4: Incorporate Patrick’s suggestions about the for-loop refactor and formatting the overlong lines. Now drop the function doc since it doesn’t apply anymore. Also adjust the commit message now that we use it in the C source in an upcoming commit, not just/only as an assert-helper (in an upcoming commit). v3 (new): This is something I wanted to submit independently until the point about aliasing builtins was brought up.[1] It will help (in a small way) with the upcoming patch “git: allow alias-shadowing deprecated builtins”. By the way: should `command-list.txt` be updated in some way (I didn’t know what way?) 🔗 1: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#mee19f8d39572f9021f9d3000758e87b6c32c967c Documentation/git.adoc | 3 ++- git.c | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4d..a2f0838b168 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -219,7 +219,8 @@ If you just want to run git as if it was started in `<path>` then use List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options), main (all commands in libexec directory), + parse-options), deprecated (deprecated builtins), + main (all commands in libexec directory), others (all other commands in `$PATH` that have git- prefix), list-<category> (see categories in command-list.txt), nohelpers (exclude helper commands), alias and config diff --git a/git.c b/git.c index 83eac0aeab7..511efdf2056 100644 --- a/git.c +++ b/git.c @@ -28,6 +28,7 @@ #define NEED_WORK_TREE (1<<3) #define DELAY_PAGER_CONFIG (1<<4) #define NO_PARSEOPT (1<<5) /* parse-options is not used */ +#define DEPRECATED (1<<6) struct cmd_struct { const char *cmd; @@ -51,7 +52,9 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +static void list_builtins(struct string_list *list, + unsigned int include_option, + unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -88,7 +91,7 @@ static int list_cmds(const char *spec) int len = sep - spec; if (match_token(spec, len, "builtins")) - list_builtins(&list, 0); + list_builtins(&list, 0, 0); else if (match_token(spec, len, "main")) list_all_main_cmds(&list); else if (match_token(spec, len, "others")) @@ -99,6 +102,8 @@ static int list_cmds(const char *spec) list_aliases(&list); else if (match_token(spec, len, "config")) list_cmds_by_config(&list); + else if (match_token(spec, len, "deprecated")) + list_builtins(&list, DEPRECATED, 0); else if (len > 5 && !strncmp(spec, "list-", 5)) { struct strbuf sb = STRBUF_INIT; @@ -322,7 +327,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - list_builtins(&list, NO_PARSEOPT); + list_builtins(&list, 0, NO_PARSEOPT); for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); @@ -590,7 +595,7 @@ static struct cmd_struct commands[] = { { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, #ifndef WITH_BREAKING_CHANGES - { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED }, #endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -647,7 +652,7 @@ static struct cmd_struct commands[] = { { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, #ifndef WITH_BREAKING_CHANGES - { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED }, #endif { "worktree", cmd_worktree, RUN_SETUP }, { "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,11 +673,16 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, + unsigned int include_option, + unsigned int exclude_option) { + if (include_option && exclude_option) + BUG("'include_option' and 'exclude_option' are mutually exclusive"); for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) + if (include_option && !(commands[i].option & include_option)) + continue; + if (exclude_option && (commands[i].option & exclude_option)) continue; string_list_append(out, commands[i].cmd); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 2/8] git: move seen-alias bookkeeping into handle_alias(...) 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk ` (7 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> We are about to complicate the command handling by allowing *deprecated* builtins to be shadowed by aliases. We need to organize the code in order to facilitate that.[1] The code in the `while(1)` speculatively adds commands to the list before finding out if it’s an alias. Let’s instead move it inside `handle_alias(...)`—where it conceptually belongs anyway—and in turn only run this logic when we have found an alias.[2][3] [1]: We will do that with an additional call to `handle_alias(1)` inside the loop. *Not* moving this code leaves a blind spot; we will miss alias looping crafted via deprecated builtin names [2]: Also rename the list to a more descriptive name [3]: The error output `'<cmd1>' is aliased to '<cmd2>'` is used for the `<cmd2> -h` case. We will get one more (redundant) line of output in the case of alias looping; that is covered in the test “looping aliases - deprecated builtins” in the next commit Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5 (new): Do a preliminary code movement in order to avoid loop aliasing in the specific case of alias-shadowing deprecated builtins. Link: https://lore.kernel.org/git/20250911204302.GA1907101@coredump.intra.peff.net/ As noted in footnote 3: you get one more line of output before the loop aliasing is detected (and see the next commit): 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' 'whatchanged' is aliased to 'pack-redundant' fatal: alias loop detected: expansion of 'whatchanged' does not terminate: whatchanged <== pack-redundant ==> This is an informational message specifically for `<git cmd> -h`. This output can be gotten after the next commit. The output in this case is very incidental: 1. You are aliasing deprecated commands in a chain 2. You are using `-h` 3. You are going to get caught by the alias loop checker git.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/git.c b/git.c index 511efdf2056..f9c2d8c8d86 100644 --- a/git.c +++ b/git.c @@ -365,7 +365,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) return (*argv) - orig_argv; } -static int handle_alias(struct strvec *args) +static int handle_alias(struct strvec *args, struct string_list *expanded_aliases) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; @@ -376,6 +376,8 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { + struct string_list_item *seen; + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); @@ -423,6 +425,24 @@ static int handle_alias(struct strvec *args) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); + seen = unsorted_string_list_lookup(expanded_aliases, args->v[0]); + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < expanded_aliases->nr; i++) { + struct string_list_item *item = &expanded_aliases->items[i]; + + strbuf_addf(&sb, "\n %s", item->string); + if (item == seen) + strbuf_addstr(&sb, " <=="); + else if (i == expanded_aliases->nr - 1) + strbuf_addstr(&sb, " ==>"); + } + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); + } + + string_list_append(expanded_aliases, args->v[0]); + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); @@ -806,8 +826,7 @@ static void execv_dashed_external(const char **argv) static int run_argv(struct strvec *args) { int done_alias = 0; - struct string_list cmd_list = STRING_LIST_INIT_DUP; - struct string_list_item *seen; + struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { /* @@ -859,35 +878,17 @@ static int run_argv(struct strvec *args) /* .. then try the external ones */ execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); - if (seen) { - struct strbuf sb = STRBUF_INIT; - for (size_t i = 0; i < cmd_list.nr; i++) { - struct string_list_item *item = &cmd_list.items[i]; - - strbuf_addf(&sb, "\n %s", item->string); - if (item == seen) - strbuf_addstr(&sb, " <=="); - else if (i == cmd_list.nr - 1) - strbuf_addstr(&sb, " ==>"); - } - die(_("alias loop detected: expansion of '%s' does" - " not terminate:%s"), cmd_list.items[0].string, sb.buf); - } - - string_list_append(&cmd_list, args->v[0]); - /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having * alias.log = show */ - if (!handle_alias(args)) + if (!handle_alias(args, &expanded_aliases)) break; done_alias = 1; } - string_list_clear(&cmd_list, 0); + string_list_clear(&expanded_aliases, 0); return done_alias; } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 3/8] git: allow alias-shadowing deprecated builtins 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 2/8] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk ` (6 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> git-whatchanged(1) is deprecated and you need to pass `--i-still-use-this` in order to force it to work as before. There are two affected users, or usages: 1. people who use the command in scripts; and 2. people who are used to using it interactively. For (1) the replacement is straightforward.[1] But people in (2) might like the name or be really used to typing it.[3] An obvious first thought is to suggest aliasing `whatchanged` to the git-log(1) equivalent.[1] But this doesn’t work and is awkward since you cannot shadow builtins via aliases. Now you are left in an uncomfortable limbo; your alias won’t work until the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be shadowed by aliases.[4] The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all deprecated commands the same. [1]: git log --raw --no-merges With a minor caveat: you get different outputs if you happen to have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ [4]: The test “looping aliases - deprecated builtins” covers the case of the extra output mentioned in footnote number 3 of the previous commit Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5: Fix a leak caused by calling `alias_lookup(...)` without freeing the return value by not calling that function. Add tests for deprecated builtins for infinite alias looping as well as simple chaining. This is to exercise all code paths that we could think of. Expand on the infinite alias looping test on the whole error output (compared to the one above). Link this change to the previous patch/commit by mentioning it in a footnote. See the last footnote and the note on the previous commit/patch. I have opted not to get rid of this redundant line. But this documents the change and future changes that affect it will trigger this assertion (say if they remove the redundant line). v4: Better `is_deprecated_command` implementation. v3 (new): Prerequisite for telling the user that they can alias `whatchanged` to `git log --raw --no-merged`. Link: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#md434b0968f499263262fb1805d82b788b8349d9a > I think that is good advice, but... it won't do anything until we > actually drop the whatchanged command, since until then we'll refuse to > override the command (even the crippled --i-still-use-this one). > > We'd need something like the patch here: ❦ The test_file_not_empty expect is here because the git(1) command could fail. Make sure that it did indeed output anyhing on stdout. (Or if a previous redirect to `expect` outputted something it should be completely different to `actual` in any case) I don’t know if this is just a waste. Documentation/config/alias.adoc | 3 ++- git.c | 17 ++++++++++++++ t/t0014-alias.sh | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Documentation/config/alias.adoc b/Documentation/config/alias.adoc index 2c5db0ad842..3c8fab3a95c 100644 --- a/Documentation/config/alias.adoc +++ b/Documentation/config/alias.adoc @@ -3,7 +3,8 @@ alias.*:: after defining `alias.last = cat-file commit HEAD`, the invocation `git last` is equivalent to `git cat-file commit HEAD`. To avoid confusion and troubles with script usage, aliases that - hide existing Git commands are ignored. Arguments are split by + hide existing Git commands are ignored except for deprecated + commands. Arguments are split by spaces, the usual shell quoting and escaping are supported. A quote pair or a backslash can be used to quote them. + diff --git a/git.c b/git.c index f9c2d8c8d86..1310363e5c4 100644 --- a/git.c +++ b/git.c @@ -823,12 +823,29 @@ static void execv_dashed_external(const char **argv) exit(128); } +static int is_deprecated_command(const char *cmd) +{ + struct cmd_struct *builtin = get_builtin(cmd); + return builtin && (builtin->option & DEPRECATED); +} + static int run_argv(struct strvec *args) { int done_alias = 0; struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { + /* + * Allow deprecated commands to be overridden by aliases. This + * creates a seamless path forward for people who want to keep + * using the name after it is gone, but want to skip the + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && + handle_alias(args, &expanded_aliases)) { + done_alias = 1; + continue; + } /* * If we tried alias and futzed with our environment, * it no longer is safe to invoke builtins directly in diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 854d59ec58c..2f71c3265f0 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -27,6 +27,21 @@ test_expect_success 'looping aliases - internal execution' ' test_grep "^fatal: alias loop detected: expansion of" output ' +test_expect_success 'looping aliases - deprecated builtins' ' + test_config alias.whatchanged pack-redundant && + test_config alias.pack-redundant whatchanged && + cat >expect <<-EOF && + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: + whatchanged <== + pack-redundant ==> + EOF + test_must_fail git whatchanged -h 2>actual && + test_cmp expect actual +' + # This test is disabled until external loops are fixed, because would block # the test suite for a full minute. # @@ -55,4 +70,30 @@ test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' +can_alias_deprecated_builtin () { + cmd="$1" && + # some git(1) commands will fail for `-h` (the case for + # git-status as of 2025-09-07) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'can alias-shadow deprecated builtins' ' + for cmd in $(git --list-cmds=deprecated) + do + can_alias_deprecated_builtin "$cmd" || return 1 + done +' + +test_expect_success 'can alias-shadow via two deprecated builtins' ' + # some git(1) commands will fail... (see above) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias.whatchanged=pack-redundant \ + -c alias.pack-redundant=status whatchanged -h >actual && + test_cmp expect actual +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 4/8] t0014: test shadowing of aliases for a sample of builtins 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (2 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk ` (5 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The previous commit added tests for shadowing deprecated builtins. Let’s make the test suite more complete by exercising a sample of the builtins and in turn test the documentation for git-config(1): To avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored except for deprecated commands. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): Only a sample of builtins since the test file takes about 600ms longer if I test all of them. t/t0014-alias.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 2f71c3265f0..1ac739a2737 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -96,4 +96,21 @@ test_expect_success 'can alias-shadow via two deprecated builtins' ' test_cmp expect actual ' +cannot_alias_regular_builtin () { + cmd="$1" && + # some git(1) commands will fail... (see above) + test_might_fail git "$cmd" -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'cannot alias-shadow a sample of regular builtins' ' + for cmd in grep check-ref-format interpret-trailers \ + checkout-index fast-import diagnose rev-list prune + do + cannot_alias_regular_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 5/8] you-still-use-that??: help the user help themselves 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (3 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 6/8] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk ` (4 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: www.git-scm.com has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: I had second thoughts about the bullet point about send-an-email. Change it to the one Eric Sunshine proposed;[1] make sure to spell out that you can send an email conditioned on not finding a suitable replacement. Also change the area to something more pointed. And also use a clear URL to refer to www.git-scm.com. [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm v1: An alternative to linking to www.git-scm.com is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..35dc57eb07e 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,24 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 6/8] whatchanged: hint about git-log(1) and aliasing 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (4 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (3 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1), either as a replacement command or as an alias.[3] That template produces almost the same output[4] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally [3]: We allow aliasing deprecated builtins now for people who are very used to the command name or just like it a lot [4]: You only get different outputs if you happen to have empty commits (no changes)[4] [5]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5: Mention the aliasing hint in the commit message. v3: Add an alias hint now that that is possible. Also prefix each hint-line with `hint: `. v2: Review found a whitespace error in the prev. patch version. I found a broken footnote and wanted to expand on the last footnote. • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 8 +++++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..1d1e6e9130a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -543,7 +543,13 @@ int cmd_whatchanged(int argc, cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + "hint:\tgit log <opts> --raw --no-merges\n" + "hint: Or make an alias:\n" + "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 35dc57eb07e..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -395,7 +401,7 @@ NORETURN void you_still_use_that(const char *command_name) " know that you still use this command and were unable\n" " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 7/8] whatchanged: remove not-even-shorter clause 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (5 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 6/8] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk ` (2 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v5 8/8] BreakingChanges: remove claim about whatchanged reports 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (6 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-09-14 19:49 ` kristofferhaugsbakk 2025-09-15 19:19 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-14 19:49 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.16.gcd94ab5bf81 ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (7 preceding siblings ...) 2025-09-14 19:49 ` [PATCH v5 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-09-15 19:19 ` Junio C Hamano 2025-09-16 20:47 ` Kristoffer Haugsbakk 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk 9 siblings, 1 reply; 102+ messages in thread From: Junio C Hamano @ 2025-09-15 19:19 UTC (permalink / raw) To: kristofferhaugsbakk Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt kristofferhaugsbakk@fastmail.com writes: > § Changes in v5 > > Fix the leak that Peff found (with Peff’s suggestion). Also fix (with > Peff’s help) a regression where you were able to get into an infinite > alias loop specifically when using deprecated builtin names. When merged to 'seen' and run with WITH_BREAKING_CHANGES=YesPlease, looping alias test would chage the behaviour, and the test needs to be prepared for it, I think. Here is how t0014 fails expecting success of 0014.4 'looping aliases - deprecated builtins': test_config alias.whatchanged pack-redundant && test_config alias.pack-redundant whatchanged && cat >expect <<-EOF && ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: whatchanged <== pack-redundant ==> EOF test_must_fail git whatchanged -h 2>actual && test_cmp expect actual --- expect 2025-09-15 19:16:26.340366359 +0000 +++ actual 2025-09-15 19:16:26.360366313 +0000 @@ -1,6 +1 @@ -'whatchanged' is aliased to 'pack-redundant' -'pack-redundant' is aliased to 'whatchanged' -'whatchanged' is aliased to 'pack-redundant' -fatal: alias loop detected: expansion of 'whatchanged' does not terminate: - whatchanged <== - pack-redundant ==> +fatal: cannot handle whatchanged as a builtin not ok 4 - looping aliases - deprecated builtins ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-15 19:19 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano @ 2025-09-16 20:47 ` Kristoffer Haugsbakk 2025-09-16 23:24 ` Jeff King 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-16 20:47 UTC (permalink / raw) To: Junio C Hamano, Kristoffer Haugsbakk Cc: git, Eric Sunshine, Jeff King, Patrick Steinhardt On Mon, Sep 15, 2025, at 21:19, Junio C Hamano wrote: > kristofferhaugsbakk@fastmail.com writes: > >> § Changes in v5 >> >> Fix the leak that Peff found (with Peff’s suggestion). Also fix (with >> Peff’s help) a regression where you were able to get into an infinite >> alias loop specifically when using deprecated builtin names. > > When merged to 'seen' and run with WITH_BREAKING_CHANGES=YesPlease, > looping alias test would chage the behaviour, and the test needs to > be prepared for it, I think. Here is how t0014 fails > > expecting success of 0014.4 'looping aliases - deprecated builtins': > test_config alias.whatchanged pack-redundant && > test_config alias.pack-redundant whatchanged && > cat >expect <<-EOF && > ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} > ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} > ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} > fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} > does not terminate: > whatchanged <== > pack-redundant ==> > EOF > test_must_fail git whatchanged -h 2>actual && > test_cmp expect actual > > --- expect 2025-09-15 19:16:26.340366359 +0000 > +++ actual 2025-09-15 19:16:26.360366313 +0000 > @@ -1,6 +1 @@ > -'whatchanged' is aliased to 'pack-redundant' > -'pack-redundant' is aliased to 'whatchanged' > -'whatchanged' is aliased to 'pack-redundant' > -fatal: alias loop detected: expansion of 'whatchanged' does not terminate: > - whatchanged <== > - pack-redundant ==> > +fatal: cannot handle whatchanged as a builtin > not ok 4 - looping aliases - deprecated builtins Thanks. This is (maybe you surmise or know already but) a problem when on the branch itself as well. I did some compiling `WITH_BREAKING_CHANGES=YesPlease` and it seems that 07572f220a8 (whatchanged: remove when built with WITH_BREAKING_CHANGES, 2025-05-12) made it a hard error to call `whatchanged` after its death: $ ./bin-wrappers/git whatchanged fatal: cannot handle whatchanged as a builtin This seems fine, although I would have expected it to say something more neutral like “command not found”. What I don’t understand though is this: $ ./bin-wrappers/git -c alias.whatchanged=status whatchanged fatal: cannot handle whatchanged as a builtin People have been saying that people can at least alias `whatchanged` to `log <something>` and then it will work after the removal. But now that it has been removed (according to the commit message) its spirit lives on and prevents reusing the name? Am I missing something here? ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-16 20:47 ` Kristoffer Haugsbakk @ 2025-09-16 23:24 ` Jeff King 2025-09-17 15:41 ` Kristoffer Haugsbakk 0 siblings, 1 reply; 102+ messages in thread From: Jeff King @ 2025-09-16 23:24 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Junio C Hamano, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Tue, Sep 16, 2025 at 10:47:58PM +0200, Kristoffer Haugsbakk wrote: > Thanks. This is (maybe you surmise or know already but) a > problem when on the branch itself as well. I did some compiling > `WITH_BREAKING_CHANGES=YesPlease` and it seems that 07572f220a8 > (whatchanged: remove when built with WITH_BREAKING_CHANGES, 2025-05-12) > made it a hard error to call `whatchanged` after its death: > > $ ./bin-wrappers/git whatchanged > fatal: cannot handle whatchanged as a builtin > > This seems fine, although I would have expected it to say something more > neutral like “command not found”. I think the breaking-changes code for whatchanged did not update the Makefile appropriately. If I build with that flag: [make sure it is not here] $ rm git-whatchanged [now build] $ make WITH_BREAKING_CHANGES=YesPlease [...] BUILTIN git-whatchanged SUBDIR templates $ ls -l git-whatchanged -rwxrwxr-x 140 peff peff 12104368 Sep 16 19:15 git-whatchanged* So we have linked it in the usual way we do for builtins, so that git-whatchanged would "work". But of course since it is not in the builtin table, it does not: $ ./git-whatchanged fatal: cannot handle whatchanged as a builtin And then because it exists in the exec-path, "git whatchanged" thinks that it can run the dashed form, so it produces the same message. We probably need this: diff --git a/Makefile b/Makefile index e11340c1ae..9311da5bb1 100644 --- a/Makefile +++ b/Makefile @@ -883,7 +883,9 @@ BUILT_INS += git-stage$X BUILT_INS += git-status$X BUILT_INS += git-switch$X BUILT_INS += git-version$X +ifndef WITH_BREAKING_CHANGES BUILT_INS += git-whatchanged$X +endif # what 'all' will build but not install in gitexecdir OTHER_PROGRAMS += git$X but annoyingly an old build will leave git-whatchanged in place and cause the same confusion. And git-status won't even notice that it's leftover because .gitignore mentions it. But we can't drop it from .gitignore until the non-breaking-changes builds go away entirely. Yuck. > What I don’t understand though is this: > > $ ./bin-wrappers/git -c alias.whatchanged=status whatchanged > fatal: cannot handle whatchanged as a builtin > > People have been saying that people can at least alias `whatchanged` to > `log <something>` and then it will work after the removal. But now that > it has been removed (according to the commit message) its spirit lives > on and prevents reusing the name? I'd have thought the alias took precedence over the stale executable file. But it can't, because "whatchanged" is no longer marked as deprecated in the builtin list. Because it's not in the builtin list at all! So it is just a "normal" non-deprecated external command from the perspective of git.c, and you are not allowed to override it. So I think the alias code is working as expected, but the stale file is causing the same confusion as above. Deleting it makes everything work. -Peff ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-16 23:24 ` Jeff King @ 2025-09-17 15:41 ` Kristoffer Haugsbakk 2025-09-17 16:25 ` Junio C Hamano 0 siblings, 1 reply; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-17 15:41 UTC (permalink / raw) To: Jeff King Cc: Junio C Hamano, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 17, 2025, at 01:24, Jeff King wrote: > On Tue, Sep 16, 2025 at 10:47:58PM +0200, Kristoffer Haugsbakk wrote: > >> Thanks. This is (maybe you surmise or know already but) a >> problem when on the branch itself as well. I did some compiling >> `WITH_BREAKING_CHANGES=YesPlease` and it seems that 07572f220a8 >> (whatchanged: remove when built with WITH_BREAKING_CHANGES, 2025-05-12) >> made it a hard error to call `whatchanged` after its death: >> >> $ ./bin-wrappers/git whatchanged >> fatal: cannot handle whatchanged as a builtin >> >> This seems fine, although I would have expected it to say something more >> neutral like “command not found”. > > I think the breaking-changes code for whatchanged did not update the > Makefile appropriately. If I build with that flag: > > [make sure it is not here] > $ rm git-whatchanged > > [now build] > $ make WITH_BREAKING_CHANGES=YesPlease > [...] > BUILTIN git-whatchanged > SUBDIR templates > > $ ls -l git-whatchanged > -rwxrwxr-x 140 peff peff 12104368 Sep 16 19:15 git-whatchanged* > > So we have linked it in the usual way we do for builtins, so that > git-whatchanged would "work". But of course since it is not in the > builtin table, it does not: > > $ ./git-whatchanged > fatal: cannot handle whatchanged as a builtin > > And then because it exists in the exec-path, "git whatchanged" thinks > that it can run the dashed form, so it produces the same message. > > We probably need this: > > diff --git a/Makefile b/Makefile > index e11340c1ae..9311da5bb1 100644 > --- a/Makefile > +++ b/Makefile > @@ -883,7 +883,9 @@ BUILT_INS += git-stage$X > BUILT_INS += git-status$X > BUILT_INS += git-switch$X > BUILT_INS += git-version$X > +ifndef WITH_BREAKING_CHANGES > BUILT_INS += git-whatchanged$X > +endif > > # what 'all' will build but not install in gitexecdir > OTHER_PROGRAMS += git$X > > but annoyingly an old build will leave git-whatchanged in place and > cause the same confusion. And git-status won't even notice that it's > leftover because .gitignore mentions it. But we can't drop it from > .gitignore until the non-breaking-changes builds go away entirely. Yuck. > >> What I don’t understand though is this: >> >> $ ./bin-wrappers/git -c alias.whatchanged=status whatchanged >> fatal: cannot handle whatchanged as a builtin >> >> People have been saying that people can at least alias `whatchanged` to >> `log <something>` and then it will work after the removal. But now that >> it has been removed (according to the commit message) its spirit lives >> on and prevents reusing the name? > > I'd have thought the alias took precedence over the stale executable > file. But it can't, because "whatchanged" is no longer marked as > deprecated in the builtin list. Because it's not in the builtin list at > all! So it is just a "normal" non-deprecated external command from the > perspective of git.c, and you are not allowed to override it. > > So I think the alias code is working as expected, but the stale file is > causing the same confusion as above. Deleting it makes everything work. That’s great, I think I understand. It is my understanding that the change to `Makefile` is needed for the test to not break when `WITH_BREAKING_CHANGES` is active. Well I tried now with a *make* after git fsck -d -x -f And it fails the same way. So I’ll just steal this change... (as well) and include it in preparations for the others. (Thanks so much!) ----- Draft of the commit message: ----- Makefile: don’t add whatchanged after it has been removed 07572f220a8 (whatchanged: remove when built with WITH_BREAKING_CHANGES, 2025-05-12) set up the removal of git-whatchanged(1) when `WITH_BREAKING_CHANGES` is active. Part of that work was removing it from `commands` in `git.c`. But the the Makefile still lists it as a builtin . That leaves it in the limbo of being linked but not being callable; you get the generic error about not being able to call it as a *builtin*: $ git whatchanged fatal: cannot handle whatchanged as a builtin instead of the expected: $ git whatchanged git: 'whatchanged' is not a git command. See 'git --help'. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting 2025-09-17 15:41 ` Kristoffer Haugsbakk @ 2025-09-17 16:25 ` Junio C Hamano 0 siblings, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-09-17 16:25 UTC (permalink / raw) To: Kristoffer Haugsbakk Cc: Jeff King, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt "Kristoffer Haugsbakk" <code@khaugsbakk.name> writes: > Draft of the commit message: > > ----- > > Makefile: don’t add whatchanged after it has been removed > > 07572f220a8 (whatchanged: remove when built with WITH_BREAKING_CHANGES, > 2025-05-12) set up the removal of git-whatchanged(1) when > `WITH_BREAKING_CHANGES` is active. Part of that work was removing it > from `commands` in `git.c`. But the the Makefile still lists it as a > builtin . That leaves it in the limbo of being linked but not being > callable; you get the generic error about not being able to call it as > a *builtin*: > > $ git whatchanged > fatal: cannot handle whatchanged as a builtin > > instead of the expected: > > $ git whatchanged > git: 'whatchanged' is not a git command. See 'git --help'. A change very well thought out. Thanks for fixing my earlier breakage. ^ permalink raw reply [flat|nested] 102+ messages in thread
* [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk ` (8 preceding siblings ...) 2025-09-15 19:19 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 1/9] Makefile: don’t add whatchanged after it has been removed kristofferhaugsbakk ` (9 more replies) 9 siblings, 10 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Based on the recent i-still-use-that reports about whatchanged, improve the error reporting with this command in mind: 1. Give more possible actions instead of just (only) asking them to send an email 2. Hint how to replace their git-whatchanged(1) use with git-log(1) or an alias `whatchanged` (you can alias deprecated commands now) 3. Minor documentation changes 4. Add `deprecated` to `git --list-cmds` 5. (new in v6) Don’t list git-whatchanged(1) as a builtin when `WITH_BREAKING_CHANGES` § What the errors now look like $ ./git whatchanged 'git whatchanged' is nominated for removal. hint: You can replace 'git whatchanged <opts>' with: hint: git log <opts> --raw --no-merges hint: Or make an alias: hint: git config set --global alias.whatchanged 'log --raw --no-merges' If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20whatchanged - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this $ ./git pack-redundant 'git pack-redundant' is nominated for removal. If you still use this command, here's what you can do: - read https://git-scm.com/docs/BreakingChanges.html - check if anyone has discussed this on the mailing list and if they came up with something that can help you: https://lore.kernel.org/git/?q=git%20pack-redundant - send an email to <git@vger.kernel.org> to let us know that you still use this command and were unable to determine a suitable replacement fatal: refusing to run without --i-still-use-this § Changes in v6 Use Peff’s patch to get rid of “the extra output”.[1] Update commit messages to not mention that. Also use another fix from Peff (patch 1); don’t list git-whatchanged(1) as a builtin when `WITH_BREAKING_CHANGES`. 🔗 1: https://lore.kernel.org/git/cover.1757446619.git.code@khaugsbakk.name/T/#mb3ac9c32c8527675a1f9cdf7709f2c74b3dd2a6c Thanks Kristoffer Haugsbakk (9): Makefile: don’t add whatchanged after it has been removed git: add `deprecated` category to --list-cmds git: move seen-alias bookkeeping into handle_alias(...) git: allow alias-shadowing deprecated builtins t0014: test shadowing of aliases for a sample of builtins you-still-use-that??: help the user help themselves whatchanged: hint about git-log(1) and aliasing whatchanged: remove not-even-shorter clause BreakingChanges: remove claim about whatchanged reports Documentation/BreakingChanges.adoc | 2 +- Documentation/config/alias.adoc | 3 +- Documentation/git-whatchanged.adoc | 8 ++- Documentation/git.adoc | 3 +- Makefile | 2 + builtin/log.c | 8 ++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- git.c | 91 ++++++++++++++++++++---------- t/t0014-alias.sh | 57 +++++++++++++++++++ usage.c | 33 ++++++++--- 11 files changed, 165 insertions(+), 46 deletions(-) Interdiff against v5: diff --git a/Makefile b/Makefile index e11340c1ae7..9311da5bb15 100644 --- a/Makefile +++ b/Makefile @@ -883,7 +883,9 @@ BUILT_INS += git-stage$X BUILT_INS += git-status$X BUILT_INS += git-switch$X BUILT_INS += git-version$X +ifndef WITH_BREAKING_CHANGES BUILT_INS += git-whatchanged$X +endif # what 'all' will build but not install in gitexecdir OTHER_PROGRAMS += git$X diff --git a/git.c b/git.c index 1310363e5c4..8c85da84c30 100644 --- a/git.c +++ b/git.c @@ -425,7 +425,10 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); - seen = unsorted_string_list_lookup(expanded_aliases, args->v[0]); + string_list_append(expanded_aliases, alias_command); + seen = unsorted_string_list_lookup(expanded_aliases, + new_argv[0]); + if (seen) { struct strbuf sb = STRBUF_INIT; for (size_t i = 0; i < expanded_aliases->nr; i++) { @@ -441,8 +444,6 @@ static int handle_alias(struct strvec *args, struct string_list *expanded_aliase " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); } - string_list_append(expanded_aliases, args->v[0]); - trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 1ac739a2737..07a53e7366e 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -33,7 +33,6 @@ test_expect_success 'looping aliases - deprecated builtins' ' cat >expect <<-EOF && ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} - ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: whatchanged <== pack-redundant ==> Range-diff against v5: -: ----------- > 1: 8b34edf876e Makefile: don’t add whatchanged after it has been removed 1: 13682553018 = 2: c10a24018ce git: add `deprecated` category to --list-cmds 2: 7f82ef6e96f ! 3: 90e35bfc063 git: move seen-alias bookkeeping into handle_alias(...) @@ Commit message The code in the `while(1)` speculatively adds commands to the list before finding out if it’s an alias. Let’s instead move it inside `handle_alias(...)`—where it conceptually belongs anyway—and in turn - only run this logic when we have found an alias.[2][3] + only run this logic when we have found an alias.[2] [1]: We will do that with an additional call to `handle_alias(1)` inside the loop. *Not* moving this code leaves a blind spot; we will miss alias looping crafted via deprecated builtin names [2]: Also rename the list to a more descriptive name - [3]: The error output `'<cmd1>' is aliased to '<cmd2>'` is used for the - `<cmd2> -h` case. We will get one more (redundant) line of output - in the case of alias looping; that is covered in the test “looping - aliases - deprecated builtins” in the next commit Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## + v6: + + Apply Peff’s patch[1] in order to get rid of the extra output line. + + Drop the footnote from the commit message now that we don’t have that + problem any more. + + 🔗 1: https://lore.kernel.org/git/cover.1757446619.git.code@khaugsbakk.name/T/#mb3ac9c32c8527675a1f9cdf7709f2c74b3dd2a6c + v5 (new): Do a preliminary code movement in order to avoid loop aliasing in the @@ git.c: static int handle_alias(struct strvec *args) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); -+ seen = unsorted_string_list_lookup(expanded_aliases, args->v[0]); ++ string_list_append(expanded_aliases, alias_command); ++ seen = unsorted_string_list_lookup(expanded_aliases, ++ new_argv[0]); ++ + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < expanded_aliases->nr; i++) { @@ git.c: static int handle_alias(struct strvec *args) + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); + } -+ -+ string_list_append(expanded_aliases, args->v[0]); + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", 3: 4bfe36cccd0 ! 4: 2cac74d731c git: allow alias-shadowing deprecated builtins @@ Commit message the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be - shadowed by aliases.[4] + shadowed by aliases. The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all @@ Commit message have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ - [4]: The test “looping aliases - deprecated builtins” covers the - case of the extra output mentioned in footnote number 3 of the - previous commit Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> ## Notes (series) ## + v6: + + Drop footnote now that we don’t have the “extra output line” problem. + v5: Fix a leak caused by calling `alias_lookup(...)` without freeing the @@ t/t0014-alias.sh: test_expect_success 'looping aliases - internal execution' ' + cat >expect <<-EOF && + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} -+ ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: + whatchanged <== + pack-redundant ==> 4: a04c6ae968e = 5: 3576439add5 t0014: test shadowing of aliases for a sample of builtins 5: 2f78ab2e28c = 6: 7499890ed49 you-still-use-that??: help the user help themselves 6: 34443066645 = 7: b0831e8967a whatchanged: hint about git-log(1) and aliasing 7: b0aabd793f0 = 8: 2f281944fbf whatchanged: remove not-even-shorter clause 8: 5021647c245 = 9: 7dc3d03d626 BreakingChanges: remove claim about whatchanged reports base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0 -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 1/9] Makefile: don’t add whatchanged after it has been removed 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 2/9] git: add `deprecated` category to --list-cmds kristofferhaugsbakk ` (8 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> 07572f220a8 (whatchanged: remove when built with WITH_BREAKING_CHANGES, 2025-05-12) set up the removal of git-whatchanged(1) when `WITH_BREAKING_CHANGES` is active. Part of that work was removing it from `commands` in `git.c`. But the Makefile still lists it as a builtin. That leaves it in the limbo of being linked but not being callable; you get the generic error about not being able to call it as a *builtin*: $ git whatchanged fatal: cannot handle whatchanged as a builtin instead of the expected: $ git whatchanged git: 'whatchanged' is not a git command. See 'git --help'. Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v6 (new): Link/Source: https://lore.kernel.org/git/cover.1757446619.git.code@khaugsbakk.name/T/#mfa023b1c1626df68d25714a5981d8662a66199dc Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index e11340c1ae7..9311da5bb15 100644 --- a/Makefile +++ b/Makefile @@ -883,7 +883,9 @@ BUILT_INS += git-stage$X BUILT_INS += git-status$X BUILT_INS += git-switch$X BUILT_INS += git-version$X +ifndef WITH_BREAKING_CHANGES BUILT_INS += git-whatchanged$X +endif # what 'all' will build but not install in gitexecdir OTHER_PROGRAMS += git$X -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 2/9] git: add `deprecated` category to --list-cmds 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 1/9] Makefile: don’t add whatchanged after it has been removed kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 3/9] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk ` (7 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> With 145 builtin commands (according to `git --list-cmds=builtins`), users are probably not keeping on top of which ones (if any) are deprecated. Let’s expand the experimental `--list-cmds`[1] to allow users and programs to query for this information. We will also use this in an upcoming commit to implement `is_deprecated_command`. [1]: Using something which is experimental to query for deprecations is perhaps not the most ideal approach, but it is simple to implement and better than having to scan the documentation Acked-by: Patrick Steinhardt <ps@pks.im> Helped-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5: Add back the `BUG` check from v3 because I think it makes sense to only populate one of the two options. Link: https://lore.kernel.org/git/cover.1757345711.git.code@khaugsbakk.name/T/#m922b852384911511c45afd458051f52b50dce62f v4: Incorporate Patrick’s suggestions about the for-loop refactor and formatting the overlong lines. Now drop the function doc since it doesn’t apply anymore. Also adjust the commit message now that we use it in the C source in an upcoming commit, not just/only as an assert-helper (in an upcoming commit). v3 (new): This is something I wanted to submit independently until the point about aliasing builtins was brought up.[1] It will help (in a small way) with the upcoming patch “git: allow alias-shadowing deprecated builtins”. By the way: should `command-list.txt` be updated in some way (I didn’t know what way?) 🔗 1: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#mee19f8d39572f9021f9d3000758e87b6c32c967c Documentation/git.adoc | 3 ++- git.c | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4d..a2f0838b168 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -219,7 +219,8 @@ If you just want to run git as if it was started in `<path>` then use List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options), main (all commands in libexec directory), + parse-options), deprecated (deprecated builtins), + main (all commands in libexec directory), others (all other commands in `$PATH` that have git- prefix), list-<category> (see categories in command-list.txt), nohelpers (exclude helper commands), alias and config diff --git a/git.c b/git.c index 83eac0aeab7..511efdf2056 100644 --- a/git.c +++ b/git.c @@ -28,6 +28,7 @@ #define NEED_WORK_TREE (1<<3) #define DELAY_PAGER_CONFIG (1<<4) #define NO_PARSEOPT (1<<5) /* parse-options is not used */ +#define DEPRECATED (1<<6) struct cmd_struct { const char *cmd; @@ -51,7 +52,9 @@ const char git_more_info_string[] = static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +static void list_builtins(struct string_list *list, + unsigned int include_option, + unsigned int exclude_option); static void exclude_helpers_from_list(struct string_list *list) { @@ -88,7 +91,7 @@ static int list_cmds(const char *spec) int len = sep - spec; if (match_token(spec, len, "builtins")) - list_builtins(&list, 0); + list_builtins(&list, 0, 0); else if (match_token(spec, len, "main")) list_all_main_cmds(&list); else if (match_token(spec, len, "others")) @@ -99,6 +102,8 @@ static int list_cmds(const char *spec) list_aliases(&list); else if (match_token(spec, len, "config")) list_cmds_by_config(&list); + else if (match_token(spec, len, "deprecated")) + list_builtins(&list, DEPRECATED, 0); else if (len > 5 && !strncmp(spec, "list-", 5)) { struct strbuf sb = STRBUF_INIT; @@ -322,7 +327,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - list_builtins(&list, NO_PARSEOPT); + list_builtins(&list, 0, NO_PARSEOPT); for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); @@ -590,7 +595,7 @@ static struct cmd_struct commands[] = { { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, #ifndef WITH_BREAKING_CHANGES - { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED }, #endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -647,7 +652,7 @@ static struct cmd_struct commands[] = { { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, #ifndef WITH_BREAKING_CHANGES - { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED }, #endif { "worktree", cmd_worktree, RUN_SETUP }, { "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,11 +673,16 @@ int is_builtin(const char *s) return !!get_builtin(s); } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, + unsigned int include_option, + unsigned int exclude_option) { + if (include_option && exclude_option) + BUG("'include_option' and 'exclude_option' are mutually exclusive"); for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { - if (exclude_option && - (commands[i].option & exclude_option)) + if (include_option && !(commands[i].option & include_option)) + continue; + if (exclude_option && (commands[i].option & exclude_option)) continue; string_list_append(out, commands[i].cmd); } -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 3/9] git: move seen-alias bookkeeping into handle_alias(...) 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 1/9] Makefile: don’t add whatchanged after it has been removed kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 2/9] git: add `deprecated` category to --list-cmds kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 4/9] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk ` (6 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> We are about to complicate the command handling by allowing *deprecated* builtins to be shadowed by aliases. We need to organize the code in order to facilitate that.[1] The code in the `while(1)` speculatively adds commands to the list before finding out if it’s an alias. Let’s instead move it inside `handle_alias(...)`—where it conceptually belongs anyway—and in turn only run this logic when we have found an alias.[2] [1]: We will do that with an additional call to `handle_alias(1)` inside the loop. *Not* moving this code leaves a blind spot; we will miss alias looping crafted via deprecated builtin names [2]: Also rename the list to a more descriptive name Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v6: Apply Peff’s patch[1] in order to get rid of the extra output line. Drop the footnote from the commit message now that we don’t have that problem any more. 🔗 1: https://lore.kernel.org/git/cover.1757446619.git.code@khaugsbakk.name/T/#mb3ac9c32c8527675a1f9cdf7709f2c74b3dd2a6c v5 (new): Do a preliminary code movement in order to avoid loop aliasing in the specific case of alias-shadowing deprecated builtins. Link: https://lore.kernel.org/git/20250911204302.GA1907101@coredump.intra.peff.net/ As noted in footnote 3: you get one more line of output before the loop aliasing is detected (and see the next commit): 'whatchanged' is aliased to 'pack-redundant' 'pack-redundant' is aliased to 'whatchanged' 'whatchanged' is aliased to 'pack-redundant' fatal: alias loop detected: expansion of 'whatchanged' does not terminate: whatchanged <== pack-redundant ==> This is an informational message specifically for `<git cmd> -h`. This output can be gotten after the next commit. The output in this case is very incidental: 1. You are aliasing deprecated commands in a chain 2. You are using `-h` 3. You are going to get caught by the alias loop checker git.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/git.c b/git.c index 511efdf2056..ef1e7b205aa 100644 --- a/git.c +++ b/git.c @@ -365,7 +365,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) return (*argv) - orig_argv; } -static int handle_alias(struct strvec *args) +static int handle_alias(struct strvec *args, struct string_list *expanded_aliases) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; @@ -376,6 +376,8 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { + struct string_list_item *seen; + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); @@ -423,6 +425,25 @@ static int handle_alias(struct strvec *args) if (!strcmp(alias_command, new_argv[0])) die(_("recursive alias: %s"), alias_command); + string_list_append(expanded_aliases, alias_command); + seen = unsorted_string_list_lookup(expanded_aliases, + new_argv[0]); + + if (seen) { + struct strbuf sb = STRBUF_INIT; + for (size_t i = 0; i < expanded_aliases->nr; i++) { + struct string_list_item *item = &expanded_aliases->items[i]; + + strbuf_addf(&sb, "\n %s", item->string); + if (item == seen) + strbuf_addstr(&sb, " <=="); + else if (i == expanded_aliases->nr - 1) + strbuf_addstr(&sb, " ==>"); + } + die(_("alias loop detected: expansion of '%s' does" + " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); + } + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); @@ -806,8 +827,7 @@ static void execv_dashed_external(const char **argv) static int run_argv(struct strvec *args) { int done_alias = 0; - struct string_list cmd_list = STRING_LIST_INIT_DUP; - struct string_list_item *seen; + struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { /* @@ -859,35 +879,17 @@ static int run_argv(struct strvec *args) /* .. then try the external ones */ execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); - if (seen) { - struct strbuf sb = STRBUF_INIT; - for (size_t i = 0; i < cmd_list.nr; i++) { - struct string_list_item *item = &cmd_list.items[i]; - - strbuf_addf(&sb, "\n %s", item->string); - if (item == seen) - strbuf_addstr(&sb, " <=="); - else if (i == cmd_list.nr - 1) - strbuf_addstr(&sb, " ==>"); - } - die(_("alias loop detected: expansion of '%s' does" - " not terminate:%s"), cmd_list.items[0].string, sb.buf); - } - - string_list_append(&cmd_list, args->v[0]); - /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having * alias.log = show */ - if (!handle_alias(args)) + if (!handle_alias(args, &expanded_aliases)) break; done_alias = 1; } - string_list_clear(&cmd_list, 0); + string_list_clear(&expanded_aliases, 0); return done_alias; } -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 4/9] git: allow alias-shadowing deprecated builtins 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (2 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 3/9] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 5/9] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk ` (5 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> git-whatchanged(1) is deprecated and you need to pass `--i-still-use-this` in order to force it to work as before. There are two affected users, or usages: 1. people who use the command in scripts; and 2. people who are used to using it interactively. For (1) the replacement is straightforward.[1] But people in (2) might like the name or be really used to typing it.[3] An obvious first thought is to suggest aliasing `whatchanged` to the git-log(1) equivalent.[1] But this doesn’t work and is awkward since you cannot shadow builtins via aliases. Now you are left in an uncomfortable limbo; your alias won’t work until the command is removed for good. Let’s lift this limitation by allowing *deprecated* builtins to be shadowed by aliases. The only observed demand for aliasing has been for git-whatchanged(1), not for git-pack-redundant(1). But let’s be consistent and treat all deprecated commands the same. [1]: git log --raw --no-merges With a minor caveat: you get different outputs if you happen to have empty commits (no changes)[2] [2]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ [3]: https://lore.kernel.org/git/BL3P221MB0449288C8B0FA448A227FD48833AA@BL3P221MB0449.NAMP221.PROD.OUTLOOK.COM/ Based-on-patch-by: Jeff King <peff@peff.net> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v6: Drop footnote now that we don’t have the “extra output line” problem. v5: Fix a leak caused by calling `alias_lookup(...)` without freeing the return value by not calling that function. Add tests for deprecated builtins for infinite alias looping as well as simple chaining. This is to exercise all code paths that we could think of. Expand on the infinite alias looping test on the whole error output (compared to the one above). Link this change to the previous patch/commit by mentioning it in a footnote. See the last footnote and the note on the previous commit/patch. I have opted not to get rid of this redundant line. But this documents the change and future changes that affect it will trigger this assertion (say if they remove the redundant line). v4: Better `is_deprecated_command` implementation. v3 (new): Prerequisite for telling the user that they can alias `whatchanged` to `git log --raw --no-merged`. Link: https://lore.kernel.org/git/cover.1756311355.git.code@khaugsbakk.name/T/#md434b0968f499263262fb1805d82b788b8349d9a > I think that is good advice, but... it won't do anything until we > actually drop the whatchanged command, since until then we'll refuse to > override the command (even the crippled --i-still-use-this one). > > We'd need something like the patch here: ❦ The test_file_not_empty expect is here because the git(1) command could fail. Make sure that it did indeed output anyhing on stdout. (Or if a previous redirect to `expect` outputted something it should be completely different to `actual` in any case) I don’t know if this is just a waste. Documentation/config/alias.adoc | 3 ++- git.c | 17 ++++++++++++++ t/t0014-alias.sh | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/Documentation/config/alias.adoc b/Documentation/config/alias.adoc index 2c5db0ad842..3c8fab3a95c 100644 --- a/Documentation/config/alias.adoc +++ b/Documentation/config/alias.adoc @@ -3,7 +3,8 @@ alias.*:: after defining `alias.last = cat-file commit HEAD`, the invocation `git last` is equivalent to `git cat-file commit HEAD`. To avoid confusion and troubles with script usage, aliases that - hide existing Git commands are ignored. Arguments are split by + hide existing Git commands are ignored except for deprecated + commands. Arguments are split by spaces, the usual shell quoting and escaping are supported. A quote pair or a backslash can be used to quote them. + diff --git a/git.c b/git.c index ef1e7b205aa..8c85da84c30 100644 --- a/git.c +++ b/git.c @@ -824,12 +824,29 @@ static void execv_dashed_external(const char **argv) exit(128); } +static int is_deprecated_command(const char *cmd) +{ + struct cmd_struct *builtin = get_builtin(cmd); + return builtin && (builtin->option & DEPRECATED); +} + static int run_argv(struct strvec *args) { int done_alias = 0; struct string_list expanded_aliases = STRING_LIST_INIT_DUP; while (1) { + /* + * Allow deprecated commands to be overridden by aliases. This + * creates a seamless path forward for people who want to keep + * using the name after it is gone, but want to skip the + * deprecation complaint in the meantime. + */ + if (is_deprecated_command(args->v[0]) && + handle_alias(args, &expanded_aliases)) { + done_alias = 1; + continue; + } /* * If we tried alias and futzed with our environment, * it no longer is safe to invoke builtins directly in diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 854d59ec58c..1b196ed9d6d 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -27,6 +27,20 @@ test_expect_success 'looping aliases - internal execution' ' test_grep "^fatal: alias loop detected: expansion of" output ' +test_expect_success 'looping aliases - deprecated builtins' ' + test_config alias.whatchanged pack-redundant && + test_config alias.pack-redundant whatchanged && + cat >expect <<-EOF && + ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ} + ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ} + fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate: + whatchanged <== + pack-redundant ==> + EOF + test_must_fail git whatchanged -h 2>actual && + test_cmp expect actual +' + # This test is disabled until external loops are fixed, because would block # the test suite for a full minute. # @@ -55,4 +69,30 @@ test_expect_success 'tracing a shell alias with arguments shows trace of prepare test_cmp expect actual ' +can_alias_deprecated_builtin () { + cmd="$1" && + # some git(1) commands will fail for `-h` (the case for + # git-status as of 2025-09-07) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'can alias-shadow deprecated builtins' ' + for cmd in $(git --list-cmds=deprecated) + do + can_alias_deprecated_builtin "$cmd" || return 1 + done +' + +test_expect_success 'can alias-shadow via two deprecated builtins' ' + # some git(1) commands will fail... (see above) + test_might_fail git status -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias.whatchanged=pack-redundant \ + -c alias.pack-redundant=status whatchanged -h >actual && + test_cmp expect actual +' + test_done -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 5/9] t0014: test shadowing of aliases for a sample of builtins 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (3 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 4/9] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 6/9] you-still-use-that??: help the user help themselves kristofferhaugsbakk ` (4 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The previous commit added tests for shadowing deprecated builtins. Let’s make the test suite more complete by exercising a sample of the builtins and in turn test the documentation for git-config(1): To avoid confusion and troubles with script usage, aliases that hide existing Git commands are ignored except for deprecated commands. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v3 (new): Only a sample of builtins since the test file takes about 600ms longer if I test all of them. t/t0014-alias.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 1b196ed9d6d..07a53e7366e 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -95,4 +95,21 @@ test_expect_success 'can alias-shadow via two deprecated builtins' ' test_cmp expect actual ' +cannot_alias_regular_builtin () { + cmd="$1" && + # some git(1) commands will fail... (see above) + test_might_fail git "$cmd" -h >expect && + test_file_not_empty expect && + test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual && + test_cmp expect actual +} + +test_expect_success 'cannot alias-shadow a sample of regular builtins' ' + for cmd in grep check-ref-format interpret-trailers \ + checkout-index fast-import diagnose rev-list prune + do + cannot_alias_regular_builtin "$cmd" || return 1 + done +' + test_done -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 6/9] you-still-use-that??: help the user help themselves 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (4 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 5/9] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 7/9] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk ` (3 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> Give the user a list of suggestions for what to do when they run a deprecated command. The first order of action will be to check the breaking changes document;[1] this short error message says nothing about why this command is deprecated, and in any case going into any kind of detail might overwhelm the user. Then they can find out if this has been discussed on the mailing list. Then users who e.g. are using git-whatchanged(1) can learn that this is arguably a plug-in replacement: git log <opts> --raw --no-merges Finally they are invited to send an email to the mailing list. Also drop the “please add” part in favor of just using the “refusing” die-message; these two would have been right after each other in this new version. Also drop “Thanks” since it now would require a new paragraph. [1]: www.git-scm.com has a disclaimer for these internal documents that says that “This information is specific to the Git project”. That’s misleading in this particular case. But users are unlikely to get discouraged from reading about why they (or their programs) cannot run a command any more; it clearly concerns them. Helped-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v2: I had second thoughts about the bullet point about send-an-email. Change it to the one Eric Sunshine proposed;[1] make sure to spell out that you can send an email conditioned on not finding a suitable replacement. Also change the area to something more pointed. And also use a clear URL to refer to www.git-scm.com. [1]: https://lore.kernel.org/git/CAPig+cQkVP57n_FE6dJ0uxvai-J7usxKFp8gzfEbPY=Ytsd6=Q@mail.gmail.com/ • Change send-an-email bullet point • Change the area • Use www.git-scm.com, not simply git-scm v1: An alternative to linking to www.git-scm.com is to move this document to a regular installed man page: gitbreaking-changes(7) What do you think? I would then have to base my topic on the in-flight pw/3.0-commentchar-auto-deprecation, which in turn depends on ps/config-wo-the-repository. Or just wait a bit for these to settle in. usage.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/usage.c b/usage.c index 81913236a4a..35dc57eb07e 100644 --- a/usage.c +++ b/usage.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" +#include "strbuf.h" static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { @@ -377,12 +378,24 @@ void bug_fl(const char *file, int line, const char *fmt, ...) NORETURN void you_still_use_that(const char *command_name) { + struct strbuf percent_encoded = STRBUF_INIT; + strbuf_add_percentencode(&percent_encoded, + command_name, + STRBUF_ENCODE_SLASH); + fprintf(stderr, _("'%s' is nominated for removal.\n" - "If you still use this command, please add an extra\n" - "option, '--i-still-use-this', on the command line\n" - "and let us know you still use it by sending an e-mail\n" - "to <git@vger.kernel.org>. Thanks.\n"), - command_name); + "If you still use this command, here's what you can do:\n" + "\n" + "- read https://git-scm.com/docs/BreakingChanges.html\n" + "- check if anyone has discussed this on the mailing\n" + " list and if they came up with something that can\n" + " help you: https://lore.kernel.org/git/?q=%s\n" + "- send an email to <git@vger.kernel.org> to let us\n" + " know that you still use this command and were unable\n" + " to determine a suitable replacement\n" + "\n"), + command_name, percent_encoded.buf); + strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 7/9] whatchanged: hint about git-log(1) and aliasing 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (5 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 6/9] you-still-use-that??: help the user help themselves kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 8/9] whatchanged: remove not-even-shorter clause kristofferhaugsbakk ` (2 subsequent siblings) 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> There have been quite a few `--i-still-use-this` user reports since Git 2.51.0 was released.[1][2] And it doesn’t seem like they are reading the man page about the git-log(1) equivalent. Tell them what options to plug into git-log(1), either as a replacement command or as an alias.[3] That template produces almost the same output[4] and is arguably a plug-in replacement. Concretely, add an optional `hint` argument so that we can use it right after the initial error line. Also mention the same concrete options in the documentation while we’re at it. [1]: E.g., • https://lore.kernel.org/git/e1a69dea-bcb6-45fc-83d3-9e50d32c410b@5y5.one/ • https://lore.kernel.org/git/1011073f-9930-4360-a42f-71eb7421fe3f@chrispalmer.uk/#t • https://lore.kernel.org/git/9fcbfcc4-79f9-421f-b9a4-dc455f7db485@acm.org/#t • https://lore.kernel.org/git/83241BDE-1E0D-489A-9181-C608E9FCC17B@gmail.com/ [2]: The error message on 2.51.0 does tell them to report it, unconditionally [3]: We allow aliasing deprecated builtins now for people who are very used to the command name or just like it a lot [4]: You only get different outputs if you happen to have empty commits (no changes)[4] [5]: https://lore.kernel.org/git/20250825085428.GA367101@coredump.intra.peff.net/ Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): v5: Mention the aliasing hint in the commit message. v3: Add an alias hint now that that is possible. Also prefix each hint-line with `hint: `. v2: Review found a whitespace error in the prev. patch version. I found a broken footnote and wanted to expand on the last footnote. • Fix whitespace error (I should have used `ci/check-whitespace.sh v2.51.0`) • Add missing colon (:) to footnote • Expand on footnote; a sentence is enough to summarize the difference Documentation/git-whatchanged.adoc | 6 +++++- builtin/log.c | 8 +++++++- builtin/pack-redundant.c | 2 +- git-compat-util.h | 2 +- usage.c | 14 ++++++++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index d21484026fe..e71d2aa2d27 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -24,7 +24,11 @@ Shows commit logs and diff output each commit introduces. New users are encouraged to use linkgit:git-log[1] instead. The `whatchanged` command is essentially the same as linkgit:git-log[1] -but defaults to showing the raw format diff output and skipping merges. +but defaults to showing the raw format diff output and skipping merges: + +---- +git log --raw --no-merges +---- The command is primarily kept for historical reasons; fingers of many people who learned Git long before `git log` was invented by diff --git a/builtin/log.c b/builtin/log.c index c2f8bbf8630..1d1e6e9130a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -543,7 +543,13 @@ int cmd_whatchanged(int argc, cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!cfg.i_still_use_this) - you_still_use_that("git whatchanged"); + you_still_use_that("git whatchanged", + _("\n" + "hint: You can replace 'git whatchanged <opts>' with:\n" + "hint:\tgit log <opts> --raw --no-merges\n" + "hint: Or make an alias:\n" + "hint:\tgit config set --global alias.whatchanged 'log --raw --no-merges'\n" + "\n")); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index fe81c293e3a..5d5ae4afa28 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -626,7 +626,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s } if (!i_still_use_this) - you_still_use_that("git pack-redundant"); + you_still_use_that("git pack-redundant", NULL); if (load_all_packs) load_all(); diff --git a/git-compat-util.h b/git-compat-util.h index 9408f463e31..398e0fac4fa 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -460,7 +460,7 @@ void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void show_usage_if_asked(int ac, const char **av, const char *err); -NORETURN void you_still_use_that(const char *command_name); +NORETURN void you_still_use_that(const char *command_name, const char *hint); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/usage.c b/usage.c index 35dc57eb07e..7545a616453 100644 --- a/usage.c +++ b/usage.c @@ -376,7 +376,8 @@ void bug_fl(const char *file, int line, const char *fmt, ...) va_end(ap); } -NORETURN void you_still_use_that(const char *command_name) + +NORETURN void you_still_use_that(const char *command_name, const char *hint) { struct strbuf percent_encoded = STRBUF_INIT; strbuf_add_percentencode(&percent_encoded, @@ -384,8 +385,13 @@ NORETURN void you_still_use_that(const char *command_name) STRBUF_ENCODE_SLASH); fprintf(stderr, - _("'%s' is nominated for removal.\n" - "If you still use this command, here's what you can do:\n" + _("'%s' is nominated for removal.\n"), command_name); + + if (hint) + fputs(hint, stderr); + + fprintf(stderr, + _("If you still use this command, here's what you can do:\n" "\n" "- read https://git-scm.com/docs/BreakingChanges.html\n" "- check if anyone has discussed this on the mailing\n" @@ -395,7 +401,7 @@ NORETURN void you_still_use_that(const char *command_name) " know that you still use this command and were unable\n" " to determine a suitable replacement\n" "\n"), - command_name, percent_encoded.buf); + percent_encoded.buf); strbuf_release(&percent_encoded); die(_("refusing to run without --i-still-use-this")); } -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 8/9] whatchanged: remove not-even-shorter clause 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (6 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 7/9] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 9/9] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-18 18:31 ` [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting Jeff King 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> The closest equivalent is `git log --raw --no-merges`. Also change to “defaults” (implicit plural). Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Documentation/git-whatchanged.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-whatchanged.adoc b/Documentation/git-whatchanged.adoc index e71d2aa2d27..436e219b7d0 100644 --- a/Documentation/git-whatchanged.adoc +++ b/Documentation/git-whatchanged.adoc @@ -15,7 +15,7 @@ WARNING ------- `git whatchanged` has been deprecated and is scheduled for removal in a future version of Git, as it is merely `git log` with different -default; `whatchanged` is not even shorter to type than `log --raw`. +defaults. DESCRIPTION ----------- -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* [PATCH v6 9/9] BreakingChanges: remove claim about whatchanged reports 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (7 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 8/9] whatchanged: remove not-even-shorter clause kristofferhaugsbakk @ 2025-09-17 20:24 ` kristofferhaugsbakk 2025-09-18 18:31 ` [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting Jeff King 9 siblings, 0 replies; 102+ messages in thread From: kristofferhaugsbakk @ 2025-09-17 20:24 UTC (permalink / raw) To: Junio C Hamano Cc: Kristoffer Haugsbakk, git, Eric Sunshine, peff, Patrick Steinhardt From: Kristoffer Haugsbakk <code@khaugsbakk.name> This was written in e836757e14b (whatschanged: list it in BreakingChanges document, 2025-05-12) which was on the same topic that added the `--i-still-use-this` requirement.[1] Maybe it was a work-in-progress comment/status. [1]: jc/you-still-use-whatchanged Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> --- Notes (series): Footnote solely to avoid awkward paragraph wrapping... Documentation/BreakingChanges.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/BreakingChanges.adoc b/Documentation/BreakingChanges.adoc index f8d2eba061c..c4985163c3c 100644 --- a/Documentation/BreakingChanges.adoc +++ b/Documentation/BreakingChanges.adoc @@ -235,7 +235,7 @@ These features will be removed. equivalent `git log --raw`. We have nominated the command for removal, have changed the command to refuse to work unless the `--i-still-use-this` option is given, and asked the users to report - when they do so. So far there hasn't been a single complaint. + when they do so. + The command will be removed. -- 2.51.0.274.gdcb64e51a0f ^ permalink raw reply related [flat|nested] 102+ messages in thread
* Re: [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk ` (8 preceding siblings ...) 2025-09-17 20:24 ` [PATCH v6 9/9] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk @ 2025-09-18 18:31 ` Jeff King 2025-09-18 20:21 ` Junio C Hamano 2025-09-18 20:28 ` Kristoffer Haugsbakk 9 siblings, 2 replies; 102+ messages in thread From: Jeff King @ 2025-09-18 18:31 UTC (permalink / raw) To: kristofferhaugsbakk Cc: Junio C Hamano, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt On Wed, Sep 17, 2025 at 10:24:10PM +0200, kristofferhaugsbakk@fastmail.com wrote: > § Changes in v6 > > Use Peff’s patch to get rid of “the extra output”.[1] Update commit > messages to not mention that. > > Also use another fix from Peff (patch 1); don’t list git-whatchanged(1) > as a builtin when `WITH_BREAKING_CHANGES`. Thanks, I looked over the patches that touch the things we've been discussing, and it all looks good to me. I am a little troubled that even after your patch 1, the test suite will get confused by a stray git-whatchanged binary left over from an earlier build. That may become an irritation later, when the breaking change becomes the norm. But maybe it won't be too bad. At that point the matching entry in .gitignore should be dropped, so at least "git clean" will find it. In the meantime, building with and without the breaking-changes flag can cause confusion, but presumably people aren't swapping between them too often? And I don't have a clever idea of how to do better, short of having the breaking-changes flag explicitly delete git-whatchanged from the build directory. Which feels a little gross. So I'd say to call it good for now, and if it comes back to bite us later, it is not harder to address then than it would be now. -Peff ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting 2025-09-18 18:31 ` [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting Jeff King @ 2025-09-18 20:21 ` Junio C Hamano 2025-09-18 20:28 ` Kristoffer Haugsbakk 1 sibling, 0 replies; 102+ messages in thread From: Junio C Hamano @ 2025-09-18 20:21 UTC (permalink / raw) To: Jeff King Cc: kristofferhaugsbakk, Kristoffer Haugsbakk, git, Eric Sunshine, Patrick Steinhardt Jeff King <peff@peff.net> writes: > I am a little troubled that even after your patch 1, the test suite will > get confused by a stray git-whatchanged binary left over from an earlier > build. That may become an irritation later, when the breaking change > becomes the norm. But maybe it won't be too bad. At that point the > matching entry in .gitignore should be dropped, so at least "git clean" > will find it. In the meantime, building with and without the > breaking-changes flag can cause confusion, but presumably people aren't > swapping between them too often? And I don't have a clever idea of how > to do better, short of having the breaking-changes flag explicitly > delete git-whatchanged from the build directory. Which feels a little > gross. > > So I'd say to call it good for now, and if it comes back to bite us > later, it is not harder to address then than it would be now. Yup, my "before pushout" local builds almost always hit a snag from leftover git-whatchanged, until I tweaked the procedure to begin with "make distclean" before doing anything else X-<, but this may be good enough for now. Thanks, both of you. ^ permalink raw reply [flat|nested] 102+ messages in thread
* Re: [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting 2025-09-18 18:31 ` [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting Jeff King 2025-09-18 20:21 ` Junio C Hamano @ 2025-09-18 20:28 ` Kristoffer Haugsbakk 1 sibling, 0 replies; 102+ messages in thread From: Kristoffer Haugsbakk @ 2025-09-18 20:28 UTC (permalink / raw) To: Jeff King, Kristoffer Haugsbakk Cc: Junio C Hamano, git, Eric Sunshine, Patrick Steinhardt On Thu, Sep 18, 2025, at 20:31, Jeff King wrote: > On Wed, Sep 17, 2025 at 10:24:10PM +0200, > kristofferhaugsbakk@fastmail.com wrote: > >> § Changes in v6 >> >> Use Peff’s patch to get rid of “the extra output”.[1] Update commit >> messages to not mention that. >> >> Also use another fix from Peff (patch 1); don’t list git-whatchanged(1) >> as a builtin when `WITH_BREAKING_CHANGES`. > > Thanks, I looked over the patches that touch the things we've been > discussing, and it all looks good to me. Thanks for the review! > I am a little troubled that even after your patch 1, the test suite will > get confused by a stray git-whatchanged binary left over from an earlier > build. That may become an irritation later, when the breaking change > becomes the norm. But maybe it won't be too bad. At that point the > matching entry in .gitignore should be dropped, so at least "git clean" > will find it. Yeah this seems tricky. And this in-between space seems difficult to deal with even with all the tools like gitignore and whatnot. > In the meantime, building with and without the breaking-changes flag > can cause confusion, but presumably people aren't swapping between > them too often? I for one (and honestly) only did it now when I was informed that it failed the test. I’ll keep it confined in its own worktree where I have no qualms doing git-clean(1) every run. > And I don't have a clever idea of how > to do better, short of having the breaking-changes flag explicitly > delete git-whatchanged from the build directory. Which feels a little > gross. Not that I know anything about build systems but that doesn’t sound like a bad or unprincipled solution. > So I'd say to call it good for now, and if it comes back to bite us > later, it is not harder to address then than it would be now. -- Kristoffer ^ permalink raw reply [flat|nested] 102+ messages in thread
end of thread, other threads:[~2025-09-18 20:28 UTC | newest] Thread overview: 102+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-27 16:29 [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 1/4] usage: help the user help themselves kristofferhaugsbakk 2025-08-27 20:36 ` Kristoffer Haugsbakk 2025-08-27 21:02 ` Eric Sunshine 2025-08-27 21:20 ` Junio C Hamano 2025-08-27 21:27 ` Eric Sunshine 2025-08-27 22:26 ` Junio C Hamano 2025-08-28 6:39 ` Kristoffer Haugsbakk 2025-08-28 15:09 ` Junio C Hamano 2025-09-03 16:50 ` Eric Sunshine 2025-09-03 17:53 ` Kristoffer Haugsbakk 2025-09-03 21:21 ` Eric Sunshine 2025-09-03 21:41 ` Kristoffer Haugsbakk 2025-09-03 21:44 ` Jeff King 2025-09-03 22:11 ` Eric Sunshine 2025-09-04 6:57 ` Kristoffer Haugsbakk 2025-09-05 13:11 ` Jeff King 2025-09-09 20:01 ` Kristoffer Haugsbakk 2025-08-27 21:14 ` Junio C Hamano 2025-08-27 16:29 ` [PATCH 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk 2025-08-27 16:45 ` Junio C Hamano 2025-08-27 16:48 ` Junio C Hamano 2025-08-27 17:08 ` Kristoffer Haugsbakk 2025-08-28 12:07 ` Kristoffer Haugsbakk 2025-08-27 16:29 ` [PATCH 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-08-27 16:29 ` [PATCH 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-08-27 16:43 ` [PATCH 0/4] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano 2025-08-29 15:21 ` [PATCH v2 " kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 1/4] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 2/4] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 3/4] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-08-29 15:21 ` [PATCH v2 4/4] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-09 6:43 ` Patrick Steinhardt 2025-09-09 8:02 ` Kristoffer Haugsbakk 2025-09-08 15:36 ` [PATCH v3 2/8] git: make the two loops look more symmetric kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk 2025-09-08 20:47 ` Junio C Hamano 2025-09-08 21:11 ` Jeff King 2025-09-08 21:55 ` Junio C Hamano 2025-09-09 6:25 ` Kristoffer Haugsbakk 2025-09-08 15:36 ` [PATCH v3 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 6/8] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-09-08 15:36 ` [PATCH v3 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 0/7] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 1/7] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-09 21:44 ` Junio C Hamano 2025-09-10 11:41 ` Patrick Steinhardt 2025-09-10 15:50 ` Jeff King 2025-09-10 21:40 ` Junio C Hamano 2025-09-10 20:23 ` Kristoffer Haugsbakk 2025-09-09 19:45 ` [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk 2025-09-10 5:13 ` Jeff King 2025-09-10 15:48 ` Jeff King 2025-09-10 17:58 ` Kristoffer Haugsbakk 2025-09-10 18:34 ` Jeff King 2025-09-11 17:31 ` Kristoffer Haugsbakk 2025-09-11 20:32 ` Jeff King 2025-09-11 20:43 ` Jeff King 2025-09-13 14:10 ` Kristoffer Haugsbakk 2025-09-13 22:06 ` Jeff King 2025-09-14 17:24 ` Kristoffer Haugsbakk 2025-09-15 1:44 ` Jeff King 2025-09-15 6:27 ` Kristoffer Haugsbakk 2025-09-11 20:44 ` Jeff King 2025-09-11 21:19 ` Junio C Hamano 2025-09-13 21:50 ` Kristoffer Haugsbakk 2025-09-09 19:45 ` [PATCH v4 3/7] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 4/7] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 5/7] whatchanged: tell users the git-log(1) equivalent kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 6/7] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-09-09 19:45 ` [PATCH v4 7/7] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 1/8] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 2/8] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 3/8] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 4/8] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 5/8] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 6/8] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 7/8] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-09-14 19:49 ` [PATCH v5 8/8] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-15 19:19 ` [PATCH v5 0/8] you-still-use-that??: improve breaking changes troubleshooting Junio C Hamano 2025-09-16 20:47 ` Kristoffer Haugsbakk 2025-09-16 23:24 ` Jeff King 2025-09-17 15:41 ` Kristoffer Haugsbakk 2025-09-17 16:25 ` Junio C Hamano 2025-09-17 20:24 ` [PATCH v6 0/9] " kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 1/9] Makefile: don’t add whatchanged after it has been removed kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 2/9] git: add `deprecated` category to --list-cmds kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 3/9] git: move seen-alias bookkeeping into handle_alias(...) kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 4/9] git: allow alias-shadowing deprecated builtins kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 5/9] t0014: test shadowing of aliases for a sample of builtins kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 6/9] you-still-use-that??: help the user help themselves kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 7/9] whatchanged: hint about git-log(1) and aliasing kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 8/9] whatchanged: remove not-even-shorter clause kristofferhaugsbakk 2025-09-17 20:24 ` [PATCH v6 9/9] BreakingChanges: remove claim about whatchanged reports kristofferhaugsbakk 2025-09-18 18:31 ` [PATCH v6 0/9] you-still-use-that??: improve breaking changes troubleshooting Jeff King 2025-09-18 20:21 ` Junio C Hamano 2025-09-18 20:28 ` Kristoffer Haugsbakk
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).