สิ่งที่คุณต้องการทำคือก่อกวนอย่างมากหากคุณเผยแพร่ประวัติแก่ผู้พัฒนารายอื่น โปรดดู“ การกู้คืนจากการอัปสตรีม Rebase” ในgit rebase
เอกสารประกอบสำหรับขั้นตอนที่จำเป็นหลังจากซ่อมแซมประวัติของคุณ
คุณมีอย่างน้อยสองตัวเลือก: git filter-branch
และการรีบูตแบบโต้ตอบทั้งคู่อธิบายไว้ด้านล่าง
การใช้ git filter-branch
ผมมีปัญหาที่คล้ายกันที่มีขนาดใหญ่การทดสอบข้อมูลไบนารีจากการนำเข้าการโค่นล้มและเขียนเกี่ยวกับการลบข้อมูลจากเก็บคอมไพล์
บอกว่าประวัติคอมไพล์ของคุณคือ:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
โปรดทราบว่าgit lola
เป็นนามแฝงที่ไม่ได้มาตรฐาน แต่มีประโยชน์อย่างมาก ด้วย--name-status
สวิทช์เราสามารถเห็นการแก้ไขทรีที่เกี่ยวข้องกับแต่ละการกระทำ
ในการกระทำ“ ประมาท” (ชื่อวัตถุของ SHA1 คือ ce36c98) ไฟล์oops.iso
คือ DVD-rip ที่ถูกเพิ่มเข้าไปโดยไม่ตั้งใจและถูกลบออกในการคอมมิชชันถัดไป cb14efd การใช้เทคนิคที่อธิบายไว้ในบล็อกโพสต์ดังกล่าวคำสั่งในการดำเนินการคือ:
git filter-branch --prune-empty -d /dev/shm/scratch \
--index-filter "git rm --cached -f --ignore-unmatch oops.iso" \
--tag-name-filter cat -- --all
ตัวเลือก:
--prune-empty
ลบการกระทำที่กลายเป็นที่ว่างเปล่า ( เช่นอย่าเปลี่ยนต้นไม้) อันเป็นผลมาจากการดำเนินการตัวกรอง ในกรณีทั่วไปตัวเลือกนี้จะสร้างประวัติที่สะอาดกว่า
-d
ตั้งชื่อไดเรกทอรีชั่วคราวที่ยังไม่มีอยู่สำหรับสร้างประวัติที่ถูกกรอง หากคุณกำลังทำงานบนลินุกซ์กระจายทันสมัยระบุต้นไม้/dev/shm
จะส่งผลในการดำเนินการได้เร็วขึ้น
--index-filter
เป็นเหตุการณ์หลักและทำงานกับดัชนีในแต่ละขั้นตอนในประวัติศาสตร์ คุณต้องการลบoops.iso
ที่ใดก็ตามที่พบ แต่จะไม่ปรากฏในทุกการกระทำ คำสั่งgit rm --cached -f --ignore-unmatch oops.iso
ลบ DVD-rip เมื่อมีอยู่และไม่ล้มเหลวเป็นอย่างอื่น
--tag-name-filter
อธิบายวิธีเขียนชื่อแท็กซ้ำ ตัวกรองcat
คือการดำเนินการระบุตัวตน ที่เก็บของคุณเช่นตัวอย่างด้านบนอาจไม่มีแท็กใด ๆ แต่ฉันได้รวมตัวเลือกนี้ไว้สำหรับการใช้งานทั่วไป
--
ระบุจุดสิ้นสุดของตัวเลือกเพื่อ git filter-branch
--all
ต่อไปนี้--
เป็นชวเลขสำหรับการอ้างอิงทั้งหมด ที่เก็บของคุณเช่นเดียวกับตัวอย่างด้านบนอาจมีผู้อ้างอิง (master) เพียงคนเดียว แต่ฉันได้รวมตัวเลือกนี้ไว้สำหรับเรื่องทั่วไป
หลังจากปั่นป่วนประวัติตอนนี้:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
|
| * f772d66 (refs/original/refs/heads/master) Login page
| | A login.html
| * cb14efd Remove DVD-rip
| | D oops.iso
| * ce36c98 Careless
|/ A oops.iso
| A other.html
|
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
ขอให้สังเกตว่าการกระทำที่ "ประมาท" ใหม่จะเพิ่มขึ้นเท่านั้นother.html
และการกระทำที่ "ลบ DVD-rip" จะไม่อยู่ในสาขาหลักอีกต่อไป สาขาที่มีข้อความระบุว่าrefs/original/refs/heads/master
คุณมีข้อผูกพันดั้งเดิมในกรณีที่คุณทำผิดพลาด หากต้องการลบให้ทำตามขั้นตอนใน“ รายการตรวจสอบสำหรับลดขนาดพื้นที่เก็บข้อมูล”
$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now
สำหรับทางเลือกที่ง่ายกว่าให้โคลนที่เก็บเพื่อทิ้งบิตที่ไม่ต้องการ
$ cd ~/src
$ mv repo repo.old
$ git clone file:///home/user/src/repo.old repo
การใช้file:///...
โคลน URL จะคัดลอกวัตถุแทนที่จะสร้างฮาร์ดลิงก์เท่านั้น
ตอนนี้ประวัติของคุณคือ:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
ชื่อวัตถุ SHA1 สำหรับการกระทำสองรายการแรก (“ ดัชนี” และ“ หน้าผู้ดูแลระบบ”) ยังคงเหมือนเดิมเพราะการดำเนินการตัวกรองไม่ได้แก้ไขการกระทำเหล่านั้น “ ประมาท” หายไปoops.iso
และ“ หน้าเข้าสู่ระบบ” ได้รับผู้ปกครองใหม่ดังนั้น SHA1 ของพวกเขาจึงเปลี่ยนไป
rebase แบบโต้ตอบ
ด้วยประวัติของ:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
คุณต้องการลบออกoops.iso
จาก "ประมาท" ราวกับว่าคุณไม่ได้เพิ่มมันแล้ว "ลบ DVD-rip" นั้นไร้ประโยชน์สำหรับคุณ ดังนั้นแผนของเราที่จะเข้าสู่การปฏิเสธแบบโต้ตอบคือการรักษา“ หน้าผู้ดูแลระบบ” แก้ไข“ ประมาท” และยกเลิก“ ลบ DVD-rip”
การ$ git rebase -i 5af4522
เริ่มต้นใช้งานตัวแก้ไขพร้อมเนื้อหาดังต่อไปนี้
pick ce36c98 Careless
pick cb14efd Remove DVD-rip
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
ดำเนินการตามแผนของเราเราปรับเปลี่ยนเป็น
edit ce36c98 Careless
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
# ...
นั่นก็คือเราลบบรรทัดที่มี“ลบ DVD-ฉีก” และเปลี่ยนการดำเนินการที่“ประมาท” ที่จะเป็นมากกว่าedit
pick
การเลิกเขียนตัวแก้ไขทำให้เราที่พร้อมท์คำสั่งพร้อมข้อความต่อไปนี้
Stopped at ce36c98... Careless
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
ตามที่ข้อความบอกเราเราอยู่ที่“ ประมาท” ที่เราต้องการแก้ไขดังนั้นเราจึงเรียกใช้สองคำสั่ง
$ git rm --cached oops.iso
$ git commit --amend -C HEAD
$ git rebase --continue
ไฟล์แรกจะลบไฟล์ที่ละเมิดออกจากดัชนี ขั้นที่สองแก้ไขหรือแก้ไข“ ประมาท” ให้เป็นดัชนีที่ได้รับการปรับปรุงและ-C HEAD
สั่งให้คอมไพล์กลับมาใช้ข้อความยืนยันเดิมอีกครั้ง ในที่สุดgit rebase --continue
ไปข้างหน้ากับส่วนที่เหลือของการดำเนินการ rebase
สิ่งนี้ให้ประวัติของ:
$ git lola --name-status
* 93174be (HEAD, master) Login page
| A login.html
* a570198 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
สิ่งที่คุณต้องการ