确定目录是否受git控制

时间:2010-01-11 20:07:44

标签: python git

如何判断给定目录是否是git存储库的一部分?

(以下是在python中,但bash或者其他什么都没问题。)

os.path.isdir('.svn')

将告诉您当前目录是否由Subversion控制。 Mercurial和Git只在存储库的顶部有一个.hg / .git,所以hg我可以使用

os.system('hg -q stat 2> /dev/null > /dev/null') == 0)

但如果没有任何更改,git status将返回非零(错误)退出状态。

正在迭代寻找.git我自己能做的最好的路径吗?

10 个答案:

答案 0 :(得分:81)

刚刚在git help rev-parse

中找到了这个
git rev-parse --is-inside-work-tree

如果它在工作树中,则打印true,如果它在'.git'树中,则打印false,如果不是,则打印致命错误。 “true”和“false”都打印在stdout上,退出状态为0,致命错误打印在stderr上,退出状态为128.

答案 1 :(得分:43)

在ruby中,如果当前目录在git repo中,system('git rev-parse')将返回true,否则返回false。我认为pythonic等价物应该类似。

编辑:果然:

# in a git repo, running ipython
>>> system('git rev-parse')
0

# not in a git repo
>>> system('git rev-parse')
32768

请注意,当您不在回购中时,STDERR上会有一些输出,如果这对您很重要。

答案 2 :(得分:6)

使用gitpython,您可以制作如下函数:

import git

...

def is_git_repo(path):
    try:
        _ = git.Repo(path).git_dir
        return True
    except git.exc.InvalidGitRepositoryError:
        return False

答案 3 :(得分:4)

嗯,.gitignore文件也可以忽略该目录 - 所以你需要检查.git存储库,如果有的话,解析.gitignore以查看该目录是否确实在git存储库中。

你到底想做什么?可能有一种更简单的方法可以做到这一点。

编辑: 你的意思是“这个目录是GIT存储库的根目录”还是,你的意思是“这个目录是否是GIT存储库的一部分”?

对于第一个,然后检查是否有.git - 因为那是在根,你就完成了。 对于第二个,一旦您确定自己在GIT存储库中,就需要检查.gitignore以查找相关子目录。

答案 4 :(得分:4)

对于记录,使用git status或类似,这只是为了完整性::))

向上搜索树真的没什么大不了的,在bash中你可以做这个简单的单行程序(如果你把它放在一行......);)如果找到一个则返回0,否则返回1。

d=`pwd`
while [ "$d" != "" ]; do
  [ -d "$d"/.git ] && exit 0
  d=${d%/*}
done
exit 1

将向上搜索以查找.git文件夹。

答案 5 :(得分:3)

很难定义.git/存储库的内容

我做了一些实验,看看Git认为Git存储库是什么。

从1.9.1开始,Git必须在.git目录中的最小目录结构是:

mkdir objects refs
printf 'ref: refs/' > HEAD

rev-parse识别。

它显然也是一个腐败的存储库,大多数有用的命令都会失败。

士气是:像任何其他格式检测一样,误报是不可避免的,特别是在这里,最小的回购是如此简单。

如果你想要一些健壮的东西,而不是检测它是否是一个Git回购,试着去做你想做的事情,并提出错误并在它失败时处理它们。

  

请求宽恕比获得许可更容易。

答案 6 :(得分:2)

再次从 git help rev-parse ,我认为您可以执行以下操作:

git rev-parse --resolve-git-dir <directory> 

并检查命令是否返回目录路径本身。根据手册git rev-parse返回目录的路径,如果参数包含git repo或者是包含git repo路径的文件。

答案 7 :(得分:0)

将此添加到.bash_profile,您的提示将始终显示活动的git分支以及您是否有未提交的更改。

function parse_git_dirty {
  [[ $(git status 2> /dev/null | tail -n1) != "nothing to commit (working directory clean)" ]] && echo "*"
}
function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/[\1$(parse_git_dirty)]/"
}

export PS1=' \[\033[0;33m\]\w\[\033[00m\]\[\033[01;00m\]$(parse_git_branch): ' #PS1='\w> '

你会看到:

 ~: 
 ~: cd code/scala-plugin/
 ~/code/scala-plugin[master*]: 

答案 8 :(得分:0)

如果您更喜欢寻找.git目录,可以在Ruby中使用这种方式:

require 'pathname'

def gitcheck()
  Pathname.pwd.ascend {|p| return true if (p + ".git").directory? }
  false
end

我无法在Python中找到类似提升的东西。

答案 9 :(得分:0)

使用git rev-parse --is-inside-work-treesubprocess.Popen,您可以检查输出中是否打印了“true”,表明目录中有一个git repo:

import subprocess

repo_dir = "../path/to/check/" 

command = ['git', 'rev-parse', '--is-inside-work-tree']
process = subprocess.Popen(command, stdout=subprocess.PIPE, cwd=repo_dir,
                           universal_newlines=True)
process_output = process.communicate()[0]

is_git_repo = str(process_output.strip())

if is_git_repo == "true":
    print("success! git repo found under {0}".format(repo_dir))
else:
    print("sorry. no git repo found under {0}".format(repo_dir))