Subject: Re: The git spring cleanup challenge

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Thu, 03 Jun 2021 14:18:15 +0200

On Thu, Jun 03 2021, Felipe Contreras wrote:

> Ævar Arnfjörð Bjarmason wrote:
>> 
>> On Tue, Jun 01 2021, Felipe Contreras wrote:
>> 
>> > Đoàn Trần Công Danh wrote:
>> >> On 2021-06-01 05:48:41-0500, Felipe Contreras <[email-masked]> wrote:
>> >> > > How about alias? It's part of my muscle memory.
>> >> > 
>> >> > No aliases.
>> >> > 
>> >> > If a new user doesn't have them, neither should you.
>> >> > 
>> >> > All VCSs have default aliases, and I advocated for git to do the same
>> >> > [1], but it wasn't accepted.
>> >> > 
>> >> > The whole point is to suffer like them.
>> >> 
>> >> Get back to the alias topic.
>> >> I also agree with other people's opinion in that thread.
>> >> IOW, I support the decision to not accept those default alias ;)
>> >
>> > Why?
>> >
>> >> It's not required to be different people to have alias defined to
>> >> different command. I have alias conditionally defined to different
>> >> command based on git-dir. For example, I had ci alias to "commit" by
>> >> default, and "commit -s" on other repositories.
>> >
>> > So? They would still work.
>> >
>> >> So, Git decides alias for me will not only break my current alias, but
>> >> also break my conditional alias.
>> >
>> > No it wouldn't. They are *default* aliases, not overriding aliases. They
>> > would be used only if you haven't set the same alias yourself.
>> >
>> > Try it.
>> >
>> > --- a/alias.c
>> > +++ b/alias.c
>> > @@ -28,13 +28,27 @@ static int config_alias_cb(const char *key, const char *value, void *d)
>> >         return 0;
>> >  }
>> >  
>> > +struct config_alias_data default_aliases[] = {
>> > +       { "co", "checkout" },
>> > +       { "ci", "checkout" },
>> > +       { "rb", "rebase" },
>> > +       { "st", "status" },
>> > +};
>> > +
>> >  char *alias_lookup(const char *alias)
>> >  {
>> >         struct config_alias_data data = { alias, NULL };
>> > +       int i;
>> >  
>> >         read_early_config(config_alias_cb, &data);
>> > +       if (data.v)
>> > +               return data.v;
>> > +       for (i = 0; i < ARRAY_SIZE(default_aliases); i++) {
>> > +               if (!strcmp(alias, default_aliases[i].alias))
>> > +                       return xstrdup(default_aliases[i].v);
>> > +       }
>> >  
>> > -       return data.v;
>> > +       return NULL;
>> >  }
>> >  
>> >  void list_aliases(struct string_list *list)
>> >
>> >
>> >> Anyway, remotes/branches are all configuration values.
>> >> Would you prefer:
>> >
>> > I meant global configurations. If it's a per-repository setting surely
>> > it wouldn't be something amenable for the Git project to set as default.
>> 
>> I agree with this batteries included sentiment, but would very much like
>> to not see this as hardcoding of ours, but us shipping optional config
>> files to be included.
>
> The problem with optional config files is that you can't standardize
> that way.
>
> If hard-coded default aliases they can be included in the documentation.
>
> Pluse we all start to typing similar commands, instead of each having
> completely different alias to the next.
>
> For example in 3 days of doing this experiment I've typed 'g c'
> countless of times (alias for `commit -v`). I added an alias for `ci`
> instead, since that what other VCSs use, like Mercurial. But I don't
> think `ci` makes sense for commit. It would be better if `co` was
> available, but then checkout needs another alias.
>
> If we could replace checkout with switch, then we could have an alias
> `sw` for switch, and another `co` for commit.
>
> But that requires that switch is actually usable (it isn't for me right
> now).
>
> This increases the urgency to fix `git switch` for me. If other
> developers were trying the same aliases they might see the same issues.
>
>> We could then just extend the include syntax rather easily to include
>> "libraries", which would be like the current include.path, but would
>> understand a library:: prefix (better name bikeshedding welcome). We'd
>> then just ship these in /usr/share/git-core/config/includes or whatever,
>> e.g. /usr/share/git-core/config/includes/aliases/svn-like.cfg
>
> I wouldn't be against some some suggested defaults, but *in addition* to
> some hardcoded default aliases that are documented.

I'm talking about in terms of the flexibility of implementation of
on-by-default defaults. We could implement it as I suggested and then
just have a core.defaultIncludes, which would by default be set to
git::aliases/svn-like.cfg or whatever, i.e. equivalent to:

    [core]
    defaultIncludes = "git::default.cfg"

Which itself would include a
/usr/share/git-core/config/includes/default.cfg which would do:

    [include]
    path = "git::aliases/svn-like.cfg"
    paht = <some other default file>

So it would work out of the box on a vanilla git install, you could then
in ~/.gitconfig or whatever set:

    [core]
    defaultIncludes = false

Or whatever, which we'd check for early with repo_config_get_bool() (see
repo-settings.c).

So you'd have an out from these optional vanilla includes. Then to
address the concern in [1] we could (sans the user-diff specific
limitations in that thread) treat the default userdiff "config" this way
and (optionally) slurp these up into a generated *.c file at build-time.

In a way this is total bikeshedding, I just think it's worth doing it
this way up-front.

It gives you a lot more flexibility than hardcoding these in the source
somewhere. It becomes easy e.g. to have multiple "default" variants, so
feature.experimental or whatever could give you early opt-in to new
aliases, or the other way around of new versions maintaining
compatibility with older style invocations via aliases.

1. https://lore.kernel.org/git/[email-masked]/