ฉันจะข้ามไฟล์ในไดเรกทอรีใน Git ได้อย่างไร?


544

ไวยากรณ์ที่เหมาะสมสำหรับ.gitignoreไฟล์ที่จะข้ามไฟล์ในไดเรกทอรีคืออะไร?

มันจะเป็น

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

หรือ

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

?


5
ความ.gitignoreแตกต่างระหว่างไฟล์และไดเรกทอรีที่ถูกละเว้น เช่นdatavs data/หมายถึงสิ่งที่แตกต่างกันหรือไม่
Charlie Parker

6
@CharlieParker yes-ish: dataจะไม่สนใจไฟล์และไดเรกทอรีที่ตรงกันdata/จะไม่สนใจเฉพาะไดเรกทอรีที่ตรง
jox

โปรดจำไว้เสมอว่าคุณได้จัดทำหรือคอมมิทไฟล์ที่คุณพยายามเพิกเฉยแล้วไม่มีทางเพิกเฉย: (แค่ 2 เซ็นต์ของฉันหลังจากคิดว่าฉันทำผิดแบบและเสียเวลาประมาณหนึ่งชั่วโมง
อดัม

@ อดัมถูกต้องคุณจะต้องอัปเดต. gitignore แล้ว unstage / git rm - เก็บไฟล์ไว้
Chris McKnight

คำตอบ:


374

รูปแบบรูปแบบ

  • บรรทัดว่างไม่ตรงกับไฟล์ดังนั้นจึงสามารถใช้เป็นตัวคั่นเพื่อให้สามารถอ่านได้

  • บรรทัดที่ขึ้นต้นด้วย#ทำหน้าที่เป็นความคิดเห็น

  • คำนำหน้าตัวเลือก!ซึ่งขัดแย้งกับรูปแบบ; ไฟล์ที่ตรงกันใด ๆ ที่ยกเว้นโดยรูปแบบก่อนหน้านี้จะถูกรวมอีกครั้ง หากรูปแบบเมื่อตะกี้ตรงนี้จะแทนที่แหล่งที่มาของรูปแบบที่ต่ำกว่า

  • หากรูปแบบลงท้ายด้วยเครื่องหมายทับมันจะถูกลบออกเพื่อจุดประสงค์ของคำอธิบายต่อไปนี้ แต่จะพบการจับคู่กับไดเรกทอรีเท่านั้น กล่าวอีกนัยหนึ่งfoo/จะจับคู่ไดเรกทอรีfooและพา ธ ที่อยู่ข้างใต้ แต่จะไม่ตรงกับไฟล์ปกติหรือลิงก์สัญลักษณ์foo(ซึ่งสอดคล้องกับวิธีที่ pathspec ทำงานโดยทั่วไปในคอมไพล์)

  • หากรูปแบบไม่มีเครื่องหมายสแลช/git จะถือว่าเป็นรูปแบบเชลล์แบบกลมและตรวจสอบการจับคู่กับชื่อพา ธ ที่สัมพันธ์กับตำแหน่งของ.gitignoreไฟล์ (เทียบกับระดับบนสุดของแผนผังงานหากไม่ใช่จาก.gitignoreไฟล์)

  • มิฉะนั้น Git จะถือว่ารูปแบบเป็นเชลล์กลมเหมาะสำหรับการบริโภคโดยfnmatch(3)ใช้FNM_PATHNAMEธง: wildcard ในรูปแบบจะไม่ตรงกับ/ในชื่อพา ธ ยกตัวอย่างเช่นDocumentation/*.htmlตรงDocumentation/git.htmlแต่ไม่หรือDocumentation/ppc/ppc.htmltools/perf/Documentation/perf.html

  • เครื่องหมายทับนำหน้าตรงกับจุดเริ่มต้นของชื่อพา ธ ยกตัวอย่างเช่น/*.cตรงแต่ไม่cat-file.cmozilla-sha1/sha1.c

คุณสามารถหาข้อมูลเพิ่มเติมได้ที่นี่

git help gitignore
หรือ
man gitignore


2
ฉันจะวางไฟล์. gitignore ที่ระดับบนสุดและทำให้มันใช้ได้กับโฟลเดอร์ใด ๆ ที่อยู่ด้านล่างได้อย่างไร ขอบคุณ.
Royi

104
-1 TL; DR และตอบคำถามแทบจะไม่ มันเป็นเรื่องเกี่ยวกับไดเรกทอรีไม่ใช่ไฟล์ดังนั้นส่วนที่เป็นตัวหนานั้นเป็นเพียงเรื่องเกี่ยวกับยิมนาสติกจิต @Jefromi ตรงมากขึ้น
Bob Stein

ฉันได้อ่านผู้ชายคนนั้นแล้วและคำตอบของ @ Jefromi นั้นดีกว่าตราบใดที่คุณยังอ่านคำเตือนของ @ jox ด้วยเช่นกันและ @ Luke Hutton อาจมีประโยชน์มากกว่าสำหรับการละเว้นไฟล์โครงการ IDE
WillC

1
นี่คือการคัดลอกวางจากเอกสาร git
mcont

1
ไม่แน่ใจ (โดยหลัก) การคัดลอกmanหน้าหรือเอกสารอย่างเป็นทางการเป็นรูปแบบที่ดีที่สุดสำหรับ ...
jdk1.0

183

มันจะเป็นอดีต ไปตามส่วนขยายเช่นกันแทนที่จะเป็นโครงสร้างโฟลเดอร์

ตัวอย่างของฉันคือ C # ไฟล์ละเว้นการพัฒนา:

#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
~$*

ปรับปรุง

ฉันคิดว่าฉันต้องการอัปเดตจากความคิดเห็นด้านล่าง แม้ว่าจะไม่ตอบคำถามของ OP โดยตรงดูตัวอย่างต่อไปนี้ของ.gitignoreไวยากรณ์เพิ่มเติม

วิกิชุมชน (อัปเดตอยู่เสมอ):

.gitignore สำหรับโครงการและโซลูชั่น Visual Studio

ตัวอย่างเพิ่มเติมที่มีการใช้ภาษาเฉพาะสามารถพบได้ที่นี่ (ขอบคุณความคิดเห็นของ Chris McKnight):

https://github.com/github/gitignore


5
@Stallman rangeนั่นคือ ดังนั้นมันจึงเข้า*.Objกันเช่น*.objกัน
norbert

131

พา ธ ที่มีเครื่องหมายทับจะถูกนำไปสัมพันธ์กับไดเรกทอรีที่มีไฟล์. gitignore ซึ่งโดยปกติแล้วจะเป็นระดับบนสุดของที่เก็บของคุณแม้ว่าคุณจะสามารถวางไว้ในไดเรกทอรีย่อยได้

ดังนั้นเนื่องจากในตัวอย่างทั้งหมดที่คุณให้เส้นทางมีเครื่องหมายทับทั้งสองรุ่นจึงเหมือนกัน เวลาเดียวที่คุณต้องใส่เครื่องหมายสแลชนำหน้าคือเมื่อไม่มีอยู่ในเส้นทางแล้ว ยกตัวอย่างเช่นที่จะไม่สนใจ foo /fooเฉพาะที่ระดับบนสุดของพื้นที่เก็บข้อมูลการใช้งาน เพียงแค่เขียนfooจะไม่สนใจสิ่งที่เรียกว่า foo ได้ทุกที่ในที่เก็บ

อักขระตัวแทนของคุณซ้ำซ้อน หากคุณต้องการละเว้นไดเรกทอรีทั้งหมดเพียงแค่ตั้งชื่อ:

lib/model/om

เหตุผลเดียวในการใช้ไวด์การ์ดในแบบที่คุณมีคือถ้าคุณตั้งใจจะยกเลิกบางสิ่งบางอย่างในไดเรกทอรี:

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

5
คำอธิบายที่ดีกว่าคำตอบที่ยอมรับสำหรับคำถามนี้
eerrzz

78

เครื่องหมายทับนำหน้าระบุว่ารายการเพิกเฉยจะใช้ได้กับไดเร็กทอรีที่มีไฟล์. gitignore อยู่เท่านั้น การระบุ*.oจะเพิกเฉยต่อไฟล์. o ทั้งหมดในไดเรกทอรีนี้และส่วนย่อยทั้งหมดในขณะที่/*.oจะเพิกเฉยต่อไฟล์เหล่านั้นใน dir นั้นและอีกครั้ง/foo/*.oจะละเว้นไฟล์เหล่านั้นใน /foo/*.o เท่านั้น


34

หากคุณต้องการที่จะนำไฟล์ .gitignore ในระดับบนและทำให้การทำงานสำหรับโฟลเดอร์ใด ๆ /**/ด้านล่างใช้

เช่นละเว้น*.mapไฟล์ทั้งหมดใน/src/main/โฟลเดอร์และโฟลเดอร์ย่อยให้ใช้:

/src/main/**/*.map

ฉันต้องการทำสิ่งนี้ ไม่แน่ใจว่าทำไมคุณต้องสอง ** 's หนึ่งก็เพียงพอแล้วสำหรับฉัน
Novocaine

8
** การแข่งขันยังไฟล์ในไดเรกทอรีย่อย
petrsyn

ขอบคุณสำหรับข้อมูล @petrsyn
Novocaine

30

ทั้งสองตัวอย่างในคำถามเป็นตัวอย่างที่แย่มาก ๆ ที่อาจนำไปสู่การสูญเสียข้อมูล!

คำแนะนำของฉัน: อย่าผนวก/*เข้ากับไดเรกทอรีในไฟล์. gignignore เว้นแต่คุณจะมีเหตุผลที่ดี

เหตุผลที่ดีจะเป็นเช่นสิ่ง Jefromi wrote: "ถ้าคุณตั้งใจจะต่อมายกเลิกไม่สนใจสิ่งที่อยู่ในไดเรกทอรี"

เหตุผลที่ไม่ควรทำอย่างอื่นก็คือการผนวก/*ไปยังไดเรกทอรีทำงานด้วยมือข้างหนึ่งในลักษณะที่มันไม่สนใจเนื้อหาทั้งหมดของไดเรกทอรี แต่ในทางกลับกันมันมีผลข้างเคียงที่อันตราย:

หากคุณดำเนินการgit stash -u(เพื่อซ่อนไฟล์ที่ถูกติดตามและไม่ได้ติดตาม) หรือgit clean -df(เพื่อลบไฟล์ที่ไม่ได้ติดตาม แต่เก็บไฟล์ที่ถูกเพิกเฉย) ในที่เก็บของคุณไดเรกทอรีทั้งหมดที่ถูกละเว้นด้วยการผนวก/*จะถูกลบทิ้งอย่างถาวร !

พื้นหลังบางส่วน

ฉันต้องเรียนรู้วิธีนี้อย่างหนัก มีคนในทีมของฉันต่อท้าย/*ไดเรกทอรีบางรายการใน. gitignore ของเรา เมื่อเวลาผ่านไปฉันมีโอกาสที่บางไดเรกทอรีจะหายไปทันที ไดเรกทอรีที่มีกิกะไบต์ของข้อมูลท้องถิ่นที่แอปพลิเคชันของเราต้องการ ไม่มีใครสามารถอธิบายได้และฉันจะทำการดาวน์โหลดข้อมูลทั้งหมดอีกครั้ง git stashหลังจากที่ในขณะที่ผมได้คิดว่ามันอาจจะต้องทำอย่างไรกับ วันหนึ่งฉันต้องการล้าง repo ในพื้นที่ของฉัน (ในขณะที่เก็บไฟล์ที่ถูกเพิกเฉย) และฉันกำลังใช้git clean -dfและข้อมูลของฉันก็หายไป เวลานี้ฉันมีเพียงพอและตรวจสอบปัญหา /*ในที่สุดผมก็คิดว่าเหตุผลที่เป็นท้าย

ฉันคิดว่ามันสามารถอธิบายได้อย่างใดโดยความจริงที่directory/*ไม่สนใจเนื้อหาทั้งหมดของไดเรกทอรี แต่ไม่ไดเรกทอรีเอง ดังนั้นจึงไม่ถือว่าถูกติดตามหรือเพิกเฉยเมื่อสิ่งต่างๆถูกลบ แม้ว่าgit statusและgit status --ignoredให้ภาพที่แตกต่างกันเล็กน้อยกับมัน

วิธีการทำซ้ำ

นี่คือวิธีการทำซ้ำพฤติกรรม ฉันใช้ Git 2.8.4 อยู่ในขณะนี้

ไดเรกทอรีที่เรียกว่าlocaldata/ไฟล์จำลองในนั้น ( important.dat) จะถูกสร้างขึ้นในพื้นที่เก็บข้อมูล git ท้องถิ่นและเนื้อหาจะถูกละเว้นโดยการใส่/localdata/*ลงใน.gitignoreไฟล์ เมื่อคำสั่ง git หนึ่งในสองคำสั่งถูกดำเนินการในขณะนี้ไดเรกทอรีจะหายไปโดยไม่คาดคิด

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

ถ้าคุณทำgit status --ignoredที่นี่คุณจะได้รับ:

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/

ตอนนี้ก็ทำ

git stash -u
git stash pop

หรือ

git clean -df

ในทั้งสองกรณีไดเรกทอรีที่ถูกกล่าวหาlocaldataจะหายไป!

ไม่แน่ใจว่านี่ถือเป็นข้อผิดพลาดหรือไม่ แต่ฉันเดาว่าอย่างน้อยมันเป็นคุณสมบัติที่ไม่มีใครต้องการ

ฉันจะรายงานเรื่องนั้นในรายการการพัฒนา git และดูว่าพวกเขาคิดอย่างไร


15

มันจะเป็น:

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

หรืออาจเป็นไปได้:

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

ในกรณีที่filterและformเป็นไดเรกทอรีเดียวใน lib ที่มีbaseไดเรกทอรีย่อยที่ต้องละเว้น (ดูมันเป็นตัวอย่างของสิ่งที่คุณสามารถทำได้กับ asterics)


14

อันแรก พา ธ ของไฟล์เหล่านั้นสัมพันธ์กับตำแหน่งของไฟล์. gitignore ของคุณ


2
สิ่งนี้เป็นจริงสำหรับรูปแบบที่มีเครื่องหมายทับเท่านั้น ชื่อไดเรกทอรีเดียวเช่น "mydir" จะไม่สนใจไดเรกทอรี (และไฟล์) ที่อยู่ในโฟลเดอร์ย่อยที่ระดับความลึกใด ๆ การใส่เครื่องหมายทับด้านหน้าเท่านั้นจะทำให้สัมพันธ์กับตำแหน่งที่ไฟล์. gitignore ของคุณอยู่
jox

4

ฉันรักษาบริการ GUI และ CLI ที่ช่วยให้คุณสามารถสร้าง.gitignoreแม่แบบได้อย่างง่ายดายมากที่https://www.gitignore.io

คุณสามารถพิมพ์แม่แบบที่คุณต้องการในช่องค้นหาหรือติดตั้งนามแฝงบรรทัดคำสั่งและเรียกใช้

$ gi swift,osx


0

ตัวอย่างไฟล์. gignignoreสามารถมีลักษณะด้านล่างสำหรับโครงการ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.