2010-01-11 18 views
59

Làm cách nào để biết thư mục đã cho là một phần của bộ đệm git?Xác định xem thư mục có dưới sự kiểm soát git hay không

(Sau đây là trong python, nhưng bash hay cái gì sẽ là tốt.)

os.path.isdir('.svn') 

sẽ cho bạn biết nếu thư mục hiện hành được điều khiển bởi Subversion. Mercurial và Git chỉ có một .hg/.git ở phía trên cùng của kho, vì vậy cho hg tôi có thể sử dụng

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

nhưng git status trả về một khác không (lỗi) trạng thái thoát nếu không có gì thay đổi.

Đang lặp lại đường dẫn tìm kiếm .git bản thân mình là điều tốt nhất tôi có thể làm?

+4

Doesnt 'git status' phàn nàn về việc không là một phần của một repo nếu bạn gọi nó là trên một con đường? tôi sẽ nghĩ rằng chụp và so sánh một hoặc hai dòng văn bản sẽ tốt hơn so với lặp lại sao lưu cây. – prodigitalson

+2

nó có, thoát trạng thái 128 trên máy của tôi. – falstro

+0

Tốc độ không phải là vấn đề lớn, ngoại trừ việc tôi thích làm mọi việc đúng cách khi có thể. Có lẽ tôi sẽ chỉ lặp lại các thư mục phụ huynh. – Grumdrig

Trả lời

42

Trong ruby, system('git rev-parse') sẽ trả về true nếu thư mục hiện tại nằm trong repo git và false nếu không. Tôi tưởng tượng tương đương pythonic nên hoạt động tương tự.

EDIT: chắc đủ:

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

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

Lưu ý rằng có một số lượng trên thiết bị lỗi chuẩn khi bạn đang không ở trong một repo, nếu điều đó quan trọng đối với bạn.

+3

Cảm ơn! Tôi đang đi với 'os.path.isdir (". Git ") hoặc os.system ('git rev-parse 2>/dev/null>/dev/null') == 0' – Grumdrig

+6

@grumdrig os.path .isdir (". git") sẽ không hoạt động, vì .git có thể là một tệp thông thường chỉ chứa đường dẫn đến thư mục git. Sử dụng git rev-parse. –

+0

Nhưng điều đó sẽ không sao, bởi vì sau đó mệnh đề 'hoặc' gọi' git rev-parse' sẽ khởi động. (Đó là 'hoặc' là mã - nó không mô tả hai lựa chọn thay thế mà tôi đang xem xét.) – Grumdrig

4

Vâng, thư mục cũng có thể bị bỏ qua bởi tệp .gitignore - vì vậy bạn cần kiểm tra kho .git và nếu có, hãy phân tích cú pháp .gitignore để xem thư mục đó có thực sự nằm trong kho git hay không .

Chính xác bạn muốn làm gì? Có thể có một cách đơn giản hơn để thực hiện việc này.

EDIT: Bạn có nghĩa là "Thư mục này là thư mục gốc của kho lưu trữ GIT" hay, ý của bạn là "Phần thư mục này có nằm trong kho GIT" không?

Đối với người đầu tiên, sau đó chỉ cần kiểm tra xem có một .git - vì đó là ở gốc và bạn đã hoàn tất. Đối với thứ hai, khi bạn đã xác định rằng bạn đang ở trong một kho lưu trữ GIT, bạn cần phải kiểm tra .gitignore cho thư mục con được đề cập.

+0

Tôi đã có một công cụ python bao gồm các chương trình kiểm soát phiên bản khác nhau mà tôi sử dụng, vì vậy tôi có thể nhận trạng thái, ví dụ: độc lập với những gì VC đang sử dụng. Git là một bổ sung mới cho tôi. Tôi không cần phải mạnh mẽ như vậy để xem xét .gitignore, thực sự. – Grumdrig

+0

Sau đó.[15 ký tự:] – Grumdrig

+0

Duy trì nhất quán với phương pháp hiện tại của bạn có lẽ là tốt nhất (trừ khi tất nhiên, công cụ của bạn thực hiện điều gì đó khác với mỗi VCS). Có thể, về lâu dài, đơn giản hơn là phải dính vào hệ thống tra cứu thư mục để tìm ra cái gì là gì, và sau đó đi đến các hành động tùy chỉnh, nếu cần thiết. – Trevoke

4

Đối với hồ sơ, tình trạng sử dụng git hoặc tương tự, đây là chỉ cho đầy đủ: :)

Tìm kiếm lên một cái cây là không có vấn đề gì thực sự, trong bash bạn có thể làm điều này đơn giản một-liner (nếu bạn đặt nó trên một dòng ...);) Trả về 0 nếu có một hàng, 1 cách khác.

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

sẽ tìm kiếm phía trên để tìm thư mục .git.

+0

Tôi thích cái này. Ty. – lzap

+0

Hmmmm nó vòng cho tôi. Tôi phải: trong khi ["$ d"! = ""]; làm – lzap

+0

@lzap; bạn đúng ../a/b/c trở thành/a/b trở thành/a trở thành không có gì. – falstro

78

Chỉ cần thấy điều này trong git help rev-parse

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

in true nếu nó là trong cây công trình, false nếu nó trong cây 'git', và lỗi nghiêm trọng nếu nó không phải. Cả 'true' và 'false' được in trên stdout với trạng thái thoát là 0, lỗi nghiêm trọng được in trên stderr với trạng thái thoát là 128.

+0

Để kiểm tra xem thư mục có dưới git hay không, ngay cả khi thư mục không tồn tại, tôi đã sử dụng: '\' cd "# {dir}" && git rev-parse - trong-công việc-cây \ ''. Trả về "true" nếu dưới git control. Nếu thư mục tồn tại nhưng không phải dưới git hoặc nếu thư mục không tồn tại, nó sẽ trả về "". – peterept

+0

Thực ra, 'git rev-parse --is-inside-work-tree' cho phép biết chúng ta ở đâu trong thư mục Git. Nó sẽ trả về true trong directy làm việc, false nếu trong thư mục .git hoặc một kho trống. – Dereckson

+2

Tại sao câu trả lời này nhận được rất nhiều phiếu bầu. Câu trả lời là khá cũ, vì vậy có thể hành vi trong git changed.I trả lời cho git phiên bản 1.7.1. "git rev-parse --is-inside-work-tree" chỉ hiển thị đúng, nếu thư mục được phân cấp theo thư mục được kiểm soát git. NHƯNG, nhưng người ta không thể suy ra rằng thư mục chúng tôi đang kiểm tra là dưới git kiểm soát, có nghĩa là "git add" đã được thực hiện trên thư mục này. – user637338

1

Thêm số này vào .bash_profile của bạn và lời nhắc của bạn sẽ luôn hiển thị nhánh git hoạt động và liệu bạn có thay đổi không được cam kết hay không.

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> ' 

Bạn sẽ thấy điều này:

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

Không sử dụng lệnh sứ (giao diện người dùng) trong tập lệnh: đầu ra của chúng có thể thay đổi. Sử dụng 'git rev-parse' và' git symbolic-ref' để thay thế. Xem thêm hàm '__git_ps1' trong 'contrib/completion/git-completion.bash' –

1

Từ git giúp rev-phân tích lần nữa, tôi nghĩ bạn có thể làm điều gì đó như:

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

và kiểm tra xem lệnh trả về đường dẫn thư mục. Theo hướng dẫn sử dụng git rev-parse trả về đường dẫn đến thư mục nếu đối số có chứa một repo git hoặc là một tệp có chứa đường dẫn đến một repo git.

2

Tôi đã thử nghiệm một chút để xem Git xem như là kho lưu trữ Git.

Tính đến 1.9.1, cấu trúc thư mục tối thiểu phải được bên trong một thư mục .git cho Git để xem xét đó là:

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

như được công nhận bởi rev-parse.

Nó cũng rõ ràng là một kho lưu trữ bị hỏng trong đó hầu hết các lệnh hữu ích sẽ thất bại.

Tinh thần là: giống như bất kỳ phát hiện định dạng nào khác, dương tính giả là không thể tránh khỏi, đặc biệt ở đây rằng repo tối thiểu rất đơn giản.

Nếu bạn muốn một cái gì đó mạnh mẽ, thay vì phát hiện nếu nó là một repo Git, cố gắng làm bất cứ điều gì bạn muốn làm, và nâng cao lỗi và đối phó với họ nếu nó không thành công.

Dễ dàng hơn khi yêu cầu sự tha thứ hơn là xin phép.

+1

Điều này là chính xác. Bạn có thể tìm thấy mã Git có liên quan trong [is_git_directory] (https://github.com/git/git/blob/57dd3dd/setup.c#L297) và [validate_headref] (https://github.com/git/git /blob/57dd3dd/path.c#L636). –

-1

Nếu bạn muốn tìm kiếm một thư mục .git, đây là một cách dễ thương để làm điều đó trong Ruby:

require 'pathname' 

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

Tôi không thể tìm thấy một cái gì đó tương tự như lên bằng Python.

5

Với gitpython, bạn có thể thực hiện một chức năng như thế này:

import git 

... 

def is_git_repo(path): 
    try: 
     _ = git.Repo(path).git_dir 
     return True 
    except git.exc.InvalidGitRepositoryError: 
     return False 
Các vấn đề liên quan