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

发布于 2024-10-08 16:30:53 字数 325 浏览 2 评论 0原文

我想测试我当前的目录是否是 git/hg/etc 的一部分。存储库,作为我的 shell 提示符的一部分。搜索了一下,我发现这个设置有类似的测试我想要的。所以我想我的问题是:最快的测试是什么来查看我是否在 git、hg、darcs 或 svn 存储库中?特别是,在我给出的链接中,他使用 gitbranch>; /dev/nullhg root > /dev/null;这些是最快的吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鸩远一方 2024-10-15 16:30:53

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

If you really need performance, you could check for .git or .hg directories. But this of course is not going to be 100% reliable.

爱,才寂寞 2024-10-15 16:30:53

测试 .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

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
煮酒 2024-10-15 16:30:53

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

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

可能不适合您,正如您在提示中所希望的那样。 (我讨厌超载我的提示:)

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 :)

复古式 2024-10-15 16:30:53

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

简而言之 'gitbranch 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

IMO git-show 应该提供一种反思给定存储库和工作目录的方法,因为 GIT_WORK_TREE 和 GIT_DIR 是如何工作的。

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.

以歌曲疗慰 2024-10-15 16:30:53

不知道这对你是否有帮助,但这是我的 PS1 for git 存储库:

$ 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 分支”有点疯狂,但我已经使用它很多年了,没有任何问题。 :-)

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. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文