Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git alias parsing breaks on shell aliases #5412

Closed
jeremywiebe opened this issue Dec 13, 2018 · 11 comments
Closed

Git alias parsing breaks on shell aliases #5412

jeremywiebe opened this issue Dec 13, 2018 · 11 comments

Comments

@jeremywiebe
Copy link

Problem

Most of my git aliases do not support tab completion.

I use several git aliases that are scripts instead of just a shortening of a git command. This breaks the git alias parsing in git.fish.

It's pretty easy to illustrate the problem using the following:

$ git config --global alias.br "!echo \"A wacky alias\" && echo \"More wackiness\""
$ git br
A wacky alias
More wackiness
$ git config -z --get-regexp 'alias\..*' | while read -lz alias command _
    echo $alias
    echo $command
end 

alias.br
!echo

As you can see it seems to split on the whitespace in the alias and then comes out with just the first part. I've been overriding it by doing set --universal __fish_git_alias_co "checkout" but that gets overridden by fish.git when I start a new Terminal (even if I put that in ~/.config/fish/config.fish).

Lastly, I can't disable/override the git alias parsing as that isn't guarded by an flag check.

I'd be happy to work up a PR if anyone is willing to give me some guidance/ideas on how to address this. :)

Environment

OS: macOS 10.14
Terminal: Terminal.app (built in terminal)
Version: fish, version 2.7.1
uname -a: Darwin Jeremys-MacBook-Pro.local 18.0.0 Darwin Kernel Version 18.0.0: Wed Aug 22 20:13:40 PDT 2018; root:xnu-4903.201.2~1/RELEASE_X86_64 x86_64
$TERM: xterm-256color

Possibly relevant (but I haven't changed this):

$ set | grep IFS
IFS \n\ \t

I haven't reproduced this in a pristine shell because, but I have broken down the relevant parts of git.fish and can reproduce the issue that way.

@jsatk
Copy link

jsatk commented Dec 13, 2018

I am also seeing this exact issue.

@faho
Copy link
Member

faho commented Dec 13, 2018

This is quite an easy fix:

git config -z --get-regexp 'alias\..*' | while read -lz alias command

Quite literally the _ removed, so that it doesn't split anymore after the first bit of whitespace, which delimits the alias from the command.

faho added a commit to faho/fish-shell that referenced this issue Dec 13, 2018
@faho faho added this to the fish-3.0 milestone Dec 13, 2018
@jeremywiebe
Copy link
Author

Well that was fast! Amazing, thank-you so much!! Looking forward to Fish 3.0

@faho faho closed this as completed Dec 13, 2018
@jsatk
Copy link

jsatk commented Dec 14, 2018

Thank you @faho .

@faho
Copy link
Member

faho commented Dec 15, 2018

Sorry folks, I was wrong. The part I changed was the "this git alias corresponds to this command" bit, which should be kept as-is.

What's broken here, I assume is the "show git aliases with what they execute" bit, which is done later: https://github.com/fish-shell/fish-shell/blob/master/share/completions/git.fish#L497-L504. Because that uses newlines to delimit it, fish will become confused if there is any alias with multiple lines in the value.

That's also simple enough to solve, but my original "fix" needs to be reverted.

@faho faho reopened this Dec 15, 2018
@faho faho removed this from the fish-3.0 milestone Dec 15, 2018
@jeremywiebe
Copy link
Author

Would it be possible to put this feature behind a flag? I applied your fix locally and realized it doesn’t solve my problem either. :-)

What I want is to have the shell understand that git co is synonymous with git checkout. But there’s no reasonable way for the shell to figure that out.

Ultimately I would rather Fish shell not try at all, or at least check if there is already an existing variable for hmthat alias and not create one in those situations.

@faho
Copy link
Member

faho commented Dec 15, 2018

What I want is to have the shell understand that git co is synonymous with git checkout.

I'm still not quite sure why that would be a problem?

Can you upload your aliases somewhere, so that I can have a look?

Or what does echo $__fish_git_alias_co say once you tried completing git once in that session (so that the completions are loaded)?

Would it be possible to put this feature behind a flag?

We try not to do that. If you want, you can copy the git completions and make the changes you want locally. See $fish_complete_path.

@jeremywiebe
Copy link
Author

Here's an example of the co alias:

!f() { if [ -n "$1" -a -z "$2" ]; then git checkout `revisionid-to-diffid.sh --tag "$@"`; else git checkout "$@"; fi && git submodule update --init --recursive; }; f

In the original case, __fish_git_alias_co was just !f().

I'm fine making a copy. Is there a way to disable the git completions that ship with the shell (I'm installing via Homebrew)?

@zanchey zanchey added this to the fish-future milestone Dec 16, 2018
@faho
Copy link
Member

faho commented Dec 16, 2018

Here's an example of the co alias:

Ah, okay. That's unparsable for us.

Here's what we're gonna do: We can't do anything with ! aliases, because those are run with /bin/sh (or whatever other shell was specified when building git), so we can just skip them here:

git config -z --get-regexp 'alias\..*' | while read -lz alias command _
    # If the command starts with a "!", it's a shell command, run with /bin/sh,
    # or any other shell defined at git's build time.
    #
    # We can't do anything with them, and we run git-config again for listing aliases,
    # so we skip them here.
    string match -q '!*' -- $command; and continue
    # Git aliases can contain chars that variable names can't - escape them.
    set alias (string replace 'alias.' '' -- $alias | string escape --style=var)
    set -g __fish_git_alias_$alias $command
end

That means to complete them you'd have to set -g __fish_git_alias_co checkout, but that's an unfortunate reality, and what you've tried to do anyway.

Is there a way to disable the git completions that ship with the shell (I'm installing via Homebrew)?

Like I said: $fish_complete_path. When fish loads a completion, it goes through the elements of that for a file named "command.fish", and loads the first one it finds (like $PATH).

By default, it should already have an entry ~/.config/fish/completions. Just copy the default completions (in e.g. /usr/local/share/fish/completions/) there and make your changes.

@jeremywiebe
Copy link
Author

That sounds good to me. Thanks for explaining (again!).

@jsatk
Copy link

jsatk commented Dec 16, 2018

Thanks @faho.

@faho faho changed the title Git alias parsing breaks on multi-line aliases Git alias parsing breaks on shell aliases Jan 13, 2019
@faho faho closed this as completed in 787f453 Jan 13, 2019
@zanchey zanchey modified the milestones: fish-future, fish 3.1.0 Jan 14, 2019
faho added a commit that referenced this issue Jan 22, 2019
We can't complete these, and now the user can do

```
set -g __fish_git_alias_$alias $command
```

e.g.

```
set -g __fish_git_alias_co checkout
```

if the arguments in the alias end up going to `git alias`.

Fixes #5412.

[ci skip]
@faho faho modified the milestones: fish 3.1.0, fish 3.0.1 Jan 22, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants