เพิ่มไฟล์ทั้งหมดลงในการคอมมิชชันยกเว้นไฟล์เดียวหรือไม่?


571

ฉันมีไฟล์จำนวนมากในเซ็ตการแก้ไข แต่ฉันต้องการละเว้นไฟล์ที่ถูกดัดแปลงเพียงไฟล์เดียว ดูเหมือนว่าหลังจากนี้git status:

# modified:   main/dontcheckmein.txt
# deleted:    main/plzcheckmein.c
# deleted:    main/plzcheckmein2.c
...

มีวิธีที่ฉันสามารถทำได้git addแต่เพียงละเว้นไฟล์ข้อความเดียวที่ฉันไม่ต้องการสัมผัส สิ่งที่ต้องการ:

git add -u -except main/dontcheckmein.txt

คำตอบ:


851
git add -u
git reset -- main/dontcheckmein.txt

28
ฉันจะแยกโฟลเดอร์ทั้งหมดได้อย่างไร - main หรือ main / หรือ main / *?
Alan Coromano

8
@MariusKavansky คุณสามารถใช้แบบฟอร์มเหล่านี้ทั้งหมด ถ้าคุณใช้main/*มันจำเป็นต้องเพิ่ม--ไว้ข้างหน้าเพื่อให้ git รู้ว่ามันเป็นเส้นทาง อีกสองสายพันธุ์ทำงานโดยไม่รวมเครื่องหมายขีดคั่นสองตัว (ทดสอบในพร้อมท์คำสั่งบน Windows 7 ด้วย msysGit)
dennisschagt

2
หากคุณมีบางโฟลเดอร์ที่คุณต้องการยกเว้นที่มีไฟล์จำนวนมากหรือโฟลเดอร์อื่น ๆ ให้เพิ่มโฟลเดอร์เหล่านั้นลงใน gitignore ของคุณชั่วคราว การดำเนินการgit resetสำหรับโฟลเดอร์เหล่านั้นในภายหลังจะยังคงใช้งานได้ แต่จะใช้เวลานานพอสมควรในการเพิ่มโฟลเดอร์ขนาดใหญ่
Michael Trouw

2
ดังนั้นจึงไม่มีซับใน?
BroVic

5
@Ben Jackson จะดีที่จะแสดงความคิดเห็นในแต่ละบรรทัดคุณไม่คิดหรือ
ed1nh0

140

1) ในการเริ่มเพิกเฉยต่อการเปลี่ยนแปลงไฟล์ที่มีเวอร์ชันเดียวแล้ว

git update-index --assume-unchanged "main/dontcheckmein.txt"

และเพื่อยกเลิกสิ่งนั้น git update-index --no-assume-unchanged "main/dontcheckmein.txt"

gitHub เอกสารที่จะไม่สนใจไฟล์

2) เพื่อเพิกเฉยต่อไฟล์เดียวโดยสมบูรณ์ซึ่งป้องกันไม่ให้ไฟล์ถูกสร้างขึ้นในที่เก็บ

ขั้นแรกให้ดูที่โพสต์สแต็คโอเวอร์โฟลว์นี้: Git โกลบอลเพิกเฉยไม่ทำงาน

ใน.gitignoreเพิ่มพา ธ สัมพัทธ์ให้กับไฟล์โดยไม่นำ./หน้า

ดังนั้นหากไฟล์ของคุณอยู่ที่MyProject/MyFolder/myfile.txt(อยู่ที่ไหน.gitในMyProjectโฟลเดอร์) ให้เพิ่มไฟล์MyFolder/myfile.txtของคุณที่.gitignore

คุณสามารถยืนยันกฎที่เกี่ยวข้องกับการเพิกเฉยผ่าน git check-ignore "MyFolder/myfile.txt"

เกี่ยวกับการละเว้นทั่วโลก

ลิงค์นั้นพูดถึง~/.gitignore_globalแต่ไฟล์เกี่ยวข้องกับโครงการของคุณ ดังนั้นหากคุณใส่รูปแบบที่ไม่รวมMyFolder/myfile.txtเข้า~/.gitignore_globalด้วยกันมันจะทำงานได้ แต่จะไม่สมเหตุสมผล ...

ในทางกลับกันถ้าคุณตั้งค่าโครงการของคุณด้วยgit config core.excludesfile .gitignoreที่ที่.gitignoreอยู่ในMyProjectไฟล์ท้องถิ่นจะแทนที่~/.gitignore_globalซึ่งอาจมีกฎที่มีประโยชน์มาก ...

ดังนั้นสำหรับตอนนี้ผมคิดว่ามันเป็นที่ดีที่สุดที่จะทำให้สคริปต์ในการผสมของคุณ.gitignoreกับที่~/.gitignore_global.gitignore

หนึ่งคำเตือนครั้งสุดท้าย
หากไฟล์ที่คุณต้องการเพิกเฉยมีอยู่ในที่เก็บแล้ววิธีนี้จะไม่ทำงานเว้นแต่คุณจะทำสิ่งนี้: git rm "MyFolder/myfile.txt"แต่สำรองข้อมูลก่อนเพราะจะถูกลบแบบโลคอลด้วย! คุณสามารถคัดลอกได้ในภายหลัง ...


5
คุณสามารถใช้git rm --cached MyFolder/myyfile.txtเพื่อลบไฟล์ออกจากที่เก็บ แต่เก็บไว้แบบโลคัล คำอธิบายเกี่ยวกับ help.github.com
dennisschagt

87

สำหรับไฟล์

git add -u
git reset -- main/dontcheckmein.txt

สำหรับโฟลเดอร์

git add -u
git reset -- main/*

9
เหตุใด -u จึงจำเป็น ทำไมไม่git add . && git reset -- main/*?

2
อ็อพชัน -u จะอัพเดตดัชนีที่มีรายการที่ตรงกับ <pathspec> แล้ว สิ่งนี้จะลบและปรับเปลี่ยนรายการดัชนีเพื่อให้ตรงกับแผนผังการทำงาน แต่ไม่เพิ่มไฟล์ใหม่ หากไม่มีการระบุ <pathspec> เมื่อใช้ตัวเลือก -u ไฟล์ที่ติดตามทั้งหมดในแผนผังการทำงานทั้งหมดจะได้รับการอัปเดต (Git เวอร์ชันเก่าที่ใช้เพื่อ จำกัด การอัปเดตไปยังไดเรกทอรีปัจจุบันและไดเรกทอรีย่อย)
Farhad Mammadli

6
ทุกคนสามารถอธิบายได้หรือไม่ว่าเหตุใด -u จึงจำเป็นต้องใช้ภาษาที่ผู้เชี่ยวชาญที่ไม่ใช่ git เข้าใจ
Patrick

2
-u ใช้ในการอ้างอิงสาขาปัจจุบันของคุณคุณกำลังผลักดัน คุณไม่จำเป็นต้องพิมพ์git push origin masterในการผลักดันครั้งต่อไปของคุณอีกต่อไปเพียงแค่git pushและคอมไพล์จะรู้ว่ามันอยู่ในสาขาหลัก หวังว่ามันจะช่วย
Pepeng Hapon

69

ตอนนี้gitสนับสนุนexclude certain paths and filesโดยมายากล pathspec และรูปแบบสั้น:(exclude) :!ดังนั้นคุณสามารถบรรลุมันเป็นคำสั่งดังต่อไปนี้

git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt

ที่จริงคุณสามารถระบุเพิ่มเติมได้ที่:

git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*

1
คำตอบที่ดีที่สุดขอบคุณ! อย่างน้อยสำหรับกรณีของฉัน: ฉันต้องการเพียงยกเว้นประเภทไฟล์
Andre Polykanine

15
มันยอดเยี่ยมมาก! โปรดทราบว่าบน Linux คุณต้องอ้างอิงส่วน:!...คำสั่งเพื่อป้องกันไม่ให้เชลล์บ่น ตัวอย่างเช่น: git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'.
Martin_W

มีอะไร:!/path/to/(file1|file2)ไหม
seeker_of_bacon

สิ่งนี้ขัดแย้งกับบางสิ่งใน zsh ไม่ได้ผลกับฉันใน macOS และคอมไพล์ล่าสุด
Merlin

1
ใครสามารถชี้ไปที่เอกสารนี้เป็นทางการได้หรือไม่?
samurai_jane

20

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

#!/bin/bash
set -e

git add -A
git reset `cat .gittrackignore`

และนี่คือ.gittrackignoreลักษณะปัจจุบันของฉัน

project.properties

ฉันกำลังทำงานในโครงการ Android ที่ฉันรวบรวมจากบรรทัดคำสั่งเมื่อปรับใช้ โครงการนี้ขึ้นอยู่กับ SherlockActionBar ดังนั้นจึงต้องอ้างอิงใน project.properties แต่มันยุ่งกับการคอมไพล์ดังนั้นตอนนี้ฉันเพิ่งพิมพ์gitaddและเพิ่มการเปลี่ยนแปลงทั้งหมดใน git โดยไม่ต้องยกเลิกการเพิ่ม project.properties ทุกครั้ง


ฉันไม่รู้ว่าอะไร--จนกระทั่งความคิดเห็นของคุณ ตาม man pages นั้นเป็นทางเลือกและจะไม่เปลี่ยนผลลัพธ์ของคำสั่ง (อย่างน้อยในกรณีนี้) คำถามนี้ดูเหมือนจะสนับสนุนว่า stackoverflow.com/questions/17800994/... แก้ไขฉันถ้าฉันผิด แต่ดูเหมือนว่าหมายถึง "ปฏิบัติอะไรก็ได้หลังจาก--เป็นข้อโต้แย้งไม่ใช่ตัวเลือก / สวิทช์"
Anthony Naddeo

ใช้ดี--ในgit checkoutฉันเห็นในคำถามนั้น ฉันไม่รู้ว่าเส้นประสองเส้นนั้นคืออะไรจนกระทั่งการแลกเปลี่ยนของเราเช่นกัน ฉันสงสัยgit checkoutว่าความคลุมเครือระหว่างสาขาและไฟล์อาจส่งผลกระทบในรูปแบบนี้หรือในรูปแบบที่แตกต่างกันgit resetด้วย
Giulio Piancastelli

10

เพื่อให้การเปลี่ยนแปลงในไฟล์ แต่ไม่ยอมรับฉันทำสิ่งนี้

git add .

git reset -- main/dontcheckmein.txt

git commit -m "commit message"

เพื่อตรวจสอบไฟล์ที่ถูกยกเว้นทำ

git status


4

ใช้git add -Aเพื่อเพิ่มไฟล์ที่แก้ไขและเพิ่มใหม่ทั้งหมดในครั้งเดียว

ตัวอย่าง

git add -A
git reset -- main/dontcheckmein.txt



1

สำหรับกรณีเฉพาะในคำถามวิธีที่ง่ายที่สุดคือการเพิ่มไฟล์ทั้งหมดด้วยนามสกุล. cและละทิ้งทุกอย่างอื่น:

git add *.c

จากgit-scm (หรือ / และman git add):

git เพิ่ม <pathspec> ...

ไฟล์ที่จะเพิ่มเนื้อหาจาก สามารถกำหนด Fileglobs (เช่น * .c) เพื่อเพิ่มไฟล์ที่ตรงกันทั้งหมด < ... >

โปรดทราบว่านี่หมายความว่าคุณสามารถทำสิ่งต่างๆเช่น:

git add **/main/*

เพื่อเพิ่มไฟล์ทั้งหมด (ที่ไม่ถูกละเว้น) ที่อยู่ในmainโฟลเดอร์ คุณยังสามารถก้าวไปข้างหน้าด้วยลวดลายที่ซับซ้อนยิ่งขึ้น:

git add **/s?c/*Service*

ด้านบนจะเพิ่มไฟล์ทั้งหมดที่อยู่ในs(any char)cโฟลเดอร์และมีที่Serviceอื่นในชื่อไฟล์

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

git add *.c *.h

ลิงก์นี้อาจให้แนวคิดแบบกลม ๆ แก่คุณเพิ่มเติม

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

โดยวิธีการที่คุณอาจต้องอ้างรูปแบบกลมของคุณสำหรับพวกเขาที่จะทำงาน แต่นี่ไม่เคยเป็นกรณีสำหรับฉัน


0

ฉันใช้git add --patchค่อนข้างน้อยและต้องการสิ่งนี้เพื่อหลีกเลี่ยงการถูกโจมตีdตลอดเวลาผ่านไฟล์เดียวกัน ฉันทำวิปนามแฝง git ขึ้นมาสองสามอันเพื่อให้งานเสร็จ:

[alias]
    HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
    ap                      = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"

ในกรณีของฉันฉันต้องการละเว้นไฟล์ minified บางไฟล์ตลอดเวลา แต่คุณสามารถทำให้มันใช้ตัวแปรสภาพแวดล้อมเช่น$GIT_EXCLUDE_PATTERNกรณีการใช้งานทั่วไปมากขึ้น



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