Làm cách nào để bỏ qua các tệp trong một thư mục trong Git?


544

Cú pháp thích hợp cho .gitignoretập tin để bỏ qua các tập tin trong một thư mục là gì?

Nó sẽ là

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*

hoặc là

/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*

?


5
sự .gitignorekhác biệt giữa các tập tin và thư mục mà nó bỏ qua? ví dụ, datavs data/có nghĩa là những thứ khác nhau?
Charlie Parker

6
@CharlieParker yes-ish: datasẽ bỏ qua các tệp thư mục phù hợp, data/sẽ chỉ bỏ qua các thư mục phù hợp.
Jox

Luôn nhớ nếu bạn đã dàn dựng hoặc cam kết tập tin mà bạn đang cố gắng bỏ qua, thì không có cách nào để bỏ qua nó :( Chỉ 2 xu của tôi sau khi nghĩ rằng tôi đã nhầm mẫu và lãng phí một phần tư giờ.
Adam

@Adam đúng bạn sẽ phải cập nhật .gitignore sau đó unstage / git rm - đã lưu tệp.
Chris McKnight

Câu trả lời:


374

HÌNH THỨC MẪU

  • Một dòng trống không khớp với các tệp, vì vậy nó có thể đóng vai trò là dấu phân tách để dễ đọc.

  • Một dòng bắt đầu với #vai trò như một bình luận.

  • Một tiền tố tùy chọn !phủ định mẫu; bất kỳ tệp phù hợp nào được loại trừ bởi một mẫu trước đó sẽ được đưa vào lại. Nếu một mẫu phủ định phù hợp, điều này sẽ ghi đè các nguồn mẫu ưu tiên thấp hơn.

  • Nếu mẫu kết thúc bằng dấu gạch chéo, nó sẽ bị xóa vì mục đích mô tả sau, nhưng nó sẽ chỉ tìm thấy khớp với một thư mục. Nói cách khác, foo/sẽ khớp với một thư mục foovà các đường dẫn bên dưới nó, nhưng sẽ không khớp với một tệp thông thường hoặc một liên kết tượng trưng foo(điều này phù hợp với cách thức hoạt động của pathspec nói chung trong git).

  • Nếu mẫu không chứa dấu gạch chéo /, git coi nó là mẫu toàn cầu shell và kiểm tra sự trùng khớp với tên đường dẫn liên quan đến vị trí của .gitignoretệp (liên quan đến toplevel của cây công việc nếu không phải từ .gitignoretệp).

  • Nếu không, xử lý git mô hình như một glob vỏ phù hợp cho tiêu dùng bằng fnmatch(3)với FNM_PATHNAMEcờ: ký tự đại diện trong mô hình sẽ không phù hợp với một /trong các tên đường dẫn. Ví dụ, Documentation/*.htmlphù hợp Documentation/git.htmlnhưng không Documentation/ppc/ppc.htmlhoặc tools/perf/Documentation/perf.html.

  • Một dấu gạch chéo hàng đầu khớp với phần đầu của tên đường dẫn. Ví dụ, /*.cphù hợp cat-file.cnhưng không mozilla-sha1/sha1.c.

Bạn có thể tìm thêm ở đây

git help gitignore
hoặc là
man gitignore


2
Làm cách nào tôi có thể đặt tệp .gitignore ở cấp cao nhất và làm cho nó hoạt động cho bất kỳ thư mục nào bên dưới nó? Cảm ơn bạn.
Royi 18/03/2015

104
-1 TL; DR và ​​hầu như không trả lời câu hỏi. Đó là về các thư mục, không phải các tập tin, vì vậy phần được in đậm chỉ là apropos với một số môn thể dục tinh thần. @Jefromi đã trực tiếp hơn.
Bob Stein

Tôi đã đọc người đàn ông này và câu trả lời của @ Jefromi tốt hơn - miễn là bạn cũng đọc cảnh báo của @ jox - và @ Luke Hutton có thể hữu ích hơn cho việc bỏ qua các tệp dự án IDE.
WillC

1
Đây thực sự là một bản sao-dán từ tài liệu git
mcont 17/8/18

1
Không chắc chắn (về cơ bản) dán sao chép một mantrang hoặc tài liệu chính thức là định dạng tốt nhất cho SO ...
jdk1.0

183

Nó sẽ là trước đây. Đi bằng phần mở rộng cũng thay vì cấu trúc thư mục.

Tức là tập tin bỏ qua phát triển C # của tôi:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

Cập nhật

Tôi nghĩ rằng tôi sẽ cung cấp một bản cập nhật từ các ý kiến ​​dưới đây. Mặc dù không trả lời trực tiếp câu hỏi của OP, hãy xem phần sau để biết thêm ví dụ về .gitignorecú pháp.

Wiki cộng đồng (liên tục được cập nhật):

.gitignore cho các dự án và giải pháp của Visual Studio

Có thể tìm thấy nhiều ví dụ khác với việc sử dụng ngôn ngữ cụ thể tại đây (nhờ nhận xét của Chris McKnight):

https://github.com/github/gitignore


5
@Stallman, đó là range. Vì vậy, nó phù hợp *.Objcũng như *.obj.
norbert

131

Các đường dẫn chứa dấu gạch chéo được lấy tương đối với thư mục chứa tệp .gitignore - thường là cấp cao nhất của kho lưu trữ của bạn, mặc dù bạn cũng có thể đặt chúng trong thư mục con.

Vì vậy, vì trong tất cả các ví dụ bạn đưa ra, các đường dẫn chứa dấu gạch chéo, hai phiên bản giống hệt nhau. Lần duy nhất mà bạn cần phải đặt một dấu gạch chéo hàng đầu là khi có không phải là một trong những con đường rồi. Ví dụ, để bỏ qua foo chỉ ở cấp cao nhất của kho lưu trữ, hãy sử dụng /foo. Đơn giản chỉ cần viết foosẽ bỏ qua bất cứ điều gì được gọi là foo bất cứ nơi nào trong kho lưu trữ.

Ký tự đại diện của bạn cũng dư thừa. Nếu bạn muốn bỏ qua toàn bộ thư mục, chỉ cần đặt tên cho nó:

lib/model/om

Lý do duy nhất để sử dụng ký tự đại diện theo cách bạn có là nếu sau đó bạn có ý định bỏ qua một cái gì đó trong thư mục:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo

5
Giải thích tốt hơn câu trả lời được chấp nhận cho câu hỏi này
eerrzz

78

Dấu gạch chéo hàng đầu chỉ ra rằng mục bỏ qua chỉ có hiệu lực đối với thư mục chứa tệp .gitignore. Việc chỉ định *.osẽ bỏ qua tất cả các tệp .o trong thư mục này và tất cả các /*.othư mục con, trong khi chỉ bỏ qua chúng trong thư mục đó, trong khi một lần nữa, /foo/*.osẽ chỉ bỏ qua chúng trong /foo/*.o.


34

Nếu bạn muốn đặt tệp .gitignore ở cấp cao nhất và làm cho nó hoạt động cho bất kỳ thư mục nào bên dưới nó sử dụng /**/.

Ví dụ: bỏ qua tất cả *.mapcác tệp trong một /src/main/thư mục và thư mục con sử dụng:

/src/main/**/*.map

Tôi cần phải làm điều này. Không chắc chắn tại sao bạn cần hai ** . Một là đủ cho tôi.
Novocaine

8
** cũng khớp các tệp trong thư mục con
petrsyn

Cảm ơn thông tin @petrsyn
Novocaine

30

Cả hai ví dụ trong câu hỏi thực sự là những ví dụ rất xấu có thể dẫn đến mất dữ liệu!

Lời khuyên của tôi: không bao giờ nối /*vào các thư mục trong tệp .gitignore, trừ khi bạn có lý do chính đáng!

Một lý do chính đáng sẽ là ví dụ những gì Jefromi đã viết: "nếu sau đó bạn có ý định bỏ qua một cái gì đó trong thư mục" .

Lý do tại sao nó không nên được thực hiện là việc gắn /*vào thư mục một mặt hoạt động theo cách nó bỏ qua đúng tất cả nội dung của thư mục, nhưng mặt khác nó lại có tác dụng phụ nguy hiểm:

Nếu bạn thực thi git stash -u(để tạm thời git clean -dfbỏ các tệp được theo dõi và không bị theo dõi) hoặc (để xóa các tệp không bị theo dõi nhưng giữ các tệp bị bỏ qua) trong kho lưu trữ của bạn, tất cả các thư mục bị bỏ qua với phần bổ sung /*sẽ bị xóa không thể đảo ngược !

Một số nền tảng

Tôi đã phải học điều này một cách khó khăn. Ai đó trong nhóm của tôi đang nối thêm /*vào một số thư mục trong .gitignore của chúng tôi. Theo thời gian tôi đã có những dịp mà các thư mục nhất định sẽ đột nhiên biến mất. Các thư mục có hàng gigabyte dữ liệu cục bộ cần thiết cho ứng dụng của chúng tôi. Không ai có thể giải thích điều đó và tôi luôn ngả mũ để tải lại tất cả dữ liệu. Sau một thời gian, tôi có một khái niệm rằng nó có thể phải làm với git stash. Một ngày nọ tôi muốn làm sạch repo cục bộ của mình (trong khi giữ các tệp bị bỏ qua) và tôi đang sử dụng git clean -dfvà một lần nữa dữ liệu của tôi đã biến mất. Lần này tôi đã có đủ và điều tra vấn đề. Cuối cùng tôi đã tìm ra lý do là sự bổ sung /*.

Tôi giả sử nó có thể được giải thích bằng cách nào đó bởi thực tế là directory/*bỏ qua tất cả nội dung của thư mục nhưng không phải chính thư mục. Do đó, nó không được xem là theo dõi hay bỏ qua khi mọi thứ bị xóa. Mặc dù git statusgit status --ignoredđưa ra một hình ảnh hơi khác nhau trên đó.

Cách sinh sản

Dưới đây là cách tái tạo hành vi. Tôi hiện đang sử dụng Git 2.8.4.

Một thư mục được gọi localdata/với một tệp giả trong đó ( important.dat) sẽ được tạo trong kho git cục bộ và nội dung sẽ bị bỏ qua bằng cách đưa /localdata/*vào .gitignoretệp. Khi một trong hai lệnh git được đề cập được thực thi ngay bây giờ, thư mục sẽ bị mất (bất ngờ).

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

Nếu bạn làm git status --ignoredở đây, bạn sẽ nhận được:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

Bây giờ hoặc làm

git stash -u
git stash pop

hoặc là

git clean -df

Trong cả hai trường hợp, thư mục bị cáo buộc bỏ qua localdatasẽ biến mất!

Không chắc đây có phải là một lỗi hay không, nhưng tôi đoán đó ít nhất là một tính năng không ai cần.

Tôi sẽ báo cáo điều đó với danh sách phát triển git và xem họ nghĩ gì về nó.


15

Nó sẽ là:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

hoặc thậm chí có thể:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

trong trường hợp đó filterformlà các thư mục duy nhất trong lib có basethư mục con cần được bỏ qua (xem nó như một ví dụ về những gì bạn có thể làm với dấu hoa thị).


14

Cái đầu tiên. Các đường dẫn tệp đó có liên quan đến vị trí tệp .gitignore của bạn.


2
Điều này chỉ đúng với các mẫu có dấu gạch chéo. Một tên thư mục duy nhất như "mydir" cũng sẽ bỏ qua các thư mục (và tệp) được đặt trong các thư mục con ở bất kỳ độ sâu nào. Chỉ đặt một dấu gạch chéo ở phía trước sẽ làm cho nó tương đối từ nơi tệp .gitignore của bạn.
Jox

4

Tôi đang duy trì dịch vụ dựa trên GUI và CLI cho phép bạn tạo các .gitignoremẫu rất dễ dàng tại https://www.gitignore.io .

Bạn có thể nhập các mẫu bạn muốn trong trường tìm kiếm hoặc cài đặt bí danh dòng lệnh và chạy

$ gi swift,osx


0

Một tệp .gitignore mẫu có thể trông giống như một tệp bên dưới cho dự án Android Studio

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle
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.