我如何(快速)判断$ PWD是否在git / hg存储库中?

时间:2010-12-18 00:30:29

标签: shell version-control

我想测试我的当前目录是否是git / hg / etc的一部分。存储库,作为我的shell提示的一部分。搜索了一下,我发现this setup有与我想要的类似的测试。所以我想我的问题是:如果我在git,hg,darcs或svn存储库中,最快的测试是什么?特别是,在我给出的链接中,他使用了git branch > /dev/nullhg root > /dev/null;是那些最快的?

5 个答案:

答案 0 :(得分:2)

如果您确实需要性能,可以检查.git.hg目录。但这当然不会100%可靠。

答案 1 :(得分:1)

测试.git.hg等是否存在是一个非常好的近似值(绝对足以提示)。但是你不能只在当前目录中测试,你也需要检查父目录。以下(未经测试的)bash / ksh / zsh片段将vc设置为当前目录所在的版本控制系统,如果找不到,则设置为空字符串。

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

答案 2 :(得分:0)

早上,我有这件可怕的作品,因为我记不住了。

#!/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

给出:

/home/user src onioncat .svn

/home/user src sqlmap .svn

/home/user src airprobe .git

/home/user src nagios CVS

可能不适合你,因为你在提示中想要它。 (我讨厌超载我的提示:)

答案 3 :(得分:0)

如果你看看git做了什么,它可能是最简单的(没有写),最快(用C语言编写)和最可靠的方式(你使用的是官方算法)。

简而言之,'git branch 2> / dev / null'是最佳选择。

从git工作目录:

$ 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
. . .

来自非git目录:

$ 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

由于GIT_WORK_TREE和GIT_DIR如何工作,IMO git-show应该提供一种内省给定存储库和工作目录的方法。

答案 4 :(得分:0)

不知道它是否对你有帮助,但这里是我的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} "

是的,在每个目录更改时调用'git branch'有点疯狂,但我已经和它一起生活了很长时间没有问题。 : - )