Определите, находится ли каталог под 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 самого лучшего, что я могу сделать?

Ответ 1

В 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, когда вы не находитесь в репо, если это имеет для вас значение.

Ответ 2

Просто нашел это в git help rev-parse

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

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

Ответ 3

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

import git

...

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

Ответ 4

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

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

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

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

Ответ 5

Для записи используйте статус git или аналогичный, это просто для полноты::)

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

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

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

Ответ 6

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

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

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

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

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

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

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

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

Ответ 7

Добавьте это в свой .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

От git снова помогите rev-parse, я думаю, вы можете сделать что-то вроде:

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

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

Ответ 9

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

require 'pathname'

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

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