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

hub alias slows down prompt if using __git_ps1 #254

Closed
crobinso opened this Issue Oct 26, 2012 · 6 comments

Comments

Projects
None yet
4 participants
@crobinso

Using git-prompt.sh gives fancy shell prompts with git branch information, among other things:

https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh

Example:

[crobinso@colepc src]$ cd qemu
[crobinso@colepc qemu (master)]$ touch foo && git add foo
[crobinso@colepc qemu (master +)]$

This is pretty popular with git users, and in fact fedora enables it by default when you install git.

If I add the hub git alias to my bashrc though, generating this prompt slows way down (which happens after every time a command is run):

Before hub alias

$ time eval echo "$PS1"
[u@h W (master *)]$

real    0m0.051s
user    0m0.003s
sys 0m0.041s

After hub alias:

$ time eval echo "$PS1"
[u@h W (master *)]$

real    0m0.317s
user    0m0.208s
sys 0m0.096s

I'm not sure if that measures it correctly, since it sure feels a lot longer than .3, but it's very noticable when previously the prompt seemed to refresh instantaneously.

I worked around this with a bit of shell in my bashrc, only talking to hub if the requested git command is one that hub overwrites. That hubcommands list would need to be expanded of course, I only added the functionality I care about. (also I'm not shell expert so I don't claim this to be a good solution, portable, etc)

function __git_or_hub {
    hubcommands="clone push pull-request fork"

    for i in "$@"; do
        test $(echo $i | cut -c 1) == "-" && continue
        cmdname="$i"
        break
    done

    for i in $hubcommands; do
        test "$i" == "$cmdname" && bincmd="hub" && break
    done

    test -z "$bincmd" && bincmd="git"

    $bincmd $@
}

# If github 'hub' is installed, use it as a git alias
#$(which hub > /dev/null 2>&1) && eval "$(hub alias -s)"
$(which hub > /dev/null 2>&1) && alias git='__git_or_hub'
@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Oct 26, 2012

Member

Even better solution: have your prompt use command git instead of just git.

command goes straight to the command, avoiding aliases, functions.

Member

mislav commented Oct 26, 2012

Even better solution: have your prompt use command git instead of just git.

command goes straight to the command, avoiding aliases, functions.

@dougbarth

This comment has been minimized.

Show comment
Hide comment
@dougbarth

dougbarth Nov 12, 2012

I found slightly changing my PS1 to unalias git before running __git_ps1 made it skip the hub wrapper, but still left the alias intact for my input. The unalias doesn't affect the normal shell since the call to __git_ps1 is made in a subshell.

alias git=hub
export PS1='[\@ \u \w$(unalias git; __git_ps1)]\n$ '

I found slightly changing my PS1 to unalias git before running __git_ps1 made it skip the hub wrapper, but still left the alias intact for my input. The unalias doesn't affect the normal shell since the call to __git_ps1 is made in a subshell.

alias git=hub
export PS1='[\@ \u \w$(unalias git; __git_ps1)]\n$ '
@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Nov 12, 2012

Member

I can see how unalias works, but it feels hackish and requires 2 commands instead of one. So I still prefer command git.

Calling stuff in one's prompt should be done with care. Each new command or function has potential to slow the prompt down further down the road. So I definitely suggest using command to go directly to the command and skip shell functions and aliases. It should be general practice.

Final thought: I won't fix this in hub (there's nothing to fix), but I will add a note about this in the docs and close this issue after that.

Member

mislav commented Nov 12, 2012

I can see how unalias works, but it feels hackish and requires 2 commands instead of one. So I still prefer command git.

Calling stuff in one's prompt should be done with care. Each new command or function has potential to slow the prompt down further down the road. So I definitely suggest using command to go directly to the command and skip shell functions and aliases. It should be general practice.

Final thought: I won't fix this in hub (there's nothing to fix), but I will add a note about this in the docs and close this issue after that.

@mislav mislav closed this in f065335 Nov 22, 2012

carlosantoniodasilva added a commit to carlosantoniodasilva/dotfiles that referenced this issue Nov 12, 2013

Add hack to remove git=hub alias before running __git_ps1
The alias makes git PS1 a lot slower with the configured GIT_* niceties
for the PS1, taking around 1s+ to return each time when in a git repo.

Unaliasing before running __git_ps1 results in around 0.6~0.7 seconds
faster response from the command, improving the usability considerably.

$ time __git_ps1
 (master>)
 real 0m1.031s
 user 0m0.698s
 sys  0m0.312s

$ unalias git

$ time __git_ps1
  (master>)
  real  0m0.408s
  user  0m0.274s
  sys 0m0.125s

A final solution would be to change the default __git_ps1 function to
use "command git" instead, which would bypass any alias for that command.

More info: github/hub#254
@ddeboer

This comment has been minimized.

Show comment
Hide comment
@ddeboer

ddeboer Jan 24, 2014

@mislav It's not clear to me how to replace __git_ps1 with a command git instance. Can you please elaborate?

ddeboer commented Jan 24, 2014

@mislav It's not clear to me how to replace __git_ps1 with a command git instance. Can you please elaborate?

@mislav

This comment has been minimized.

Show comment
Hide comment
@mislav

mislav Jan 24, 2014

Member

@ddeboer I probably wasn't clear enough. If you were writing that function yourself, my suggestion was to be using command git everywhere instead of plain git invocations.

However, since this function is provided from somewhere else (git's own bash scripts?), you can't really edit it. So, your only option is to copy the function's source code over to your bash init files, and edit git in it to be command git. Or, you could use my bash prompt.

Member

mislav commented Jan 24, 2014

@ddeboer I probably wasn't clear enough. If you were writing that function yourself, my suggestion was to be using command git everywhere instead of plain git invocations.

However, since this function is provided from somewhere else (git's own bash scripts?), you can't really edit it. So, your only option is to copy the function's source code over to your bash init files, and edit git in it to be command git. Or, you could use my bash prompt.

@ddeboer

This comment has been minimized.

Show comment
Hide comment
@ddeboer

ddeboer Jan 24, 2014

@mislav Thanks for the explanation!

ddeboer commented Jan 24, 2014

@mislav Thanks for the explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment