อธิบายว่ากฎ gitignore ใดละเว้นไฟล์ของฉัน


310

มีวิธีใดบ้างที่จะดูว่าเหตุใดบางไฟล์จึงถูกละเว้นโดย git (เช่นกฎใดใน.gitignoreไฟล์ที่ทำให้ไฟล์นั้นถูกละเว้น)?

ลองนึกภาพฉันมีนี้ (หรือสถานการณ์ที่ซับซ้อนมากขึ้นด้วยหลายร้อยโฟลเดอร์และหลายสิบ.gitignoreไฟล์:

/
-.gitignore
-folder/
    -.gitignore
    -subfolder/
              -.gitignore
              -file.txt

หากฉันใช้git add folder/subfolder/file.txtคอมไพล์อาจบ่นว่ามันถูกละเว้น:

The following paths are ignored by one of your .gitignore files:
folder/subfolder/file.txt
Use -f if you really want to add them.

มีวิธีใดบ้างที่จะรู้ว่าสิ่งใดที่เป็นไป.gitignoreได้ทั้งหมดที่มีกฎในการเพิกเฉยต่อไฟล์นี้และแสดงกฎด้วย? ชอบ:

The following paths are ignored by your folder/.gitignore file (line 12: *.txt)
folder/subfolder/file.txt
Use -f if you really want to add them.

หรือเพียงแค่:

$ git why-is-ignored folder/subfolder/file.txt
folder/.gitignore:12:*.txt

4
หมายเหตุ: git check-ignoreจะเร็ว ๆ นี้ (git1.8.5 / 1.9) จะมี--no-indexตัวเลือก ดูคำตอบของฉันด้านล่าง
VonC

หมายเหตุ: GIT_TRACE_EXCLUDE=1 git statusอีกไม่นานจะเป็นวิธีเพิ่มเติมในการแก้ปัญหา.gitignoreกฎ ดูคำตอบที่แก้ไขของฉันด้านล่าง
VonC

โพสต์บล็อกที่เกี่ยวข้อง: danielcompton.net/2016/04/21/… .
krlmlr

คำตอบ:


643
git check-ignore -v filename

ดูหน้าคนสำหรับรายละเอียดเพิ่มเติม

คำตอบเดิมมีดังนี้:

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

UPDATE:ว้าวมันยากกว่าที่ฉันคาดไว้มาก การgitจัดการที่แยกออกจากอวัยวะภายในนั้นค่อนข้างคลุมเครือ อย่างไรก็ตามนี่คือการกระทำที่เกือบจะเสร็จสิ้นซึ่งใช้กับmasterสาขาต้นน้ำของวันนี้ ชุดการทดสอบเสร็จสมบูรณ์ 99% แต่ฉันยังคงจัดการ--stdinตัวเลือกไม่เสร็จ หวังว่าฉันจะจัดการมันในสุดสัปดาห์นี้แล้วส่งแพตช์ของฉันไปยังรายชื่อผู้รับจดหมาย git

ในระหว่างนี้ฉันยินดีต้อนรับการทดสอบจากทุกคนที่สามารถทำได้ - เพียงโคลนจากส้อมของฉันgitตรวจสอบcheck-ignoreสาขาและรวบรวมตามปกติ

อัพเดท 2:เสร็จแล้ว! รุ่นล่าสุดอยู่บน GitHub ตามข้างต้นและฉันได้ส่งชุดโปรแกรมแก้ไขไปยังรายชื่อผู้รับจดหมาย gitสำหรับการตรวจสอบเพื่อน มาดูกันว่าพวกเขาคิดอย่างไร ...

อัปเดต 3:หลังจากผ่านไปหลายเดือนของการแฮ็ค / ตรวจสอบการแก้ไข / การอภิปราย / การรอคอยฉันดีใจที่สามารถพูดได้ว่าฟีเจอร์นี้ได้มาถึงmasterสาขาของ gitแล้วและจะวางจำหน่ายในรุ่นถัดไป (1.8.2, 8 มีนาคม 2013) นี่คือหน้าคู่มือcheck-ignore ว้านั่นเป็นวิธีที่ได้ผลมากกว่าที่ฉันคาดไว้!

UPDATE 4:หากคุณกำลังสนใจในเรื่องเต็มเกี่ยวกับวิธีการคำตอบนี้พัฒนาและคุณลักษณะที่มาที่จะดำเนินการตรวจสอบตอนที่ 32 ของพอดคาสต์


2
ฉันใช้ 1.8.2 และgit check-ignoreไม่ทำอะไรเลย
zakdances

3
@yourfriendzak ปราศจากข้อสงสัยgit check-ignoreมีอยู่และทำงานใน 1.8.2 หากพฤติกรรมไม่ใช่สิ่งที่คุณคาดหวังฉันขอแนะนำให้คุณ (อีกครั้ง) อ่านหน้าคู่มือและหากยังไม่ได้โปรดส่งรายงานข้อผิดพลาดที่เหมาะสมในรายชื่อผู้รับจดหมาย git เพียงแค่บอกว่าไม่ได้ทำอะไรก็ไม่ได้มีประโยชน์อะไรมาก ฉันหวังว่าคุณอาจทำงานบนไฟล์ที่ไม่ละเว้นและจะไม่ถูกต้องคาดหวังว่าการส่งออกบางส่วน (แม้ว่าฉันอาจจะเพิ่มการสนับสนุนสำหรับ--show-unmatchedกับ--verboseโหมดการส่งออกในอนาคต)
Adam Spires

1
@ AdamSpiers คุณพูดถูก ฉันควรระบุว่าเมื่อฉันรันคำสั่งจะไม่มีการพิมพ์อะไร ไม่มีข้อความแสดงข้อผิดพลาดไม่มีข้อความสำเร็จไม่มีข้อมูล เพียงแค่พรอมต์ถัดไปว่างเปล่าปรากฏขึ้น ดังนั้นฉันถูกต้องที่จะสมมติว่า "ไม่มีผลลัพธ์" เป็นพฤติกรรมที่คาดหวังในบางสถานการณ์?
zakdances

1
@ AdamSpiers ขอบคุณมากสำหรับสิ่งนี้! หลังจากการตรวจสอบ 3 วันคุณได้ช่วยฉันติดตามสาเหตุของการสร้างที่เสียหายเนื่องจากไฟล์ที่ถูกละเว้นทั่วโลกใน. gitignore_global! ฉันไม่รู้ด้วยซ้ำว่าเป็นเรื่อง!
BenBtg

3
ไม่ใช่ทุกวันที่เราเห็นนักพัฒนา Stack Overflow ทำการเปลี่ยนแปลงมากมายเพื่อใช้งานคุณสมบัติของนักพัฒนา ว้าวและเคารพ
user3613932

18

อัปเดต git 2.8 (มีนาคม 2016):

GIT_TRACE_EXCLUDE=1 git status

ดู " วิธีตรวจสอบ.gitignoreไฟล์ "

นั่นคือประกอบกับgit check-ignore -vอธิบายไว้ด้านล่าง


คำตอบเดิม: กันยายน 2013 (git 1.8.2 จากนั้น 1.8.5+):

git check-ignoreปรับปรุงอีกครั้งในgit 1.8.5 / 1.9 (Q4 2013) :

" git check-ignore" ปฏิบัติตามกฎเดียวกันกับ " git add" และ " git status" ซึ่งกลไกการเพิกเฉย / ไม่รวมจะไม่มีผลกับเส้นทางที่ถูกติดตามไปแล้ว
ด้วย "--no-indexตัวเลือก "" สามารถใช้ในการวิเคราะห์เส้นทางที่ควรละเว้นซึ่งถูกเพิ่มลงในดัชนีโดยไม่ตั้งใจ

ดูคอมมิชชัน 8231fa6จากhttps://github.com/flashydave :

check-ignoreปัจจุบันแสดงให้เห็นว่า.gitignoreกฎจะปฏิบัติต่อเส้นทางที่ไม่ได้ติดตามได้อย่างไร เส้นทางที่ติดตามไม่สร้างผลลัพธ์ที่มีประโยชน์
สิ่งนี้จะช่วยป้องกันการดีบั๊กว่าทำไมเส้นทางจึงถูกติดตามอย่างไม่คาดคิดเว้นแต่ว่าเส้นทางนั้นจะถูกลบออกจากดัชนีเป็นครั้งแรกgit rm --cached <path>ป้องกันไม่ให้การแก้จุดบกพร่องนี้ทำไมกลายเป็นเส้นทางการติดตามโดยไม่คาดคิดเว้นแต่ว่าเส้นทางจะถูกลบออกจากดัชนีแรกที่มี

ตัวเลือก--no-indexจะบอกให้คำสั่งข้ามการตรวจสอบพา ธ ที่อยู่ในดัชนีและด้วยเหตุนี้จึงอนุญาตให้ตรวจสอบพา ธ ที่ถูกติดตามได้เช่นกัน

ในขณะที่พฤติกรรมนี้เบี่ยงเบนไปจากลักษณะของgit addและgit statusกรณีการใช้งานไม่น่าจะทำให้เกิดความสับสนของผู้ใช้

สคริปต์ทดสอบจะถูกเพิ่มเพื่อตรวจสอบตัวเลือกนี้กับมาตรฐานที่ละเว้นเพื่อให้แน่ใจว่าพฤติกรรมที่ถูกต้อง


--no-index::

อย่าดูในดัชนีเมื่อดำเนินการตรวจสอบ
สิ่งนี้สามารถใช้:

  • เพื่อดีบักสาเหตุที่พา ธ ถูกติดตามโดยเช่นgit add .และไม่ถูกละเว้นโดยกฎตามที่ผู้ใช้คาดหวังหรือ
  • git add -fเมื่อมีการพัฒนารูปแบบรวมถึงการปฏิเสธเพื่อให้ตรงกับเส้นทางเพิ่มก่อนหน้านี้ด้วย

4

ฉันไม่พบอะไรเลยในหน้า man แต่นี่เป็นสคริปต์ที่รวดเร็วและสกปรกที่จะตรวจสอบไฟล์ของคุณในแต่ละไดเรกทอรีหลักเพื่อดูว่าสามารถ git-add'ed ได้หรือไม่ รันในไดเร็กทอรีที่มีไฟล์ปัญหาดังนี้:

test-add.sh STOP_DIR FILENAME

โดยที่STOP_DIRเป็นไดเรกทอรีระดับบนสุดของโครงการ Git และFILENAMEเป็นชื่อไฟล์ปัญหา (ไม่มีพา ธ ) มันสร้างไฟล์ว่างเปล่าที่มีชื่อเดียวกันในแต่ละระดับของลำดับชั้น (หากไม่มี) และพยายามที่git add -nจะดูว่าสามารถเพิ่มได้หรือไม่ มันแสดงผลเหมือน:

FAILED:    /dir/1/2/3
SUCCEEDED: /dir/1/2

สคริปต์:

#!/usr/bin/env bash
TOP=$1
FILE=$2
DIR=`pwd`
while : ; do
  TMPFILE=1
  F=$DIR/$FILE
  if [ ! -f $F ]; then
    touch $F
    TMPFILE=0
  fi
  git add -n $F >/dev/null 2>&1
  if [ $? = 0 ]; then
    echo "SUCCEEDED: $DIR"
  else
    echo "FAILED:    $DIR"
  fi
  if [ $TMPFILE = 0 ]; then
    rm $F
  fi
  DIR=${DIR%/*}
  if [ "$DIR" \< "$TOP" ]; then
    break
  fi
done 

1

หากต้องการเพิ่มคำตอบหลักของการใช้git check-ignore -v filename(ขอบคุณ BTW) ฉันพบว่าไฟล์. gitignore ของฉันปิดกั้นทุกอย่างเพราะมีการขึ้นบรรทัดใหม่หลังสัญลักษณ์แทนดังนั้นฉันจึงมี:

* .sublime-project

ตัวอย่างเช่น. ฉันเพิ่งลบบรรทัดใหม่และ voila! มันได้รับการแก้ไข

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