Git: จะลบไฟล์ออกจากการกระทำในอดีตได้อย่างไร?


113

ฉันได้กระทำกับ id 56f06019 (ตัวอย่าง) ในการกระทำนั้นฉันได้ส่งไฟล์ขนาดใหญ่โดยไม่ได้ตั้งใจ (50Mb) ในคอมมิตอื่นฉันเพิ่มไฟล์เดียวกัน แต่มีขนาดที่เหมาะสม (เล็ก) ตอนนี้ repo ของฉันเมื่อฉันโคลนหนักเกินไป :( จะลบไฟล์ขนาดใหญ่นั้นออกจากประวัติ repo เพื่อลดขนาด repo ของฉันได้อย่างไร


ในกรณีของฉันมันไม่ใช่ไฟล์ขนาดใหญ่ แต่เป็นไฟล์คอนฟิกูเรชันที่มีเครดิตฐานข้อมูล ฉันเรียนคอมไพล์ตอนนั้นฉันไม่รู้จัก. gitignore
Rashi


1
ที่เกี่ยวข้องhelp.github.com/articles/…
Trevor Boyd Smith

คำตอบ:


165

บทที่ 9 ของPro Gitหนังสือมีส่วนในการลบวัตถุ

ให้ฉันสรุปขั้นตอนสั้น ๆ ที่นี่:

git filter-branch --index-filter \
    'git rm --cached --ignore-unmatch path/to/mylarge_50mb_file' \
    --tag-name-filter cat -- --all

เช่นเดียวกับตัวเลือก rebasing ที่อธิบายไว้ก่อนหน้าfilter-branchนี้คือการดำเนินการเขียนใหม่ หากคุณเคยเผยแพร่ประวัติคุณจะต้องส่ง--forceข้อมูลอ้างอิงใหม่

filter-branchวิธีการเป็นอย่างมากที่มีประสิทธิภาพมากขึ้นกว่าrebaseวิธีการเพราะมัน

  • ช่วยให้คุณสามารถทำงานกับทุกสาขา / อ้างอิงในครั้งเดียว
  • เปลี่ยนชื่อแท็กได้ทันที
  • ทำงานได้อย่างหมดจดแม้ว่าจะมีการผสานรวมหลายครั้งตั้งแต่การเพิ่มไฟล์
  • ทำงานได้อย่างหมดจดแม้ว่าไฟล์จะถูกเพิ่ม / ลบหลายครั้งในประวัติของ (a) branch (es)
  • ไม่สร้างคอมมิตใหม่ที่ไม่เกี่ยวข้อง แต่จะคัดลอกในขณะที่แก้ไขทรีที่เกี่ยวข้อง ซึ่งหมายความว่าสิ่งต่างๆเช่นการเซ็นสัญญาคอมมิตบันทึก ฯลฯ จะถูกเก็บรักษาไว้

filter-branch สำรองข้อมูลไว้ด้วยดังนั้นขนาดของ repo จะไม่ลดลงทันทีเว้นแต่คุณจะหมดอายุ reflogs และการรวบรวมขยะ:

rm -Rf .git/refs/original       # careful
git gc --aggressive --prune=now # danger

1
เป็นที่น่าสังเกตว่าสิ่งนี้ดูเหมือนจะไม่ทำงานภายใต้ windows cmd.exe ดูเหมือนว่าจะทำงานภายใต้ cygwin ได้ดี
ชื่อปลอม

2
ฉันได้รับ git filter-branch ข้างต้นเพื่อทำงานโดยใช้ double-quotes แทน single-quotes (บน Windows Server 2012 cmd.exe)
JCii

1
สิ่งที่ได้ผลสำหรับฉันคือบรรทัดคำสั่งสาขาตัวกรองนี้ git filter-branch --force --index-filter 'git rm --ignore-unmatch --cached PathTo/MyFile/ToRemove.dll' -- fbf28b005^.. แล้วrm --recursive --force .git/refs/originalและrm --recursive --force .git/logs จากนั้นผมใช้git prune --expire now และgit gc --aggressive นี้ทำงานที่ดีกว่าสำหรับผมกว่าขั้นตอนที่แน่นอนของคุณระบุไว้ข้างต้น ขอบคุณสำหรับการรวมลิงก์ไปยังหนังสือ Git Pro เนื่องจากเป็นสิ่งล้ำค่า
dacke.geo

หลังจากคำสั่ง filter-branch วิธีเดียวที่ฉันจะได้ขนาดของโฟลเดอร์. git คือทำตามคำสั่งที่พบที่นี่: stackoverflow.com/questions/1904860/… git -c gc.reflogExpire = 0 -c gc reflogExpireUnreachable = 0 -c gc.rerereresolved = 0 \ -c gc.rerereunresolved = 0 -c gc.pruneExpire = now gc "$ @"
Steve Ardis

สำหรับการลดขนาด repo ฉันใช้คำสั่งที่ระบุไว้ใน git filter-branch doc: git-scm.com/docs/…
Ludovic Ronsin


0

คุณจะต้องgit rebaseในโหมดโต้ตอบดูตัวอย่างที่นี่: ฉันจะลบคอมมิตบน GitHub ได้อย่างไร และวิธีการเอากระทำเก่า

หากคอมมิตของคุณอยู่ที่ HEAD ลบ 10 คอมมิต:

$ git rebase -i HEAD~10

หลังจากฉบับประวัติของคุณคุณต้องพุชประวัติ "ใหม่" คุณต้องเพิ่มการ+บังคับ (ดู refspec ในตัวเลือกการกด ):

$ git push origin +master

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


3
ซึ่งไม่ได้ลบไฟล์ขนาดใหญ่ออกจากประวัติ นอกจากนี้วิธีการที่ยอมรับแรงผลักดันgit push --forceหรือgit push -f(ซึ่งไม่จำเป็นต้องมีคนที่จะรู้เป้าหมายสาขาการผลักดัน)
sehe

จากคำถามไฟล์ใหม่จะเหมือนกับไฟล์เก่าทุกประการนั่นคือเส้นทางเดียวกัน นี่คือสาเหตุที่คุณไม่สามารถใช้git rmบนเส้นทางได้โดยตรง
Loïc d'Anterroches

2
@sehe ถ้าคุณทำ rebase เพื่อกำจัดการกระทำด้วยไฟล์ขนาดใหญ่มันจะหายไป
vonbrand

@vonbrand จากสาขานั้นที่คุณรีบิวต์เท่านั้น ฉันไม่ได้สมมติว่าสาขา 'จาก' ถูกลบ แต่ถ้าคุณลบกิ่งไม้แก้ไขมันจะช่วยได้: _
เห็น

@ แน่นอนคุณต้องไล่สาขาทั้งหมดที่มีการกระทำผิด หากก่อนที่ repo จะมีความวุ่นวายคุณจะต้องจัดระเบียบใหม่ให้ทำมากมาย แต่ rebase เป็นเครื่องมือสำหรับสิ่งนี้
vonbrand

0

ฉันลองใช้คำตอบต่อไปนี้บน windows https://stackoverflow.com/a/8741530/8461756

คำพูดเดี่ยวใช้ไม่ได้กับ windows คุณต้องมีเครื่องหมายคำพูดคู่

ต่อไปนี้ทำงานให้ฉัน

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PathRelativeRepositoryRoot / bigfile.csv" - --all

หลังจากลบไฟล์ขนาดใหญ่แล้วฉันสามารถพุชการเปลี่ยนแปลงไปยัง github master ได้


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