Определите, находится ли каталог под контролем git - PullRequest
63 голосов
/ 11 января 2010

Как узнать, является ли данный каталог частью репозитория 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 ]

82 голосов
/ 11 января 2010

Только что нашел это в git help rev-parse

git rev-parse --is-inside-work-tree

печатает true, если оно находится в рабочем дереве, false, если оно находится в дереве .git, и фатальную ошибку, если его нет. И «истина», и «ложь» выводятся на стандартный вывод со статусом выхода 0, фатальная ошибка выводится на стандартный вывод 128 со статусом выхода.

43 голосов
/ 11 января 2010

В ruby, system('git rev-parse') вернет true, если текущий каталог находится в git-репо, и false в противном случае. Я полагаю, что питонический эквивалент должен работать аналогично.

РЕДАКТИРОВАТЬ: Конечно:

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

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

Обратите внимание, что на STDERR есть выход, если вы не в репо, если это важно для вас.

6 голосов
/ 10 октября 2016

С помощью gitpython вы можете создать такую ​​функцию:

import git

...

def is_git_repo(path):
    try:
        _ = git.Repo(path).git_dir
        return True
    except git.exc.InvalidGitRepositoryError:
        return False
4 голосов
/ 11 января 2010

Для записи используйте git status или подобное, это только для полноты::)

Поиск вверх по дереву на самом деле не важен, в bash вы можете сделать этот простой однострочный (если вы поместите его в одну строку ...);) Возвращает 0, если он найден, 1 в противном случае.

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

будет искать вверх в поисках папки .git.

4 голосов
/ 11 января 2010

Что ж, каталог также может быть проигнорирован файлом .gitignore - поэтому вам нужно проверить наличие репозитория .git, и, если он есть, проанализировать .gitignore, чтобы узнать, действительно ли этот каталог находится в репозитории git.

Что именно вы хотите сделать? Там может быть более простой способ сделать это.

EDIT: Вы имеете в виду «Является ли этот каталог корнем репозитория GIT» или «Этот каталог является частью репозитория GIT»?

Для первого, затем просто проверьте, есть ли .git - так как это в корне, и все готово. Во втором случае, когда вы определили, что находитесь внутри GIT-репозитория, вам нужно проверить .gitignore для рассматриваемого подкаталога.

3 голосов

Трудно определить, что такое .git/ хранилище

Я немного поэкспериментировал, чтобы увидеть, что Git считает хранилищем Git.

Начиная с 1.9.1, минимальная структура каталогов, которая должна быть в каталоге .git, чтобы Git считал его:

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

как признано rev-parse.

Очевидно, это также поврежденный репозиторий, в котором большинство полезных команд не будут работать.

Мораль такова: как и при обнаружении любого другого формата, ложные срабатывания неизбежны, особенно здесь, когда минимальное репо настолько просто.

Если вы хотите что-то надежное, вместо того, чтобы определять, является ли это Git-репо, попробуйте делать все, что вы хотите, и выявлять ошибки и устранять их, если это не удается.

Проще просить прощения, чем получать разрешение.

2 голосов
/ 30 января 2013

С git help rev-parse еще раз, я думаю, вы можете сделать что-то вроде:

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

и проверьте, возвращает ли команда сам путь к каталогу. Согласно инструкции git rev-parse возвращает путь к каталогу, если аргумент содержит git-репо или является файлом, который содержит путь к git-репо.

0 голосов
/ 18 мая 2018

Используя git rev-parse --is-inside-work-tree вместе с subprocess.Popen, вы можете проверить, выводится ли "true" из вывода, указывающего, что каталог имеет git-репо:

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))
0 голосов
/ 24 марта 2015

Если вы предпочитаете искать каталог .git, вот хороший способ сделать это в Ruby:

require 'pathname'

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

Я не могу найти что-то похожее на Ascend в Python.

0 голосов
/ 11 января 2010

Добавьте это к вашему .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*]: 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...