วิธีลบไฟล์ที่ลบหลายไฟล์ในที่เก็บ Git


237

ฉันได้ลบบางไฟล์และสถานะ git แสดงดังต่อไปนี้

ฉันมุ่งมั่นและผลักดัน

GitHub ยังคงแสดงไฟล์ที่ถูกลบในที่เก็บ ฉันจะลบไฟล์ในที่เก็บ GitHub ได้อย่างไร

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

ถ้าฉันใช้git rmมันให้สิ่งต่อไปนี้

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched


คำตอบ:


638
git add -u 

อัปเดตการเปลี่ยนแปลงทั้งหมดของคุณ


31
ใช้เสน่ห์ได้ เมื่อคุณเห็นบางสิ่งเช่น "สถานะ git | sed -n '/ ^ # * ลบ: / s /// p' | xargs git rm" เป็นวิธีแก้ปัญหาที่เสนอสำหรับความต้องการที่เรียบง่าย แต่บ่อยครั้งคุณจะรู้ว่าทางออกที่ดีกว่าคือ ไม่ช้าก็เร็วจะอยู่ใกล้ ๆ
arcseldon

ง่ายกว่าดีกว่านี่มันมีประโยชน์จริงๆแล้วเป็นวิธี "ทุบตี"
Castiel

1
ผู้เขียนถามว่าจะลบไฟล์ทำไมการเพิ่มไฟล์เป็นคำตอบที่ถูกต้อง?
kelin

3
@kelin: จาก git docs ( git-scm.com/docs/git-add ): "-u --updateอัปเดตดัชนีที่ซึ่งมีรายการที่ตรงกับ <pathspec> อยู่แล้วซึ่งจะลบและแก้ไขรายการดัชนีเป็น ตรงกับแผนผังการทำงาน แต่ไม่เพิ่มไฟล์ใหม่หากไม่ได้ระบุ <pathspec> เมื่อใช้ตัวเลือก -u ไฟล์ที่ติดตามทั้งหมดในแผนผังการทำงานทั้งหมดจะได้รับการอัปเดต (Git เวอร์ชันเก่าที่ใช้เพื่อ จำกัด การอัปเดตไปยังไดเรกทอรีปัจจุบัน ไดเรกทอรีย่อยของมัน) "
HEDMON

92

ต้องระมัดระวังมากเกี่ยวกับgit rm .; มันอาจลบมากกว่าที่คุณต้องการ แน่นอนคุณสามารถกู้คืน แต่มันง่ายกว่าที่จะไม่ต้องทำ

ง่ายที่สุดคือ:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

คุณไม่สามารถใช้สัญลักษณ์แทนเชลล์ได้เนื่องจากไฟล์ไม่มีอยู่ แต่คุณสามารถใช้ (ใน Bash เป็นอย่างน้อย):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

หรือพิจารณา:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

สิ่งนี้ใช้เวลาเอาต์พุตgit statusไม่พิมพ์อะไรตามค่าเริ่มต้น ( sed -n) แต่บนบรรทัดที่เริ่มต้น# deleted:มันจะกำจัด#และdeleted:และและพิมพ์สิ่งที่เหลืออยู่ xargsรวบรวมอาร์กิวเมนต์และจัดเตรียมให้กับgit rmคำสั่ง สิ่งนี้ใช้ได้กับไฟล์จำนวนเท่าใดก็ได้โดยไม่คำนึงถึงความคล้ายคลึงกัน (หรือความแตกต่าง) ในชื่อ


6
คุณสามารถใช้อักขระตัวแทน (แม้ว่าคุณอาจจำเป็นต้องหลบหนี) และ git จะจับคู่พา ธ ในดัชนีไม่ใช่เฉพาะในแผนผังการทำงานดังนั้นจึงไม่สำคัญว่าไม่มีอยู่ในระบบไฟล์
Ben James

109
git diff --diff-filter=D --name-only -z | xargs -0 git rmเป็นวิธีที่เชื่อถือได้มากกว่าการพยายามวิเคราะห์คำgit statusที่เน้นผู้ใช้และไม่รับประกันว่าจะเสถียรกว่าเวอร์ชันในอนาคต
CB Bailey

@Charles: มันดีกว่า แต่ก็ต้องมีความรู้ค่อนข้างมากเกี่ยวกับตัวเลือกอะไรบ้างที่มีgit diff(ซึ่งฉันไม่ได้มีโดยไม่จำเป็นต้องมีมาก่อน) ขอบคุณ!
Jonathan Leffler

8
โปรดทราบว่านอกจากนี้ยังมี "git ls-files - ลบ"
Petr Gladkikh

1
ดังนั้นgit ls-files --deleted | xargs git rmได้หลอกลวงให้ฉัน
fiacobelli

50

อีกรุ่นสำหรับคำตอบของ ByScripts คือ

git rm $(git ls-files --deleted)

นี่จะเป็นการลบไฟล์ที่ถูกลบออกจาก git เท่านั้น

มันอาจจะใช้สำหรับการเพิ่มไฟล์ที่แก้ไขเท่านั้น

git add $(git ls-files --modified)

คำสั่งเหล่านี้ยังทำงานบน gitbash สำหรับ windows


2
ไม่มีค่าเลยการgit ls-filesลบหรือแก้ไขสถานะจะมีประโยชน์มาก
Mario Peshev

1
พฤติกรรมของที่'git add --update (or -u)'ไม่มีอาร์กิวเมนต์เส้นทางจากไดเรกทอรีย่อยของต้นไม้จะเปลี่ยนแปลงใน Git 2.0 และไม่ควรใช้อีกต่อไป ในการเพิ่มเนื้อหาสำหรับทั้งต้นให้รัน: git add --update :/ (หรือ git add -u: /) เพื่อ จำกัด คำสั่งให้กับไดเรกทอรีปัจจุบันให้รัน: git add --update . (หรือ git add -u.) ด้วยเวอร์ชัน Git ปัจจุบันคำสั่งจะถูก จำกัด ไดเรกทอรีปัจจุบัน
Ans

1
มีความคิดวิธีจัดการกับพา ธ ด้วยช่องว่างในนั้นไหม? ตัวอย่าง: src/my spaced directory/myfile. สิ่งนี้สามารถจัดการได้ทีละรายการ แต่จะจัดการได้อย่างไรโดยใช้คำสั่งในคำตอบนี้
มูฮัมหมัด Gelbana

35

อัปเดตการเปลี่ยนแปลงทั้งหมดที่คุณทำ:

git add -u

ไฟล์ที่ถูกลบควรเปลี่ยนจากที่ไม่มีสเตจ (มักเป็นสีแดง) เป็นสเตจ (สีเขียว) จากนั้นส่งคอมมิทเพื่อลบไฟล์ที่ถูกลบ:

git commit -m "note"

1
สมควรได้รับตราประชานิยม
John

1
นี่คือทางออกที่ดีที่สุด ไม่มีแฮ็คสคริปต์ไม่มีกระบวนการที่ยืดเยื้อเพียงแค่ตั้งค่าสถานะเพื่อบอกคอมไพล์ให้อัปเดตดัชนีอย่างละเอียด
Ron Dahlgren

ยอดเยี่ยม! ช่วยฉันไม่ให้พิมพ์เส้นทางไฟล์ 20+ ขอบคุณ!
allardbrain

12

ทางออกที่ดีที่สุดถ้าคุณไม่สนใจเกี่ยวกับไฟล์ที่ถูกแก้ไขการแสดงละครคือการใช้git add -uตามที่กล่าวโดยmshameersและ / หรือpb2q pb2q

หากคุณเพียงแค่ต้องการลบไฟล์ที่ถูกลบ แต่ไม่ใช่สเตจที่ถูกแก้ไขใด ๆ ฉันคิดว่าคุณควรใช้ls-filesอาร์กิวเมนต์ด้วย--deletedตัวเลือก (ไม่จำเป็นต้องใช้ regex หรือ args / options ที่ซับซ้อนอื่น ๆ ):

git ls-files --deleted | xargs git rm

1
git add -Aแก้ปัญหานี้ ... ในกรณีที่ใครอยากรู้ในอนาคต ตรวจสอบคำตอบด้านล่าง
Ja8zyjits

8

ใช่git rm <filename>จะแสดงสถานะไฟล์ที่ถูกลบซึ่ง<filename>อาจเป็นรูปแบบ glob:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

จากนั้นคุณสามารถกระทำ

git commit -a จะทำในครั้งเดียวถ้าคุณต้องการ

คุณยังสามารถใช้git add -uเพื่อจัดการการเปลี่ยนแปลงทั้งหมดรวมถึงไฟล์ที่ถูกลบทั้งหมดจากนั้นส่งคอมมิท


ดังนั้น rm (หยุดเต็ม) ลบพวกเขาในครั้งเดียว?
ชิน

ดังนั้นเพียงแค่คอมไพล์ rm จะลบทั้งหมดในครั้งเดียว?
ชิน

1
คุณสามารถใช้รูปแบบแบบกลมเพื่อลบหลายไฟล์ ฉันอัพเดตคำตอบเพื่อแสดงตัวอย่าง
Ben James

5
ดูเหมือนว่าgit add -uเป็นสิ่งที่เรากำลังมองหา - หากคุณทำการลบหลายอย่างแล้วต้องการลบการลบทั้งหมดซึ่งดูเหมือนจะเป็นวิธีที่ง่ายที่สุดและ 'มาตรฐาน' ที่สุด xargs) มีเหตุผลที่เราไม่ต้องการใช้สิ่งนี้นอกเหนือจากความจริงที่ว่ามันเพิ่มการเปลี่ยนแปลงทั้งหมดในครั้งเดียวหรือไม่?
trisweb

7

เมื่อฉันมีไฟล์จำนวนมากที่ฉันลบไปแล้วซึ่งไม่ได้มีการกำหนดไว้สำหรับการคอมมิชชันคุณสามารถทำได้git rmทั้งหมดในรายการเดียวด้วย:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

git rmในฐานะที่เป็นผู้ตอบคำถามดังกล่าวต้องระวังด้วย


5

ลองสิ่งนี้:

 git rm `git ls-files -d`

วิธีนี้แก้ไขปัญหาของฉันเกี่ยวกับการแสดงเฉพาะสคริปต์ที่ถูกลบ (ใช้ทุบตี)
Mariano Argañaraz

3

คุณสามารถใช้ได้

git commit -m "remove files" -a
git push

หลังจากคุณลบไฟล์ด้วยตนเอง


1
หรือเหมือนกัน แต่ชัดเจนยิ่งขึ้น: คอมไพล์กระทำ -am "ลบไฟล์"
BradChesney79

3

คุณสามารถสร้างเชลล์สคริปต์ซึ่งจะลบไฟล์ทั้งหมดของคุณเมื่อทำงาน:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

สคริปต์ที่สร้างขึ้นremove.shและมีรายการgit rmคำสั่งทั้งหมด




2

หากคุณต้องการลบทั้งหมดโดยใช้ "git rm" นี่คือสิ่งที่ฉันทำ:

git ls-files --deleted -z | xargs -0 git rm

เคียวรีนี้แสดงรายการไฟล์ทั้งหมดที่ถูกลบและลบออกจากที่เก็บ git ของคุณ หวังว่ามันจะช่วย


1

ฟังก์ชั่นทำความสะอาดในตัวสามารถเป็นประโยชน์ ...

git clean -fd

1
ใช้กับไฟล์ที่ไม่ได้ติดตามเท่านั้น
Elijah Lynn

1

ฉันมีปัญหาไฟล์ผีนี้ปรากฏขึ้นใน repo ของฉันหลังจากที่ฉันลบพวกเขาและพบคำสั่งเรียบร้อยนี้!

git add -A

โดยพื้นฐานแล้วมันเหมือนกับgit add -aและถูกgit add -uรวมเข้าด้วยกัน ฉันได้รับจากลิงค์สุดยอดนี้ ( ลิงก์นี้ชี้ไปที่เวอร์ชันบน archive.org ตอนนี้เพราะต้นฉบับเปลี่ยนมาเป็นหน้าสแปม / ฟิชชิ่ง ณ เดือนมิถุนายน 2559)


0

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

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

ตรวจสอบให้แน่ใจว่าคุณได้ทดสอบด้วยตัวเลือก - run-run ของ git ก่อนที่จะรันด้วยสิ่งต่อไปนี้:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

คำอธิบาย:

git status --porcelain

พิมพ์ออกมาบางอย่างเช่น D "/ พา ธ ไปยังโฟลเดอร์ / พา ธ ไปยังไฟล์" ซึ่งจะเกิดขึ้นเฉพาะเมื่อมีช่องว่างในชื่อพา ธ

awk '/^.D .*$/ {print $0}'

จับคู่เฉพาะบรรทัดที่ขึ้นต้นด้วย "D"

sed 's/ D \(.*\)/\1/'

ลบ "D" จากด้านหน้าของแต่ละสาย

tr -d '"'

ลบคำพูดถ้ามี

xargs -I {} git rm '{}'

กำหนดตัวแปรชื่อไฟล์เป็น {} เรียกใช้ชื่อไฟล์ภายใต้ git rm ที่อยู่ในเครื่องหมายคำพูดเดี่ยวเพื่อให้แน่ใจว่ารองรับชื่อไฟล์พร้อมช่องว่าง

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