Sự khác biệt giữa thư mục bỏ qua Git và thư mục / * là gì?


108

Tôi bối rối về cách chính xác để bỏ qua nội dung của một thư mục trong git.

Giả sử tôi có cấu trúc thư mục sau:

my_project  
     |--www  
         |--1.txt  
         |--2.txt
     |--.gitignore

Sự khác biệt giữa việc đặt điều này là gì:

www

Và điều này?

www/*

Lý do tôi hỏi câu hỏi này là: Trong git, nếu một thư mục trống, git sẽ không đưa thư mục trống đó vào kho lưu trữ. Vì vậy, tôi đã thử giải pháp là thêm một tệp .gitkeep bổ sung trong thư mục để nó không bị trống. Khi tôi đang thử giải pháp đó, nếu trong tệp .gitignore, tôi viết như sau:

www
!*.gitkeep

Nó không hoạt động (Ý định của tôi là bỏ qua tất cả nội dung dưới www nhưng giữ lại thư mục). Nhưng nếu tôi thử những cách sau:

www/* 
!*.gitkeep

Sau đó, nó hoạt động! Vì vậy, tôi nghĩ rằng nó phải có một số khác biệt giữa hai cách tiếp cận.


Một sự khác biệt đơn giản giữa binbin/là cái trước sẽ bỏ qua tệp hoặc thư mục, cái sau chỉ là những thư mục. Tôi không biết sự khác biệt vớibin/*
Đại Tá Panic

Câu trả lời:


203

Có sự khác biệt giữa www, www/www/*.

Về cơ bản, từ tài liệu và các bài kiểm tra của riêng tôi, wwwtìm thấy sự trùng khớp với một tệp hoặc một thư mục, www/chỉ khớp với một thư mục, trong khi www/*khớp với các thư mục và tệp bên trong www.

Tôi sẽ chỉ thảo luận về sự khác biệt giữa www/www/*ở đây, vì sự khác biệt giữa wwwwww/là rõ ràng.

Đối với www/, git bỏ qua wwwchính thư mục , có nghĩa là git thậm chí sẽ không nhìn vào bên trong. Nhưng đối với www/*, git sẽ kiểm tra tất cả các tệp / thư mục bên trong wwwvà bỏ qua tất cả chúng bằng mẫu *. Nó dường như dẫn đến kết quả tương tự vì git sẽ không theo dõi một thư mục trống wwwnếu tất cả các tệp / thư mục con của nó bị bỏ qua. Và thực sự kết quả sẽ không có gì khác biệt đối với trường hợp của OP với www/hoặcwww/* độc lập. Nhưng nó sẽ tạo ra sự khác biệt nếu nó được kết hợp với các quy tắc khác.

Ví dụ, nếu chúng ta muốn chỉ bao gồm www/1.txtmà bỏ qua tất cả những thứ khác bên trong wwwthì sao?

Sau đây .gitignoresẽ không hoạt động.

www/
!www/1.txt

Trong khi những điều sau đây .gitignorehoạt động, tại sao?

www/*
!www/1.txt

Đối với trước đây, git chỉ bỏ qua thư mục wwwvà thậm chí sẽ không nhìn vào bên trong để bao gồm www/1.txtlại. Quy tắc đầu tiên loại trừ thư mục mẹ wwwnhưng không loại trừwww/1.txt và kết quả là www/1.txtkhông thể " bao gồm lại ".

Nhưng đối với phần sau, git đầu tiên bỏ qua tất cả các tệp / folers dưới www , và sau đó bao gồm lại một trong số chúng www/1.txt.

Đối với ví dụ này, các dòng sau trong tài liệu có thể giúp:

Tiền tố tùy chọn "!" mà phủ định mẫu; bất kỳ tệp phù hợp nào bị loại trừ bởi mẫu trước đó sẽ được đưa vào lại. Không thể bao gồm lại tệp nếu thư mục mẹ của tệp đó bị loại trừ.


Đừng bạn nghĩ www/1.txtvà sau đó www/sẽ làm tương tự như phương pháp thứ hai ...
Naveed Butt

8

Tôi chỉ đang phân tích tài liệu và theo như tôi có thể nói thì chúng chỉ khác nhau ở các mẫu nâng cao hơn, ví dụ:

$ cat .gitignore
    # exclude everything except directory foo/bar
    /*
    !/foo
    /foo/*
    !/foo/bar

Tôi đã kiểm tra ở trên, và nếu bạn thay thế !/foobằng !/foo/*, bạn thực sự nhận được một kết quả khác.

Ghi chú

foo

Sẽ loại trừ bất kỳ tệp nào foo, nhưng

foo/

sẽ chỉ loại trừ các thư mục có tên foo.


3

Ngoài những câu trả lời hoàn toàn tốt mà bạn đã có, bạn cần lưu ý rằng bạn có thể có .gitignoreở bất kỳ đâu trong dự án của mình, bao gồm cả các thư mục con.

Vì vậy, nếu bạn muốn bỏ qua tất cả các file bên trong www, nhưng whant các wwwthư mục được phiên bản, thay vì sử dụng một sản phẩm nào .gitkeep, .dummyhoặc bất cứ tên bạn chọn, tại sao không sử dụng một .gitignoreở đó, nói để bỏ qua tất cả các file?

/
|- .gitignore   (a)
\- www
    |- .gitignore   (b)
    |- 1.jpg
    \- 2.jpg

Trong thư mục gốc .gitignore(a), bạn không nói gì về wwwthư mục hoặc nội dung của nó.

Trong www/.gitignore(b) bạn đặt như sau:

# ignore all files in this folder except this .gitignore
*
!.gitignore

Bằng cách này, mọi thứ trông có tổ chức hơn (ít nhất là với tôi).


1

Để bỏ qua mọi thứ trong một thư mục ngoại trừ tệp dotfiles, bạn có thể sử dụng mô hình toàn cầu sau trong .gitignore:

www/[^.]*

Vì vậy, không cần thêm .gitignore, chỉ cần thêm một .keeptệp vào wwwthư mục của bạn .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.