วิธีที่ง่าย™
ปรากฎว่านี่เป็นวิธีปฏิบัติทั่วไปและมีประโยชน์ที่ผู้ซ้อนของ Git ทำให้มันง่าย แต่คุณต้องมี Git รุ่นใหม่ (> = 1.7.11 พฤษภาคม 2012) ดูภาคผนวกสำหรับวิธีการติดตั้ง Git ล่าสุด นอกจากนี้ยังมีตัวอย่างของโลกแห่งความจริงในคำแนะนำด้านล่าง
เตรียม repo เก่า
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
หมายเหตุ: <name-of-folder>
ต้องไม่มีตัวอักษรนำหน้าหรือต่อท้าย ตัวอย่างเช่นโฟลเดอร์ที่ชื่อsubproject
ต้องถูกส่งผ่านเป็นsubproject
ไม่ใช่./subproject/
หมายเหตุสำหรับผู้ใช้ Windows:เมื่อความลึกของโฟลเดอร์ของคุณคือ> 1 <name-of-folder>
ต้องมีตัวคั่นโฟลเดอร์สไตล์ * nix (/) ตัวอย่างเช่นโฟลเดอร์ที่ชื่อpath1\path2\subproject
ต้องถูกส่งผ่านเป็นpath1/path2/subproject
สร้าง repo ใหม่
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
เชื่อมโยง repo ใหม่ไปยัง GitHub หรือที่ใดก็ได้
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
ภายใน Cleanup <big-repo>
, ถ้าต้องการ
git rm -rf <name-of-folder>
หมายเหตุ : สิ่งนี้จะอ้างอิงข้อมูลย้อนหลังทั้งหมดในที่เก็บดูภาคผนวกด้านล่างหากคุณกังวลเกี่ยวกับการยืนยันรหัสผ่านหรือคุณจำเป็นต้องลดขนาดไฟล์ใน.git
โฟลเดอร์ของคุณ
...
เกมส์
เหล่านี้เป็นขั้นตอนเดียวกันกับข้างต้น<meta-named-things>
แต่ต่อไปนี้ขั้นตอนที่แน่นอนของฉันสำหรับพื้นที่เก็บข้อมูลของฉันแทนการใช้
นี่เป็นโครงการที่ฉันมีสำหรับการใช้งานโมดูลเบราว์เซอร์ JavaScript ในโหนด:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
ฉันต้องการแยกโฟลเดอร์เดียวbtoa
ออกเป็นที่เก็บ Git แยกต่างหาก
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
ตอนนี้ฉันมีสาขาใหม่btoa-only
ที่เพิ่งทำไปbtoa
และฉันต้องการสร้างที่เก็บใหม่
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
ต่อไปฉันจะสร้าง repo ใหม่บน GitHub หรือ Bitbucket หรืออะไรก็ตามและเพิ่มเป็น origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
วันที่มีความสุข!
หมายเหตุ:หากคุณสร้าง repo กับที่README.md
, .gitignore
และLICENSE
คุณจะต้องดึงครั้งแรก:
git pull origin master
git push origin master
สุดท้ายฉันจะต้องการลบโฟลเดอร์ออกจาก repo ที่ใหญ่กว่า
git rm -rf btoa
...
ภาคผนวก
Git ล่าสุดบน macOS
วิธีรับ Git รุ่นล่าสุดโดยใช้Homebrew :
brew install git
Git ล่าสุดบน Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
หากไม่ได้ผล (คุณมี Ubuntu รุ่นเก่ามาก) ให้ลอง
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
หากยังไม่ได้ผลให้ลอง
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree
ขอบคุณ rui.araujo จากความคิดเห็น
การล้างประวัติของคุณ
โดยค่าเริ่มต้นการลบไฟล์ออกจาก Git ไม่ได้เป็นการลบออกไปจริงๆมันแค่ยอมรับว่าพวกเขาไม่ได้อยู่ที่นั่นอีกแล้ว หากคุณต้องการลบการอ้างอิงประวัติจริง ๆ (เช่นคุณมีรหัสผ่านที่กำหนด) คุณต้องทำสิ่งนี้:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
หลังจากนั้นคุณสามารถตรวจสอบว่าไฟล์หรือโฟลเดอร์ของคุณไม่ปรากฏในประวัติ Git เลย
git log -- <name-of-folder> # should show nothing
อย่างไรก็ตามคุณไม่สามารถ "ดัน" ลบไปที่ GitHubและสิ่งที่คล้ายกันได้ หากคุณลองคุณจะได้รับข้อผิดพลาดและคุณจะต้องดำเนินการgit pull
ก่อนgit push
- แล้วคุณจะกลับมามีทุกสิ่งในประวัติศาสตร์ของคุณ
ดังนั้นหากคุณต้องการลบประวัติจาก "จุดเริ่มต้น" - หมายถึงลบออกจาก GitHub, Bitbucket และอื่น ๆ - คุณจะต้องลบ repo และกดสำเนา repo ที่ตัดทิ้งอีกครั้ง แต่เดี๋ยวก่อน - มีอีกมาก ! - หากคุณกังวลเกี่ยวกับการลบรหัสผ่านหรืออะไรทำนองนั้นคุณจะต้องตัดการสำรองข้อมูล (ดูด้านล่าง)
ทำให้.git
เล็กลง
คำสั่งลบประวัติดังกล่าวยังคงทิ้งไฟล์สำรองไว้มากมายเพราะ Git นั้นใจดีเกินไปที่จะช่วยให้คุณไม่ทำลาย repo ของคุณโดยไม่ได้ตั้งใจ ในที่สุดมันจะลบไฟล์ที่ถูกโยงถึงในวันและเดือน แต่มันจะทิ้งไว้ชั่วขณะในกรณีที่คุณรู้ว่าคุณบังเอิญลบบางสิ่งที่คุณไม่ต้องการ
ดังนั้นหากคุณต้องการล้างถังขยะเพื่อลดขนาดโคลนของ repo ทันทีคุณต้องทำสิ่งแปลก ๆ ทั้งหมดนี้:
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now
git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune
ที่กล่าวว่าฉันขอแนะนำไม่ให้ทำตามขั้นตอนเหล่านี้จนกว่าคุณจะรู้ว่าคุณต้อง - ในกรณีที่คุณพรุนไดเรกทอรีย่อยผิด y'know? ไฟล์สำรองไม่ควรทำการโคลนเมื่อคุณกด repo ไฟล์เหล่านั้นจะอยู่ในสำเนาของเครื่อง
เครดิต
git filter-branch
ดูคำตอบของฉันด้านล่าง