Git completion and PS1 not working: "__git_ps1: command not found" on "sudo -s" or "sudo su" on Ubuntu 12.04
Asked Answered
G

6

10

I installed git and git-flow completion adding these line to .bashrc of root and a normal_user on a Ubuntu 12.04 machine:

source /etc/git-completion.bash
source /etc/git-flow-completion.bash
GIT_PS1_SHOWUPSTREAM="verbose"
GIT_PS1_SHOWDIRTYSTATE=true
PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '

When I log as root or normal_user git completion works. However if I use "sudo -s" or "sudo su" git completion is not working and I continually get "__git_ps1: command not found" each time I press return. I tried to remove the "source" commands and use "apt-get install bash-completion" (bash-completion was already installed). So even without the 2 source I get the exact same behavior.

Anybody knows what the problem is and how to make it work?

Garniture answered 26/7, 2012 at 5:12 Comment(1)
If I enable the bash debug this is what I see: pastebin.com/VEPXEr52Garniture
C
19

When you do sudo su it won't source the users .bashrc. The PS1 is inherited from the user you did the sudo su from but the new shell doesn't know where it can find ___git_ps1

You need to simulate a login by executing sudo su -l

Chamois answered 26/7, 2012 at 11:56 Comment(3)
Thank you. Everything seems correct. "sudo su -l" works too. Is there any way to force "sudo -s" and "sudo su" to read .bashrc ?Garniture
Here they suggest to use "sudo -i" hungrygeek.holidayextras.co.uk/2012/07/20/… It is as short as "sudo -s" but a different command. I am asking if we can keep using “sudo -s” or “sudo su” because I can change but people in our organization are used to these commands.Garniture
For Ubuntu you could try adding your "script" in the file /etc/bash.bashrc That probably would make it work for sudo suChamois
C
5

In your case it occurs because the git-prompt.sh file wasn't started at terminal start, it is possible to find contrib/completion/git-prompt.sh in the initial git-core files.

Probably already is present by the machine, for search:

find ~ -name git-prompt.sh

Can take a lot of time and consequently it is better to specify instead of / search more exact, probably you guess where it is possible to find. When will find, add to .bashrc before your promt change expression by an example as it was made by me with the indication of the ways:

if [ -f $HOME/git/1.8.0/contrib/completion/git-prompt.sh ]; then

. $HOME/git/1.8.0/contrib/completion/git-prompt.sh

fi

After all do:

. ~/.bashrc

Chazan answered 11/11, 2012 at 14:9 Comment(1)
As I state in the question, I am using git-completion.bash and I have a custom prompt. As @peter-van-der-does said the problem is that sudo su does not move over the function ___git_ps1. git-prompt.sh does not seem to be any different... Am I wrong?Garniture
B
5

The prompt functionality was split out of git-completion.bash into git-prompt.sh on May 22, 2012; you will need to source that one as well. Git 1.7.12 was the first release to see this change. I just had the same issue when updating my git-completion.bash.

Banquet answered 30/5, 2013 at 20:18 Comment(0)
O
4

Assuming you're fine not have git completion when logged in as root via sudo su, it's just a little bash kung fu to avoid trying to evaluate __git_ps1.

You can place any kind of conditional you want inside the PS1 prompt (hence how it can substitute in the branch name when in a git directory). So, just wrap the git stuff in a conditional checking you're not user id 0 (root).

Replace in your export PS1 statement:

$(__git_ps1) 

with

$(if [ $(id -u) -ne 0 ]; then echo  $(__git_ps1) ; fi)

The whole prompt you have in the OP would look now look like this:

 PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(if [ $(id -u) -ne 0 ]; then echo  $(__git_ps1) ; fi)\[\033[00m\]\$ '

Now in a shell you should be able to sudo su without the error message.

Outpouring answered 28/2, 2017 at 0:58 Comment(0)
A
0

If you prefer not to add extra flags like -l (or don't want to alias su and the like) you can also just change root's bashrc to not use __git_ps1.

For example, in my /root/.bashrc I have (I like having root be red):

export PS1='\[\e[1;31m\][\u@\h \W]# \[\e[0m\]'

Basically, just copy the PS1 you have in your ~/.bashrc or similar to /root/.bashrc and delete any references to __git_ps1.

Ideally, you rarely do development as root so won't need __git_ps1. If you do (ill advised), you can copy over all of the code needed to execute __git_ps1 to /root/.bashrc.

Artair answered 5/10, 2015 at 16:50 Comment(0)
R
-1

Maybe a little late, however you can replace in your PS1:

(__git_ps1)

with

(type -t __git_ps1 >& /dev/null && __git_ps1)

This will disable calling __git_ps1 when it is not available, which you probably wouldn't need as superuser anyway.

Rodmun answered 4/3, 2015 at 17:40 Comment(2)
It's completely legal syntax.Rodmun
For anyone wanting to use this solution: it's supposed to be &> instead of >&Organization

© 2022 - 2024 — McMap. All rights reserved.