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


171

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

git clone <path>
git config core.sparsecheckout true
echo <dir> > .git/info/sparse-checkout
git read-tree -m -u HEAD

ปัญหาเกี่ยวกับลำดับของคำสั่งนี้คือการโคลนต้นฉบับก็ทำการเช็คเอาต์ หากคุณเพิ่ม -n ลงในคำสั่ง clone ดั้งเดิมคำสั่ง read-tree จะส่งผลให้เกิดข้อผิดพลาดดังต่อไปนี้:

ข้อผิดพลาด: การชำระเงินแบบเบาบางทำให้ไม่มีรายการในไดเรกทอรีทำงาน

จะทำการเช็คเอาต์แบบเบาบางโดยไม่ต้องตรวจสอบไฟล์ทั้งหมดก่อนได้อย่างไร



หมายเหตุ: git worktree add --no-checkoutจะทำงานด้วย (ไม่เพียงgit clone --no-checkout) กับ git 2.9 (แค่ 2016) ดูคำตอบของฉันด้านล่าง
VonC

หลังจากที่พยายามแก้ปัญหาทั้งหมดได้ที่นี่ที่เดียวเท่านั้นที่เพิ่งดาวน์โหลดไดเรกทอรี (ไม่มีการผลักดันหลังจากนั้น!) จะนี้
LondonRob

คำตอบ:


24

ในปี 2020 มีวิธีจัดการกับการชำระเงินแบบกระจัดกระจายได้ง่ายกว่าโดยไม่ต้องกังวลกับไฟล์. git นี่คือวิธีที่ฉันทำ:

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

โปรดทราบว่ามันต้องมีการติดตั้ง git เวอร์ชั่น 2.25 อ่านเพิ่มเติมได้ที่นี่: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

UPDATE:

ดังกล่าวข้างต้นgit cloneคำสั่งจะยังคงโคลน repo กับประวัติศาสตร์ที่เต็มไปด้วยแม้ว่าจะไม่มีการตรวจสอบไฟล์ออก หากคุณไม่ต้องการประวัติเต็มคุณสามารถเพิ่ม--depthพารามิเตอร์ในคำสั่งเช่นนี้:

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1

1
นั่นคือความจริงจุดดี upvoted ฉันติดตามsparse-checkout --coneคุณสมบัติในstackoverflow.com/a/59515426/6309
VonC

น่าจะเพิ่มการโคลนนิ่งบางส่วน ( --filter) ลงในคำตอบของคุณที่นี่
เทาร

@ alexey-grinko คำสั่งแรกที่ยังคงมีการโคลน repo ทั้งหมดในคำถามแม้ว่ามันจะไม่ได้ตรวจสอบออก ... ฉันกำลังมองหาที่จะประหยัดเวลาที่ไม่ได้โคลนทุกสิ่งที่ฉันไม่ต้องการ .. .
mropp

1
@ motpp ฉันได้อัปเดตคำตอบโดยการเพิ่ม--depthพารามิเตอร์ซึ่งทำให้เราสามารถทำการโคลนแบบตื้นได้ มันจะช่วยได้ไหม @ เต่าไม่แน่ใจว่าจะใช้อย่างไร--filterในกรณีนี้ฉันไม่ได้ลอง คุณสามารถยกตัวอย่างหรือโพสต์คำตอบอื่นในหัวข้อนี้?
Alexey Grinko

4
โปรดทราบว่ามันใช้งานไม่ได้ในรุ่น 2.27 - ฉันไม่รู้ว่าทำไม
Blazes

162

โปรดทราบว่าคำตอบนี้ดาวน์โหลดสำเนาที่สมบูรณ์ของข้อมูลจากที่เก็บ git remote add -fคำสั่งจะโคลนที่เก็บทั้งหมด จากหน้าคนของgit-remote :

ด้วย-fตัวเลือกgit fetch <name>จะถูกเรียกใช้ทันทีหลังจากตั้งค่าข้อมูลระยะไกล


ลองสิ่งนี้:

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add -f origin git://...
echo "path/within_repo/to/desired_subdir/*" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

ตอนนี้คุณจะพบว่าคุณมีการ "เช็คเอาต์" ที่มีเพียงไฟล์จากพา ธ / within_repo / ถึง / ต้องการ_subdirปัจจุบัน (และในเส้นทางนั้น)

โปรดทราบว่าในบรรทัดคำสั่งของ windows คุณจะต้องไม่อ้างอิงพา ธ นั่นคือคุณต้องเปลี่ยนคำสั่งที่ 6 ด้วยอันนี้:

echo path/within_repo/to/desired_subdir/* > .git/info/sparse-checkout

ถ้าคุณทำไม่ได้คุณจะได้รับเครื่องหมายคำพูดในไฟล์ sparse-checkout และมันจะไม่ทำงาน


3
ฉันไม่สามารถใช้คำสั่ง "git checkout [branchname]" (และพบข้อผิดพลาด: การชำระเงินแบบเบาบางทำให้ไม่มีรายการในไดเรกทอรีทำงาน) ฉันใช้ "ต้นกำเนิด git pull master" และทำงานอย่างถูกต้อง
Natty

2
ด้วย git เวอร์ชั่น 1.7.2.5 บน linux, ฉันได้ผลลัพธ์ดังนี้: echo 'dir / *' ตรวจสอบเฉพาะไฟล์ใน dir / แต่ไม่ใช่ในส่วนย่อย; echo 'dir /' (ไม่มีเครื่องหมายดอกจัน!) ตรวจสอบต้นไม้ทั้งหมดอย่างถูกต้องภายใต้ dir / HTH
pavek

37
สิ่งนี้ธรรมดาไม่ได้ผลสำหรับฉัน - คำสั่ง "git remote" ส่งผลให้ repo ทั้งหมดถูกเช็คเอาท์! - จากนั้น; ดังนั้น "git config ... " และข้อมูลจำเพาะของ sub-dir ที่น่าสนใจในคำสั่งต่อไปนี้จึงไม่มีผลกระทบ repo URL ถูกระบุในคำสั่ง "git remote" เพียงแค่พา ธ ไปยังไฟล์. git ระดับบนสุดหรือไม่ หรือควรเป็นเส้นทางไปยังส่วนย่อยย่อยที่น่าสนใจ?
Rob Cranfill

10
นี่คือรุ่นที่มีความคล่องตัว (ไม่จำเป็นต้องสร้างไดเรกทอรีด้วยตนเองทำการเริ่มต้นและเพิ่มระยะไกลเพียงทำ clit git ปกติ + รอบการชำระเงินด้วยตัวเลือก - no-checkout ตามที่กล่าวถึงโดย @onionjake): git clone - no-checkout <project> cd <project> echo <dir>> .git / info / sparse-checkout git checkout <branch>
Gregor

22
git remote addทุกอย่างดาวน์โหลดคำสั่งเพราะเห็นว่าเป็นสิ่งที่-fไม่ - บอกว่ามันสามารถดึงข้อมูลได้ทันทีก่อนที่คุณจะได้กำหนดไว้ในตัวเลือกที่เช็คเอาท์เบาบาง แต่การละเว้นหรือการเรียงลำดับใหม่จะไม่ช่วย การจ่ายเงินแบบเบาบางมีผลเฉพาะกับแผนผังการทำงานเท่านั้นไม่ใช่ที่เก็บข้อมูล หากคุณต้องการให้ที่เก็บของคุณกินอาหารแทนคุณต้องดูที่ตัวเลือก--depthหรือ--single-branchตัวเลือกแทน
Miral

43

Git clone มีตัวเลือก ( --no-checkoutหรือ-n) ที่ทำในสิ่งที่คุณต้องการ

ในรายการคำสั่งของคุณเพียงแค่เปลี่ยน:

git clone <path>

สำหรับสิ่งนี้:

git clone --no-checkout <path>

จากนั้นคุณสามารถใช้การชำระเงินเบาบางตามที่ระบุไว้ในคำถาม


7
ใช่มันไม่ได้ทำการเช็คเอาท์ แต่ยังมีการดึงข้อมูลเพื่อดาวน์โหลดประวัติ repo ทั้งหมด
Jason S

9
@ Jason คำถามคือโดยเฉพาะเกี่ยวกับการไม่ชำระเงิน หากคุณไม่ต้องการประวัติทั้งหมดให้ใช้--depth <depth>ตัวเลือกบน git clone สิ่งนั้นจะดาวน์โหลดเฉพาะการคอมมิทล่าสุด<depth>จากประวัติ ขณะนี้ยังไม่มีวิธีดาวน์โหลดการคอมมิทด้วย git เพียงบางส่วน แต่หากรีโมตของคุณรองรับคุณสามารถใช้git archive --remoteเพื่อดาวน์โหลดไฟล์บางส่วนได้
onionjake

ขณะนี้คุณสามารถ 'ตรวจสอบ' กระทำโดยไม่ต้องดาวน์โหลดไฟล์ใด ๆ ที่ใช้vfsforgit.org สิ่งนี้อาจมีประโยชน์หากมีคนพยายามเช็คเอาต์ชุดย่อยขนาดเล็กของคำสั่งเดียว
onionjake

22

ฉันมีกรณีการใช้งานที่คล้ายกันยกเว้นฉันต้องการชำระเงินเฉพาะการกระทำสำหรับแท็กและตัดไดเรกทอรี การใช้--depth 1ทำให้เบาบางและเร่งความเร็วได้มากขึ้น

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add origin <url>  # Note: no -f option
echo "path/within_repo/to/subdir/" > .git/info/sparse-checkout
git fetch --depth 1 origin tag <tagname>
git checkout <tagname>

3
- ความลึก 1 เรียกว่าโคลนตื้นเพียง FYI
Mark Allison

1
สิ่งนี้ช่วย! ขอบคุณ
kp123

1
ขอบคุณสำหรับสิ่งนี้. ทำให้ถูกต้องกับสิ่งนี้หลังจากลองวิธีอื่น ๆ อีกมากมายเพื่อป้องกันการดาวน์โหลด repo ทั้งหมด
เจ ...

12

ฉันพบคำตอบที่ฉันกำลังมองหาจากหนึ่งซับที่โพสต์ก่อนหน้านี้โดย pavek (ขอบคุณ!) ดังนั้นฉันต้องการที่จะให้คำตอบที่สมบูรณ์ในคำตอบเดียวที่ทำงานบนLinux (GIT 1.7.1):

1--> mkdir myrepo
2--> cd myrepo
3--> git init
4--> git config core.sparseCheckout true
5--> echo 'path/to/subdir/' > .git/info/sparse-checkout
6--> git remote add -f origin ssh://...
7--> git pull origin master

ฉันเปลี่ยนลำดับของคำสั่งเล็กน้อย แต่ดูเหมือนจะไม่มีผลกระทบใด ๆ กุญแจสำคัญคือการปรากฏตัวของเครื่องหมายทับต่อท้าย "/" ที่ส่วนท้ายของเส้นทางในขั้นตอนที่ 5


3
คุณแน่ใจหรือว่านี่คือสิ่งที่คุณต้องการ -f หมายถึงการดึงข้อมูลทั้งหมดคุณยังได้รับข้อมูลอื่น ๆ ทั้งหมดที่คุณไม่ต้องการและมันช้า (นี่คือ "การตรวจสอบพื้นที่เก็บข้อมูลทั้งหมด")
Shuman

1
ฉันลองขั้นตอนข้างต้นใน Windows แต่การเช็คเอาต์สำรองไม่ทำงานในพรอมต์คำสั่งดังนั้นฉันจึงลองเชลล์ Git Bash และใช้งานได้ !! พรอมต์คำสั่งสามารถดำเนินการคำสั่ง git ทั้งหมดเช่น push, pull และ etc แต่เมื่อมันมาถึงการชำระเงินเบาบางมันล้มเหลว
user593029

วิธีทำเฉพาะไฟล์ในไดเรกทอรีย่อย ฉันต้องการดึงไฟล์เฉพาะในไดเรกทอรีย่อยที่ระบุ
Babish Shrestha

@BabishShrestha ดูความคิดเห็นโดย onionjake บนคำตอบอื่น ๆ FWIW: |
rogerdpack

9

น่าเสียดายที่ข้อผิดพลาดข้างต้นไม่ได้ผลสำหรับฉันดังนั้นฉันจึงใช้เวลานานมากในการลองใช้ชุดsparse-checkoutไฟล์ที่แตกต่างกัน

ในกรณีของฉันฉันต้องการข้ามโฟลเดอร์ด้วย IntelliJ IDEA configs

นี่คือสิ่งที่ฉันทำ:


วิ่ง git clone https://github.com/myaccount/myrepo.git --no-checkout

วิ่ง git config core.sparsecheckout true

สร้าง.git\info\sparse-checkoutด้วยเนื้อหาดังต่อไปนี้

!.idea/*
!.idea_modules/*
/*

เรียกใช้ 'ชำระเงิน git -' เพื่อรับไฟล์ทั้งหมด


สิ่งสำคัญที่ทำให้มันใช้งานได้คือการเพิ่ม/*หลังจากชื่อโฟลเดอร์

ฉันมีคอมไพล์ 1.9


3
ไม่, มันยังคงดาวน์โหลดทุกอย่าง, ทุกคอม
มิต

6
การชำระเงินแบบเบาบางส่งผลกระทบต่อแผนผังการทำงานเท่านั้น จะไม่มีผลกับขนาดของที่เก็บหรือสิ่งที่ถูกดึงออกมา คุณต้องการตัวเลือกต่าง ๆ ถ้าคุณต้องการ
Miral

ลองใช้ Git Bash Shell ครั้งต่อไปหากทำงานใน Windows และใช้ขั้นตอนข้างต้นโดย 'pbetkier' มันใช้งานได้ดี
user593029

6

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

วิธีที่ดีในการทำเช่นนี้

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r HEAD จะดาวน์โหลดการแก้ไขครั้งล่าสุดเท่านั้นไม่สนใจประวัติทั้งหมด

  2. หมายเหตุtrunkและ / โฟลเดอร์เฉพาะ

คัดลอก URL /trunk/และการเปลี่ยนแปลงก่อนและหลัง ฉันหวังว่านี่จะช่วยใครซักคน สนุก :)

อัปเดตเมื่อวันที่ 26 ก.ย. 2019


ใช้ได้เฉพาะกับผู้ที่มาจากหรือใช้ svn จะไม่ลงคะแนนโหวตอันนี้
C Johnson เมื่อ

@Cohnson อย่างที่คุณเห็นฉันกำลังโคลนโฟลเดอร์ repo git ทำงานได้ดี
Qamar

1
โปรดทราบว่านี่ไม่ใช่สิ่งที่ git นำเสนอนอกกรอบ แต่เป็นสิ่งที่ฮับ Git นำเสนออยู่ติดกับข้อเสนอ Git ปกติ อย่างไรก็ตามมันทำงานได้อย่างสวยงามเมื่อคุณสามารถใช้งานได้ ขอบคุณ!
Qix - MONICA ถูกยกเลิก

1
จากคำแนะนำมากมายใน SO ของคุณเป็นทางออกที่กระชับและชัดเจนที่สุด
boardrider

4

git 2.9 (มิถุนายน 2559) จะสรุป--no-checkoutตัวเลือกให้กับgit worktree add(คำสั่งที่อนุญาตให้ทำงานกับต้นไม้ทำงานหลายต้นสำหรับ repo หนึ่งอัน )

ดูกระทำ ef2a0ac (29 มีนาคม 2016) โดยเรย์เหวย (OneRaynyDay )
ช่วยโดย: เอริคซันไชน์ ( sunshineco)และJunio C Hamano (gitster )
(รวมโดยJunio C Hamano - gitster-ในการกระทำ 0d8683c , 13 เมษายน 2016)

git worktreeหน้าคนในขณะนี้รวมถึง:

--[no-]checkout:

โดยค่าเริ่มต้นaddการตรวจสอบออก<branch>แต่--no-checkoutสามารถใช้ในการเช็คเอาท์ปราบเพื่อที่จะทำให้การปรับแต่งเช่นการกำหนดค่าเบาบางเช็คเอาต์


4

ขั้นตอนในการชำระเงินแบบกระจายเพียงโฟลเดอร์เฉพาะ:

1) git clone --no-checkout  <project clone url>  
2) cd <project folder>
3) git config core.sparsecheckout true   [You must do this]
4) echo "<path you want to sparce>/*" > .git/info/sparse-checkout
    [You must enter /* at the end of the path such that it will take all contents of that folder]
5) git checkout <branch name> [Ex: master]

FYI ในขั้นตอนแรก (1) คุณไม่จำเป็นต้องใช้ - ไม่มีการชำระเงิน เพียงทำสำเนา repo ทั้งหมดแล้วดำเนินการตามขั้นตอนด้านล่าง 2-5 (ดังที่กล่าวไว้ข้างต้น) คุณจะได้ผลลัพธ์ที่คุณต้องการ แจ้งให้เราทราบหากคุณไม่ได้รับมัน
SANDEEP MACHIRAJU

4

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

$ cd linux
$ du -sh .git .
2.1G    .git
894M    .
$ du -sh 
2.9G    .
$ mkdir ../linux-sparse-test
$ cd ../linux-sparse-test
$ git init
Initialized empty Git repository in /…/linux-sparse-test/.git/
$ git config core.sparseCheckout true
$ git remote add origin ../linux
# Parameter "origin master" saves a tiny bit if there are other branches
$ git fetch --depth=1 origin master
remote: Enumerating objects: 65839, done.
remote: Counting objects: 100% (65839/65839), done.
remote: Compressing objects: 100% (61140/61140), done.
remote: Total 65839 (delta 6202), reused 22590 (delta 3703)
Receiving objects: 100% (65839/65839), 173.09 MiB | 10.05 MiB/s, done.
Resolving deltas: 100% (6202/6202), done.
From ../linux
 * branch              master     -> FETCH_HEAD
 * [new branch]        master     -> origin/master
$ echo "Documentation/hid/*" > .git/info/sparse-checkout
$ git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
$ ls -l
total 4
drwxr-xr-x 3 abe abe 4096 May  3 14:12 Documentation/
$  du -sh .git .
181M    .git
100K    .
$  du -sh
182M    .

ดังนั้นฉันได้ลงจาก 2.9GB เป็น 182MB ซึ่งมันเงียบดีอยู่แล้ว

แม้ว่าฉันจะไม่ได้รับสิ่งนี้เพื่อทำงานกับgit clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test( บอกใบ้ที่นี่ ) จากนั้นไฟล์ที่ขาดหายไปจะถูกเพิ่มเป็นไฟล์ที่ถูกลบไปยังดัชนี ดังนั้นหากใครรู้ว่าเทียบเท่าgit clone --filter=blob:noneสำหรับgit fetchเราอาจจะสามารถบันทึกเมกะไบต์เพิ่มเติม (การอ่าน man page ของgit-rev-listคำใบ้ก็มีบางสิ่งที่เหมือน--filter=sparse:path=…กัน แต่ฉันก็ไม่ได้ทำงานเช่นกัน

(พยายามทั้งหมดด้วย git 2.20.1 จาก Debian Buster)


1
ข้อเสนอแนะที่น่าสนใจ upvoted ฉันก็ไม่รู้--filter=sparse:path=…เหมือนกัน
VonC

3

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

น่าสนใจถ้าคุณเช็คเอาต์ไดเรกทอรีที่ไม่ได้อยู่ในไฟล์ sparse-checkout ดูเหมือนว่าจะไม่แตกต่างกัน พวกเขาจะไม่แสดงในสถานะ git และ git read-tree -m -u HEAD ไม่ได้ทำให้มันถูกลบออก git reset - ฮาร์ดไม่ทำให้ไดเรกทอรีถูกลบอย่างใดอย่างหนึ่ง ทุกคนมีประสบการณ์มากขึ้นที่จะแสดงความคิดเห็นเกี่ยวกับสิ่งที่คอมไพล์คิดว่าของไดเรกทอรีที่มีการตรวจสอบ แต่ที่ไม่ได้อยู่ในไฟล์เช็คเอาต์กระจัดกระจาย?


0

ในกรณีของฉันฉันต้องการข้ามPodsโฟลเดอร์เมื่อโคลนโครงการ ฉันทำทีละขั้นตอนเหมือนด้านล่างและใช้งานได้สำหรับฉัน หวังว่ามันจะช่วย

mkdir my_folder
cd my_folder
git init
git remote add origin -f <URL>
git config core.sparseCheckout true 
echo '!Pods/*\n/*' > .git/info/sparse-checkout
git pull origin master

ข้อควรจำหากคุณต้องการข้ามโฟลเดอร์เพิ่มเพียงเพิ่มบรรทัดเพิ่มเติมในไฟล์ sparse-checkout

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