Reputation: 41
I want to test if my present directory is part of a git/hg/etc. repository, as part of my shell prompt. Searching around a bit, I found this setup which has similar tests to what I want. And so I guess my question is: what are the fastest tests to see if I am in a git, hg, darcs, or svn repository? In particular, in the link I gave he uses git branch > /dev/null
and hg root > /dev/null
; are those the fastest?
Upvotes: 4
Views: 404
Reputation: 793
Don't know if it will be helpful for you but here is my PS1 for git repository:
$ egrep 'PS|RESET|PS1' ~/.bashrc
PS_AT='\[\033[1;30m\]'
PS_PWD='\[\033[1;34m\]'
RESET='\[\033[m\]'
export PS1='$(branch=$(git branch 2>/dev/null | grep "^*" | cut -d" " -f2-); [ -n "$branch" ] && (repo=$(git config --get remote.origin.url 2>/dev/null); ([ -n "$repo" ] && echo $repo || echo origin) | sed -r "s,/?.git$,," | awk -F"/" "{print \\$NF}" | xargs -r -I r echo -ne "\[\033[1;34m\][\[\033[0;34m\]r\[\033[1;34m\]:"; echo $branch | xargs -r -I r echo -e "\[\033[0;33m\]r\[\033[1;34m\]]\[\033[m\] "))'"\u${PS_AT}@${RESET}\h${PS_AT}:${PS_PWD}\W${PS_AT}\$${RESET} "
Yes, it's a bit crazy to call 'git branch' on every directory change but I've been living with that for ages without a problem. :-)
Upvotes: 0
Reputation: 1704
If you look at what git does, it's probably the simplest (nothing to write), fastest (it's written in C) and surest way (you're using the official algorithm).
In short 'git branch 2>/dev/null' is the way to go.
From a git working directory:
$ cd /d/qneill/gcc
$ strace -e trace=access,chdir,stat git branch 2>&1 | egrep -v '/etc/|/lib/'
stat(".git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access(".git/objects", X_OK) = 0
access(".git/refs", X_OK) = 0
access("/home/qneill/.gitconfig", R_OK) = 0
stat(".git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access(".git/config", R_OK) = 0
access("/home/qneill/.gitconfig", R_OK) = 0
access(".git/config", R_OK) = 0
access("/home/qneill/.gitconfig", R_OK) = 0
access(".git/config", R_OK) = 0
stat(".git/refs/remotes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
. . .
From a non-git directory:
$ mkdir -p /tmp/d1; cd /tmp/d1; pwd
/tmp/d1
$ strace -e trace=access,chdir,stat git branch 2>&1 | egrep -v '/etc/|/lib/'
stat(".git", 0x7fff32570650) = -1 ENOENT (No such file or directory)
access(".git/objects", X_OK) = -1 ENOENT (No such file or directory)
access("./objects", X_OK) = -1 ENOENT (No such file or directory)
chdir("..") = 0
stat(".git", 0x7fff32570650) = -1 ENOENT (No such file or directory)
. . .
fatal: Not a git repository (or any of the parent directories): .git
IMO git-show should provide a way to introspect about the given repository and working directory, because of how GIT_WORK_TREE and GIT_DIR work.
Upvotes: 0
Reputation: 107809
Testing for the existence of .git
, .hg
and so on is a very good approximation (definitely good enough for a prompt). But you can't just test in the current directory, you need to check parent directories as well. The following (untested) bash/ksh/zsh snippet sets vc
to the version control system the current directory appears to be under, or to the empty string if it can't find one.
vc=
if [ -d .svn ]; then
vc=svn
elif [ -d CVS ]; then
vc=cvs
else
d=..
while ! [ "$d" -ef / ]; do
if [ -d "$d/.bzr" ]; then
vc=bzr
elif [ -d "$d/_darcs" ]; then
vc=darcs
elif [ -d "$d/.git" ]; then
vc=git
elif [ -d "$d/.hg" ]; then
vc=hg
fi
if [ -n "$vc" ]; then break; fi
d=$d/..
done
fi
Upvotes: 1
Reputation: 96
morning, I had this terrible piece, because I could not remember.
#!/bin/bash -
MYPATH=/home/user
fail() {
echo "$1"
exit 1
}
test -d $MYPATH || fail "Can't chdir to $MYPATH, exiting .."
for x in $(locate $MYPATH | egrep "\.svn|CVS|\.hg|\.git" | awk -F '/' '{print $4}' | sort -u); do
if [ -n "$x" ]; then
find $x -name "\.svn" -o -name "CVS" -o -name "\.hg" -o -name "\.git" -type d| \
awk -v v="$MYPATH" -F '/' '{print v,$1,$2,$3}'| \
egrep "\.svn|CVS|\.hg|\.git";
else
fail "Hm, no repositories found"
fi
done
gives:
/home/user src onioncat .svn
/home/user src sqlmap .svn
/home/user src airprobe .git
/home/user src nagios CVS
Might not be for you, as you want it in the prompt. (I hate overloading my prompt :)
Upvotes: 0
Reputation: 138407
If you really need performance, you could check for .git
or .hg
directories. But this of course is not going to be 100% reliable.
Upvotes: 2