2010-01-11 12 views
59

如何判斷給定的目錄是否是git存儲庫的一部分?確定目錄是否在git控制下

(下面是Python,但bash或東西就可以了。)

os.path.isdir('.svn') 

會告訴你,如果當前目錄是由Subversion的控制。水銀和Git只需要在倉庫的頂部.hg/git的,所以我hg可以使用

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

git status返回非零(錯誤)退出,如果沒什麼改變狀態。

正在迭代尋找.git我自己最好的路徑嗎?

+4

犯規'git的status'抱怨不是,如果你把它叫做路徑上回購的一部分?我認爲捕獲並比較一行或兩行文本比迭代樹更好。 – prodigitalson 2010-01-11 20:18:41

+2

它是的,退出我的機器上的狀態128。 – falstro 2010-01-11 20:23:08

+0

速度不是一個大問題,只是我喜歡在可能的情況下以正確的方式做事。也許我只是迭代父輩的dirs。 – Grumdrig 2010-01-11 20:31:54

回答

42

在ruby中,system('git rev-parse')將返回true,如果當前目錄位於git repo中,則返回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一些輸出時,你是不是在回購協議,如果這對你很重要。

+3

謝謝!我正在使用'os.path.isdir(「。git」)或os.system('git rev-parse 2>/dev/null>/dev/null')== 0' – Grumdrig 2010-01-11 20:51:39

+6

@grumdrig os.path .isdir(「.git」)不起作用,因爲.git可以是一個只包含git目錄路徑的常規文件。使用git rev-parse。 – 2011-09-15 13:14:54

+0

但是這樣可以,因爲那麼調用'git rev-parse'的'或'子句就會啓動。(''或'在代碼中 - 它沒有描述我正在考慮的兩種替代方案。) – Grumdrig 2011-09-15 18:09:15

4

那麼,該目錄也可以被.gitignore文件忽略 - 所以你需要檢查一個.git倉庫,如果有,請解析.gitignore以查看該目錄是否確實存在於git倉庫中。

你究竟想做什麼?可能有一個更簡單的方法來做到這一點。

編輯: 你的意思是「這個目錄是GIT存儲庫的根目錄」還是,你的意思是「這個目錄是否是GIT存儲庫的一部分」?

對於第一個,然後檢查是否有.git - 因爲這是在根,並且你完成了。 對於第二個,一旦你確定你在GIT倉庫中,你需要檢查.gitignore來查找有問題的子目錄。

+0

我有一個Python的工具包我使用各種版本的控制程序,這樣我就可以獲取狀態,例如,獨立的VC有什麼在使用。 Git是我的新增功能。我不需要那麼強大,以至於不能考慮.gitignore,真的。 – Grumdrig 2010-01-11 20:29:16

+0

後者。[15個字符:] – Grumdrig 2010-01-11 20:36:42

+0

保持與您當前的方法保持一致可能是最好的(除非您的工具對每個VCS執行不同的操作)。 從長遠來看,它可能更簡單地堅持目錄遍歷系統以找出什麼是什麼,然後根據需要轉到自定義操作。 – Trevoke 2010-01-11 20:38:01

4

爲了記錄在案,使用git的狀態或類似的,這僅僅是爲了完整性::)

搜索向上樹是根本不算真的,在bash你可以做到這一點簡單的一行(如果你把它在一行上...);)如果找到一個,則返回0,否則返回1。

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

會向上搜索一個.git文件夾。

+0

我喜歡這個。 TY。 – lzap 2011-03-01 13:02:30

+0

嗯,它爲我循環。我必須:while [「$ d」!=「」];做 – lzap 2011-03-01 13:13:24

+0

@lzap;你是對的../a/b/c變成/ a/b變成/ a變成了無。 – falstro 2011-03-01 13:19:16

78

剛剛發現這git help rev-parse

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

打印true如果是在工作樹,false如果是在「git的」樹,如果它既不致命錯誤。 'true'和'false'都打印在退出狀態爲0的stdout上,致命錯誤打印在退出狀態爲128的stderr上。

+0

要檢查文件夾是否在git下,即使該文件夾不存在,我使用:'\'cd「#{dir}」&& git rev-parse --is-inside-work-tree \''。如果在git控制下返回「true」。如果文件夾存在但不在git下或文件夾不存在,則返回「」。 – peterept 2014-05-15 01:23:50

+0

其實'git rev-parse --is-inside-work-tree'可以讓我們知道我們在Git目錄下的位置。它將在directy中返回true,如果在.git文件夾或裸倉庫中則返回false。 – Dereckson 2014-11-18 18:16:53

+2

爲什麼這個答案得到這麼多的票。答案是相當古老的,所以也許git的行爲改變了。我回答了git版本1.7.1。 「git rev-parse --is-inside-work-tree」只顯示true,如果該目錄是在git控制的目錄下的分層結構。但是,我們不能推斷出我們正在檢查的目錄是在git控制下,這意味着在這個目錄上執行了「git add」。 – user637338 2015-02-04 11:19:57

1

將此添加到您的.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*]: 
+1

不要在腳本中使用瓷器(用戶界面)命令:它們的輸出可能會改變。改爲使用'git rev-parse'和'git symbolic-ref'。參見'contrib/completion/git-completion.bash'中的'__git_ps1'函數 – 2010-01-12 16:04:43

1

git的幫助下再次REV-解析,我想你可以這樣做:

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

,並檢查命令返回目錄路徑本身。根據手冊git rev-parse返回目錄的路徑,如果參數包含git倉庫或者是包含git倉庫路徑的文件。

2

我做實驗,看看有什麼混帳認爲作爲一個Git倉庫的一個位。

截至1.9.1,最小的目錄結構必須是.git目錄內的Git的考慮是:

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

通過rev-parse所認可。

這顯然也是一個腐敗的倉庫中,最有用的命令就會失敗。

的士氣是:像任何其他格式檢測,誤報是不可避免的,特別是這裏最小的回購就是這麼簡單。

如果你想要的東西穩健,而不是檢測它是否是一個Git回購,嘗試做任何你想做的事,並引發錯誤並處理他們,如果它失敗。

請求寬恕比獲得權限要容易得多。

+1

這是準確的。相關的Git代碼可以在[is_git_directory](https://github.com/git/git/blob/57dd3dd/setup.c#L297)和[validate_headref](https://github.com/git/git)中找到/blob/57dd3dd/path.c#L636)。 – 2017-11-14 14:58:58

-1

如果您更願意尋找一個.git目錄,這裏是做在Ruby中的可愛方式:

require 'pathname' 

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

我無法找到類似的東西在Python提升。

5

隨着gitpython,可以使這樣的功能:

import git 

... 

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