ทำ "ส่งออก git" (เช่น "ส่งออก svn") หรือไม่


2356

ฉันสงสัยว่ามีทางออกที่ดี "git ส่งออก" ที่สร้างสำเนาของต้นไม้โดยไม่มี.gitไดเรกทอรีพื้นที่เก็บข้อมูล มีอย่างน้อยสามวิธีที่ฉันรู้:

  1. git cloneตามด้วยการลบ.gitไดเรกทอรีที่เก็บ
  2. git checkout-index alludes ฟังก์ชั่นนี้ แต่เริ่มต้นด้วย "เพียงแค่อ่านต้นไม้ที่ต้องการลงในดัชนี ... " ซึ่งฉันไม่แน่ใจว่าจะทำอย่างไร
  3. git-exportเป็นสคริปต์ของบุคคลที่สามที่ทำหน้าที่git cloneเป็นสถานที่ชั่วคราวตามด้วยrsync --exclude='.git'ปลายทางสุดท้าย

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


1
@rnrTom: ดูคำตอบของ Somov (ไม่มีสิ่งใด "บีบอัด" ในไฟล์เก็บถาวร tar)
etarion

23
@mrTom git archive --format zip --output "output.zip" master -0จะให้การบีบอัดที่ไม่มีการบีบอัดให้คุณ (-0 คือการตั้งค่าสถานะสำหรับการไม่บีบอัด) git-scm.com/docs/git-archive

7
ฉันเห็นด้วยกับ @mrTom และฉันไม่คิดว่าไฟล์เก็บถาวรถูกบีบอัดหรือไม่บีบอัดเป็นปัญหาหลักหรือไม่ ด้วย SVN ฉันสามารถexportไดเรกทอรีย่อย 250 kB โดยตรงจากที่เก็บระยะไกล (ซึ่งอาจมีขนาด 200 MB ไม่รวมการแก้ไข) - และฉันจะเข้าชมเครือข่ายสำหรับการถ่ายโอนดาวน์โหลด 250 kB (หรือมากกว่านั้น) ด้วยgit, archiveจะต้องมีการเปิดใช้งานบนเซิร์ฟเวอร์ (ดังนั้นฉันไม่สามารถทดลองใช้งานได้) - clone --depth 1จากเซิร์ฟเวอร์อาจยังคงเรียก repo ของการพูด 25 MB ซึ่งเป็น.gitโฟลเดอร์ย่อยเพียงอย่างเดียวใช้เวลา 15MB ดังนั้นฉันยังคงบอกว่าคำตอบคือ "ไม่"
sdaau

@ mrTom คำตอบคือใช่ใช่ดูคำตอบของ OP - คำสั่งคือgit checkout-index
nocache

นี่เป็นวิธีที่ดีและเรียบง่าย:git archive -o latest.zip HEAD
Evgeni Sergeev

คำตอบ:


2397

git archiveน่าจะเป็นวิธีที่ง่ายที่สุดเพื่อให้บรรลุนี้ด้วย หากคุณต้องการต้นไม้ที่ขยายออกมาจริงๆคุณสามารถทำสิ่งนี้ได้

git archive master | tar -x -C /somewhere/else

เวลาส่วนใหญ่ที่ฉันต้องการ 'ส่งออก' บางอย่างจากคอมไพล์ฉันต้องการเก็บถาวรที่บีบอัดในกรณีใด ๆ ดังนั้นฉันทำสิ่งนี้

git archive master | bzip2 >source-tree.tar.bz2

ไฟล์ ZIP:

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive สำหรับรายละเอียดเพิ่มเติมมันค่อนข้างยืดหยุ่น


โปรดทราบว่าแม้ว่าไฟล์เก็บถาวรจะไม่มีไดเรกทอรี. git แต่จะมีไฟล์เฉพาะ git ที่ซ่อนอยู่เช่น. gitignore,. gitattributes ฯลฯ หากคุณไม่ต้องการให้อยู่ในไฟล์เก็บถาวร ใช้แอ็ตทริบิวต์ export-ละเว้นในไฟล์. gitattributes และยอมรับสิ่งนี้ก่อนทำการเก็บถาวรของคุณ อ่านเพิ่มเติม...


หมายเหตุ: หากคุณสนใจที่จะส่งออกดัชนีคำสั่งคือ

git checkout-index -a -f --prefix=/destination/path/

(ดูคำตอบของ Gregสำหรับรายละเอียดเพิ่มเติม)


198
ไฟล์เก็บถาวรของ ZIP:git archive --format zip --output /full/path master
Vadim

221
โปรดทราบว่าไฟล์เก็บถาวรจะไม่มีไดเรกทอรี. git แต่จะมีไฟล์เฉพาะ git ที่ซ่อนอยู่เช่น. gitignore,. gitattributes ฯลฯ ดังนั้นหากคุณไม่ต้องการให้แน่ใจว่าคุณใช้แอตทริบิวต์ export-ละเว้น เป็น. gitattributes ไฟล์และคอมมิทนี้ก่อนที่จะทำการเก็บถาวรของคุณ ดูFeeding.cloud.geek.nz/2010/02/…
mj1531

54
ในการติดตามบันทึกของสตรีม: คุณสามารถเพิ่มสตริง '--prefix = something /' ลงในคำสั่งเพื่อควบคุมชื่อไดเรกทอรีที่จะถูกบรรจุภายในซิป ตัวอย่างเช่นถ้าคุณใช้git archive --format zip --output /path/to/file.zip --prefix=newdir/ masterผลลัพธ์จะถูกเรียกว่า 'file.zip' แต่เมื่อคุณแกะออกไดเรกทอรีระดับบนสุดจะเป็น 'newdir' (หากคุณไม่ใช้แอททริบิวต์ --prefix ระดับบนสุดจะเป็น 'ไฟล์')
Alan W. Smith

89
วิธีที่ง่ายที่สุด: git archive -o latest.zip HEADมันสร้างไฟล์เก็บถาวร Zip ที่มีเนื้อหาของการส่งข้อมูลล่าสุดในสาขาปัจจุบัน โปรดทราบว่ารูปแบบเอาต์พุตถูกอนุมานโดยส่วนขยายของไฟล์เอาต์พุต
nacho4d

37
มันไม่รองรับ submodules git :(
umpirsky

320

ฉันพบว่าตัวเลือก 2 หมายถึงอะไร จากที่เก็บคุณสามารถทำได้:

git checkout-index -a -f --prefix=/destination/path/

เครื่องหมายทับที่ท้ายเส้นทางมีความสำคัญมิฉะนั้นจะทำให้ไฟล์อยู่ใน / ปลายทางด้วยคำนำหน้า 'path'

เนื่องจากในสถานการณ์ปกติดัชนีมีเนื้อหาของที่เก็บไม่มีอะไรพิเศษที่ต้องทำเพื่อ "อ่านต้นไม้ที่ต้องการลงในดัชนี" มันมีอยู่แล้ว

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

สิ่งนี้ดูเหมือนจะเป็น "ส่งออกคอมไพล์" ฉันกำลังมองหา


73
... และอย่าลืม SLASH ในตอนท้ายมิฉะนั้นคุณจะไม่มีเอฟเฟกต์ที่ต้องการ;)
conny

1
git addคำสั่งเปลี่ยนแปลงเนื้อหาในดัชนีดังนั้นสิ่งที่git statusแสดงให้เห็นว่า "ความมุ่งมั่นที่จะเป็น" คือความแตกต่างระหว่างหัวและเนื้อหาของดัชนี
Greg Hewgill

7
@conny: อ่านความคิดเห็นของคุณลืมมันและเรียกใช้คำสั่งโดยไม่ต้องต่อท้ายเฉือน คำแนะนำ: ปฏิบัติตามคำแนะนำของ
conny

35
+1 ตามคำแนะนำของ conny นอกจากนี้อย่าพยายามสร้าง '~ / dest /' เนื่องจากจะสร้างไดเรกทอรีชื่อ '~' ในไดเรกทอรีทำงานแทนที่จะเป็นสิ่งที่คุณต้องการจริงๆ คาดเดาสิ่งที่เกิดขึ้นเมื่อคุณพิมพ์คำสั่ง rm -rf ~
Kyle Heironimus

5
@KyleHeironimus - คำเตือนของคุณเกี่ยวกับการใช้ '~ / dest / `เป็นจริงถ้าคุณใช้อัญประกาศรอบคำนำหน้าพา ธ ของคุณซึ่งบอกเชลล์ไม่ให้ดำเนินการขยายตัวหนอน dir ที่เรียกว่า~(ไม่ใช่'~'!) จะถูกสร้างขึ้นใน dir ที่ทำงานของคุณ ไม่มีอะไรพิเศษเกี่ยวกับเรื่องgit checkout-indexนี้: สิ่งนี้เป็นเรื่องจริงmkdir '~/dest'( อย่าทำอย่างนั้น! ) อีกเหตุผลที่ดีที่จะหลีกเลี่ยงชื่อไฟล์ที่จำเป็นต้องมีการอ้างถึง (เช่นที่มีที่ว่างอยู่ในนั้น) :-)
แมตต์วาลลิส

254

git archive ยังทำงานกับที่เก็บระยะไกล

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

ในการส่งออกพา ธ เฉพาะภายใน repo ให้เพิ่มพา ธ มากเท่าที่คุณต้องการเป็นอาร์กิวเมนต์สุดท้ายในคอมไพล์เช่น:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

6
อันนี้เป็นตัวเลือกที่ฉันชอบที่สุด มันมีประโยชน์เพิ่มเติมที่ใช้กับที่เก็บเปลือย
innaM

5
กำลังปรับปรุงรุ่นคือ: git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf - (มั่นใจได้ว่าไฟล์เก็บถาวรของคุณอยู่ในโฟลเดอร์)
Nick

7
หมายเหตุ : เซิร์ฟเวอร์จะต้องเปิดใช้งานคุณสมบัตินี้
Jakub Narębski

12
ฉันลองแล้ว: git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git masterถึงขั้นร้ายแรง: โปรโตคอลไม่รองรับการทำงาน ไม่คาดหวังจุดสิ้นสุดคำสั่งสตรีม
andyf

7
@andyf GitHub มีวิธีของตนเอง: curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -ต่อเอกสาร
บิชอป

62

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบกรณีพิเศษหากที่เก็บโฮสต์บน GitHub

svn exportใช้เพียงแค่

เท่าที่ผมรู้ Github archive --remoteไม่อนุญาตให้ แม้ว่า GitHub นั้นใช้งานได้กับ svnและพวกเขามี git repos ทั้งหมดที่svnสามารถเข้าถึงได้ดังนั้นคุณสามารถใช้svn exportเหมือนปกติโดยมีการปรับเปลี่ยนเล็กน้อยใน URL GitHub ของคุณ

ตัวอย่างเช่นในการส่งออกพื้นที่เก็บข้อมูลทั้งหมดให้สังเกตว่าtrunkในการแทนที่ URL master(หรือสาขา HEAD ของโครงการถูกตั้งค่าเป็น ):

svn export https://github.com/username/repo-name/trunk/

และคุณสามารถส่งออกไฟล์เดียวหรือแม้กระทั่งพา ธ หรือโฟลเดอร์ที่แน่นอน:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

ตัวอย่างกับjQuery JavaScript Library

HEADสาขาหรือปริญญาโทสาขาจะสามารถใช้ได้โดยใช้trunk:

svn ls https://github.com/jquery/jquery/trunk

HEAD สาขาที่ไม่ใช่สาขาจะสามารถเข้าถึงได้ภายใต้/branches/:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

แท็กทั้งหมดอยู่/tags/ในลักษณะเดียวกัน:

svn ls https://github.com/jquery/jquery/tags/2.1.3

1
git archiveทำงานได้ดีกับ GitHub ตราบใดที่คุณใช้โปรโตคอล git เพียงแทนที่https://ด้วยgit://ใน URL ฉันไม่รู้ว่าทำไม GitHub ไม่โฆษณาคุณสมบัติที่ซ่อนอยู่นี้
Neil Mayhew

1
@NeilMayhew fatal: The remote end hung up unexpectedlyมันไม่ทำงานสำหรับฉันฉันได้รับ ลองใช้สองเซิร์ฟเวอร์ที่แตกต่างกันด้วย jQuery github repo
Anthony Hatzopoulos

คุณถูก. ฉันลืมว่าฉันกำลังใช้git config url.<base>.insteadOfเพื่อแคชพื้นที่เก็บข้อมูลระยะไกล ดังนั้นฉันจึงใช้file://URL ในความเป็นจริง ฉันสงสัยว่าgit archiveจะสามารถทำงานกับgit://URL ได้เนื่องจากจะต้องสามารถทำงานได้git-upload-archiveที่รีโมตปลายทาง มันควรจะเป็นไปได้โดยใช้sshโปรโตคอลยกเว้นว่า github ไม่อนุญาต ( Invalid command: 'git-upload-archive')
Neil Mayhew

มีวิธีใดที่จะใช้เครื่องมือเซิร์ฟเวอร์ภายในที่ทำงานเหมือน github หากฉันต้องการทำกับที่เก็บ git ที่โฮสต์ภายใน?
kriss

1
upvoted - เป็นเรื่องที่แปลกประหลาดอย่างยิ่งที่ Git ไม่มีคุณสมบัตินี้และเราต้องใช้ svn
Jason S

40

จากคู่มือ Git :

ใช้ git-checkout-index เพื่อ "ส่งออกต้นไม้ทั้งหมด"

ความสามารถของคำนำหน้านั้นทำให้การใช้ดัชนี git-checkout-index เป็นฟังก์ชั่น "ส่งออกเป็นต้นไม้" ได้ง่าย เพียงอ่านต้นไม้ที่ต้องการลงในดัชนีและทำ:

$ git checkout-index --prefix=git-export-dir/ -a


19
ฉันคิดว่าความสับสนเป็นวลี "อ่านต้นไม้ที่ต้องการลงในดัชนี"
davetron5000

4
หากคุณต้องการที่จะส่งออก foo ไดเรกทอรีในแถบสาขาแล้วนี้จะเป็นgit read-tree bar:fooและแล้วgit checkout-index --prefix=export_dir/ -aหลังจากนั้นบางทีคุณควรจะทำอย่างไรgit update-index master
ปาสกาลขัดสน

1
@JohnWeldon คุณต้องการโคลน repo ก่อนหรือไม่? ถ้าเป็นเช่นนั้นฉันจะไม่ยอมรับมันเนื่องจากจุดรวมของ "การส่งออก svn" ของไดเรกทอรีย่อยคือการรับสำเนาของไดเรกทอรีย่อยนั้นโดยตรง ถ้าใครมี repo Git 1GB และทั้งหมดที่ฉันต้องการคือไดเรกทอรีย่อย 10kB มันก็บ้าที่จะต้องให้ฉันลอกแบบทั้งหมด
Jason S

3
นอกจากนี้ฉันต้องการ echo @ davetron5000 พร้อมความคิดเห็น "อ่านต้นไม้ที่ต้องการในดัชนี" ซึ่งฉันไม่รู้ว่ามันแปลว่าอะไร
Jason S

38

ฉันเขียน wrapper ง่าย ๆgit-checkout-indexที่คุณสามารถใช้สิ่งนี้:

git export ~/the/destination/dir

หากไดเรกทอรีปลายทางอยู่แล้วคุณจะต้องเพิ่มหรือ-f--force

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

ที่เก็บ github สำหรับ git-export


15
เสื้อคลุมนี้ไม่ได้เป็นผู้ไม่เชื่อเรื่องพระเจ้าแพลตฟอร์ม; มันอาศัย / bin / sh ดังนั้นหากคุณใช้ Windows วิธีนี้อาจไม่เหมาะกับคุณ
shovavnik

18
อืม, สคริปต์นี้มี 57 บรรทัดของเอกสาร, ช่องว่าง, การตั้งค่า, การแยกอาร์กิวเมนต์และมีเพียงหนึ่งบรรทัดซึ่งจริง ๆ แล้วทำอะไรบางอย่าง ...
Vladimir Panteleev

36

ดูเหมือนว่านี่เป็นปัญหาของ Git น้อยกว่า SVN Git ใส่เฉพาะโฟลเดอร์. git ในรูทเก็บข้อมูลในขณะที่ SVN ใส่โฟลเดอร์. svn ไว้ในทุกไดเรกทอรีย่อย ดังนั้น "การส่งออก svn" หลีกเลี่ยงเวทมนตร์บรรทัดคำสั่งซ้ำในขณะที่การเรียกซ้ำ Git ไม่จำเป็น


26
ในฐานะของ SVN 1.7 มีโฟลเดอร์. svn เพียงโฟลเดอร์เดียวเท่านั้นคือsubversion.apache.org/docs/release-notes/1.7.html#single-db
kostmo

สิ่งนี้จะไม่กำจัดไฟล์บิลด์เพิ่มเติมใด ๆ ที่ลบการส่งออก svn ดังนั้นนี่ไม่ใช่คำตอบที่แน่นอน
ygoe

28

มีค่าเท่ากับ

svn export . otherpath

ภายใน repo ที่มีอยู่คือ

git archive branchname | (cd otherpath; tar x)

มีค่าเท่ากับ

svn export url otherpath

คือ

git archive --remote=url branchname | (cd otherpath; tar x)

1
ขอบคุณนี่คือสิ่งที่ฉันหายไป ... นอกจากนี้เพื่อตรวจสอบการประทับเวลาของการส่งออก (พวกเขาจะไม่ถูกเก็บไว้ในไฟล์) ให้ใช้git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)... อย่างไรก็ตามการเก็บถาวรด้วยการประทับเวลานั้นไม่สำคัญเลยตัวอย่างด้านล่าง
sdaau

1
คุณสามารถใช้ตัวเลือก C สำหรับ tar แทน subshell เช่นนี้: git archive branchname | tar xC otherpath
James Moore

หัวขึ้นว่าCตัวเลือกในการ tar เป็น GNU Tar เท่านั้น
aredridel

22

หากคุณไม่ได้ยกเว้นไฟล์ด้วย.gitattributes export-ignoreลองgit checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f
เมื่อตรวจสอบเส้นทางจากดัชนีอย่าล้มเหลวในรายการที่ยังไม่ได้รวม แต่จะไม่สนใจรายการที่ไม่ได้รวม

และ

-q
หลีกเลี่ยง verbose

นอกจากนี้คุณยังจะได้รับสาขาหรือแท็กใด ๆ หรือจากที่เฉพาะเจาะจง Commit Revision เหมือนใน SVN เพียงการเพิ่มการ SHA1 (SHA1 ใน Git เป็นเทียบเท่ากับจำนวนการแก้ไขใน SVN)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

/path/to/checkout/ต้องว่างเปล่า Git จะไม่ลบไฟล์ใด ๆ แต่จะเขียนทับไฟล์ที่มีชื่อเดียวกันโดยไม่มีการเตือนใด ๆ

UPDATE: เพื่อหลีกเลี่ยงปัญหาที่เกิดจากหัวหรือปล่อยให้พื้นที่เก็บข้อมูลที่ใช้งานไม่ได้เมื่อใช้การชำระเงินเพื่อส่งออกด้วยแท็กสาขาหรือ SHA1 คุณต้องเพิ่ม-- ./ที่ส่วนท้าย

รีบคู่--บอกคอมไพล์ว่าทุกอย่างหลังจากที่ขีดกลางเส้นทางหรือไฟล์และยังอยู่ในกรณีนี้บอกgit checkoutจะไม่เปลี่ยนHEAD

ตัวอย่าง:

คำสั่งนี้จะได้รับเพียงไดเรกทอรี libs และยังreadme.txtไฟล์ที่ว่ากระทำ

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

นี้จะสร้าง (ทับ) my_file_2_behind_HEAD.txtสองกระทำด้านหลังศีรษะHEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

เพื่อรับการส่งออกของสาขาอื่น

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

โปรดสังเกตว่า./สัมพันธ์กับรูทของที่เก็บ


ที่จริงแล้วในบรรดาคนอื่น ๆ และ upvotes นี้มันใช้งานได้ดีที่สุดสำหรับฉันโดยไม่มีการบีบอัดใด ๆ ทำงานได้ดีกับที่เก็บเปลือย (gitolite)
takeshin

1
โปรดสังเกตว่าการชำระเงิน SHA1 จะสร้างปัญหา "
behead

actualy @ITGabs นี่ไม่ได้ดาวน์โหลดโฟลเดอร์ ".git" ดังนั้นโฟลเดอร์ที่ดาวน์โหลดไม่ได้เป็นที่เก็บคอมไพล์ดังนั้นมันจึงไม่ใช่ "beheaded" ในทางเทคนิค
Fabio Marreco

@FabioMarreco ปัญหา behead อยู่ในที่เก็บไม่ได้อยู่ในไฟล์ที่ส่งออก / ดาวน์โหลดฉันกำลังอัปเดตคำตอบสำหรับรายละเอียดเพิ่มเติม
user5286776117878

3
มันใช้งานได้ดีสำหรับฉัน แต่ตอนแรกฉันได้รับข้อความข้อผิดพลาด "ไม่ใช่ที่เก็บคอมไพล์" จากนั้นฉันพบว่า "/ path / to / repo /" ต้องชี้ไปที่โฟลเดอร์. git ดังนั้นสิ่งนี้จึงใช้ได้: --git-dir = / path / to / repo /
.git

21

ฉันใช้ git-submodules อย่างกว้างขวาง อันนี้ใช้ได้สำหรับฉัน:

rsync -a ./FROM/ ./TO --exclude='.*'

1
จะไม่ว่าไฟล์พลาดมีชื่อขึ้นต้นด้วยจุดเช่น.htaccess?
Greg Hewgill

8
ทางออกที่ดีฉันจะเปลี่ยน --exclude = '. *' เป็น --exclude = '. git *'
schmunk

18
- ไม่รวม vcs หากคุณจะใช้กลยุทธ์นี้
ล็อต

./FROM/ เป็น repo ระยะไกลได้หรือไม่
ต่อต้านการออกแบบ

2
ในฐานะที่เป็น FYI, สำเนาของฉันรายการอาร์กิวเมนต์เป็นrsync --cvs-excludeนอกจากนี้ยังมีการคัดลอก.gitattributesและ.gitignore
Ryan Ransford

19

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

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

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

เมื่อมีการสร้างการปล่อยแน่ใจว่ามันจะเป็นประโยชน์ในการโคลนสาขาที่มีเสถียรภาพเป็นเช่นหรือ--branch stable--branch release/0.9


สิ่งนี้ไม่ทำงานหากปลายทางมีอยู่และไม่ว่างเปล่า
บาร์นี้

2
The One True Answer: มันเกิดขึ้นจากส่วนลึก git archive | tarวิธีการคือใช้ไม่ได้กับสภาพแวดล้อมเปลือก POSIX-เข้ากันไม่ได้ (เช่น AppVeyor ของ CMD- หรือ PowerShell ตาม CI) ซึ่งเป็นที่ไม่เหมาะ git checkoutวิธีการปรับเปลี่ยนดัชนีของต้นไม้การทำงานหลักซึ่งเป็นที่น่ากลัว git checkout-indexวิธีการต้องใช้ดัชนีของต้นไม้การทำงานหลักที่จะได้รับการแก้ไขก่อนที่จะยิ่งน่ากลัวเอ้อ แบบดั้งเดิมgit cloneวิธีการโคลนครบถ้วนของประวัติศาสตร์ที่เก็บของก่อนที่จะลบประวัติศาสตร์ที่ซึ่งเป็นที่สิ้นเปลือง นี้เป็นเพียงการแก้ปัญหาทางด้านซ้ายมีสติ
เซซิลแกงกะหรี่

1
ในการส่งออกในพื้นที่โปรดทราบว่าเส้นทางที่แน่นอนของแผนผังการทำงาน Git ที่จะทำการโคลนนิ่งควรถูกนำหน้าด้วยfile://โปรโตคอล (เช่นgit clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo) ความล้มเหลวในการทำเช่นนั้นจะปล่อย"warning: --depth is ignored in local clones; use file:// instead."และทำมาตรฐานมากกว่าการโคลนนิ่งแบบตื้น ๆ เพื่อเอาชนะจุดประสงค์ทั้งหมดของคำตอบนี้ Salud!
เซซิลแกงกะหรี่

16

สิ่งนี้จะคัดลอกเนื้อหาทั้งหมดลบไฟล์. dot ฉันใช้สิ่งนี้เพื่อส่งออกโครงการโคลนคอมไพล์ไปยัง repo คอมไพล์ของเว็บแอปของฉันโดยไม่ต้องมีไฟล์. git

cp -R ./path-to-git-repo / path / to / destination /

ทุบตีเก่าธรรมดาใช้งานได้ดี :)


ทำไมไม่เพียงแค่ผลักไปที่ระยะไกล? ง่ายกว่าทุบตี
nurettin

2
ไฟล์ที่เป็นส่วนหนึ่งของเว็บแอปพลิเคชั่นและชื่อขึ้นต้นด้วย dot :) คิดเกี่ยวกับ. htaccess
Artur

3
บางครั้งคุณต้องการที่จะเพิกเฉยต่อสิ่งที่อยู่.gitignoreภายใน
fregante

14

ง่ายๆเหมือนโคลนจากนั้นลบโฟลเดอร์. git:

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git


4
สุจริต - คำตอบนี้ซึ่งเป็น # 1 ในคำถาม - คือสิ่งที่คุณกำลังจะทำ 99% ของเวลา คำตอบเหล่านี้ส่วนใหญ่บ้าเกินไปที่ซับซ้อน
Geoff Nixon

11

สำหรับผู้ใช้ GitHub ที่git archive --remoteวิธีการที่จะไม่ทำงานโดยตรงเช่นURL ที่ส่งออกชั่วคราว คุณต้องถาม GitHub สำหรับ URL ที่แล้วดาวน์โหลด URL นั้น curlทำให้ง่าย:

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

นี้จะให้รหัสที่ส่งออกในไดเรกทอรีท้องถิ่น ตัวอย่าง:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

แก้ไข
หากคุณต้องการให้ใส่รหัสลงในไดเรกทอรีที่มีอยู่เฉพาะ(แทนที่จะเป็นแบบสุ่มจาก github):

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1

11

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

git archive --format zip --output /full/path/to/zipfile.zip master 

นี่เป็นสิ่งที่ดีเพียงแค่ต้องลบ gitignore หลังจากนั้นมันก็เสร็จสิ้นและพร้อมที่จะแบ่งปัน
Sogger

การลบ. gitgnore และอื่น ๆ ถูกกล่าวถึงในคำตอบที่ยอมรับความคิดเห็น: ใช้ไฟล์. gitattributes
Sogger

10

ฉันแค่ต้องการชี้ให้เห็นว่าในกรณีที่คุณเป็น

  1. การส่งออกโฟลเดอร์ย่อยของที่เก็บ (นั่นคือวิธีที่ฉันใช้ในการใช้คุณสมบัติการส่งออก SVN)
  2. ตกลงที่มีการคัดลอกทุกอย่างจากโฟลเดอร์นั้นไปยังปลายทางที่ใช้งาน
  3. และเนื่องจากคุณมีสำเนาของที่เก็บทั้งหมดแล้ว

จากนั้นคุณก็สามารถใช้แทนการกล่าวถึงcp foo [destination]git-archive master foo | -x -C [destination]


9

คุณสามารถเก็บ repo ระยะไกลได้ที่การกระทำใด ๆ ที่เป็นไฟล์ zip

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT

8

การทุบตีการนำ git-export มาใช้

ฉันได้แบ่งกระบวนการสร้างและลบไฟล์. ที่ว่างในฟังก์ชั่นของตัวเองโดยมีจุดประสงค์เพื่อใช้งานซ้ำในการใช้งาน 'git-archive' (จะโพสต์ในภายหลัง)

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

EMPTY_FILE = "ว่าง";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

เอาท์พุท:

$ git-export /tmp/rel-1.0.0

กำลังเพิ่มไฟล์ '.empty' ลงในโฟลเดอร์ว่าง: ... เสร็จแล้ว

องค์ประกอบการตรวจสอบออกดัชนี: ... เสร็จแล้ว

รีเซ็ต HEAD และดัชนี: ... เสร็จแล้ว

ชำระล้างองค์ประกอบเฉพาะ Git: ...

'/tmp/rel-1.0.0/{.buildpath}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.project}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.gitignore}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.git}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.gitattributes}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{*.mno}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{*~}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.*~}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{*.swp}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{*.swo}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.DS_Store}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.settings}' ไฟล์ ... เสร็จแล้ว '

'/tmp/rel-1.0.0/{.empty}' ไฟล์ ... เสร็จแล้ว '

เสร็จแล้ว

การเก็บถาวรส่วนประกอบที่เช็คเอาต์: ... เสร็จแล้ว

-rw-r - r-- 1 ล้อผู้ดูแลระบบ 25445901 3 พ.ย. 12:57 /tmp/rel-1.0.0.tgz

ตอนนี้ฉันได้รวมฟังก์ชั่น 'เก็บถาวร git' ไว้ในกระบวนการเดียวที่ใช้ประโยชน์จากฟังก์ชั่น 'create_empty' และคุณสมบัติอื่น ๆ

function git-archive () {
    PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }

การใช้งาน: git-archive [/ var / www / htdocs] /repos/web.domain/website:rel-1.0.0
tocororo

8

หากคุณต้องการสิ่งที่ทำงานร่วมกับ submodules นี่อาจคุ้มค่ากับการไป

บันทึก:

  • MASTER_DIR = การชำระเงินด้วย submodules ของคุณที่เช็คเอาท์ด้วย
  • DEST_DIR = ตำแหน่งที่การส่งออกนี้จะจบลง
  • หากคุณมี rsync ฉันคิดว่าคุณสามารถทำสิ่งเดียวกันได้โดยมีอาการปวดบอลน้อยลง

สมมติฐาน:

  • คุณต้องเรียกใช้จากไดเรกทอรีหลักของ MASTER_DIR (เช่นจาก MASTER_DIR cd .. )
  • DEST_DIR จะถือว่าถูกสร้างขึ้น นี่เป็นเรื่องง่ายที่จะแก้ไขเพื่อรวมการสร้าง DEST_DIR หากคุณต้องการ

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude = '. git *' && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz


6

การตั้งค่าของฉันจริง ๆ แล้วจะต้องมีเป้าหมายdistใน Makefile ของคุณ (หรือระบบบิลด์อื่น ๆ ) ที่ส่งออกไฟล์เก็บถาวรที่แจกจ่ายได้ของโค้ดของคุณ (. tar.bz2, .zip, .jar หรืออะไรก็ตามที่เหมาะสม) หากคุณบังเอิญใช้ GNU autotools หรือระบบ MakeMaker ของ Perl ฉันคิดว่ามันมีให้คุณโดยอัตโนมัติ ถ้าไม่ฉันขอแนะนำให้เพิ่ม

ETA (2012-09-06): ว้าว downvotes รุนแรง ฉันยังเชื่อว่ามันเป็นการดีกว่าที่จะสร้างการกระจายของคุณด้วยเครื่องมือสร้างของคุณแทนที่จะเป็นเครื่องมือควบคุมซอร์สโค้ดของคุณ ฉันเชื่อในการสร้างสิ่งประดิษฐ์ด้วยเครื่องมือสร้าง ในงานปัจจุบันของฉันผลิตภัณฑ์หลักของเราสร้างขึ้นด้วยเป้าหมายมด เราอยู่ในท่ามกลางระบบควบคุมซอร์สโค้ดสวิตชิ่งและการปรากฏตัวของเป้าหมายมดนี้หมายถึงความยุ่งยากในการโยกย้ายน้อยลง


โครงการที่ฉันมีอยู่ในใจไม่ใช่โครงการรหัส มันเกิดขึ้นมากขึ้นตามแนวของโครงการเว็บไซต์
Greg Hewgill

ไม่ตอบคำถาม
Andrew Ferrier

1
ใช่คำตอบดังกล่าวอาจไม่ตรงกับความต้องการของทุกคน แต่ downvotes นั้นแปลกประหลาด มันเป็นคำตอบที่ถูกต้องทั้งหมดและในหลาย ๆ สถานการณ์คำตอบที่ถูกต้องเพียงข้อเดียว มันทำให้ประเด็นที่ถูกต้องมากที่คิดเกี่ยวกับปัญหานี้ในฐานะ "ปัญหาเครื่องมือ vc" มักจะลงเส้นทางที่ผิดอย่างสิ้นเชิง
snogglethorpe

6

นี่จะเป็นการคัดลอกไฟล์ในช่วงคอมมิท (C ถึง G) ไปยังไฟล์ tar หมายเหตุ: นี่จะได้รับไฟล์ที่ได้ตกลงไว้เท่านั้น ไม่ใช่ที่เก็บทั้งหมด แก้ไขเล็กน้อยจากที่นี่

ตัวอย่างประวัติความเป็นมา

A -> B -> C -> D -> E -> F -> G -> H -> I

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

หน้าคู่มือ git-diff-tree

-r -> recurse ในต้นไม้ย่อย

- no-commit-id -> git diff-tree เอาท์พุทบรรทัดที่มี commit ID เมื่อใช้ได้ การตั้งค่าสถานะนี้ระงับเอาท์พุทกระทำ ID

--name-only -> แสดงชื่อไฟล์ที่ถูกเปลี่ยนเท่านั้น

--diff-filter = ACMRT -> เลือกเฉพาะไฟล์เหล่านี้ ดูที่นี่สำหรับรายการไฟล์ทั้งหมด

C..G -> ไฟล์ในช่วงที่กำหนด

C ~ -> รวมไฟล์จาก Commit C ไม่ใช่เฉพาะไฟล์ตั้งแต่ Commit C

| xargs tar -rf myTarFile -> เอาต์พุตไปยัง tar


5

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

สามารถทำได้เช่นนี้

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch มีให้ตั้งแต่ Git 1.7.10 (เมษายน 2012)
  • --depthเป็น (คืออะไร) รายงานความผิดปกติ แต่สำหรับกรณีของการส่งออกประเด็นที่กล่าวถึงไม่ควรสำคัญ

หมายเหตุ: ฉันเพิ่งสังเกตเห็นว่ามีเบราว์เซอร์ 2 หน้าฉันดูเพียงหน้าเดียวก่อนโพสต์ มีหนึ่ง anwser ที่คล้ายกันที่มีเพียงอย่างเดียว--depthซึ่งหมายถึง--single-branchเว้นแต่--no-single-branchจะได้รับซึ่งหมายความว่าสิ่งนี้อาจมีผลเหมือนกัน ไม่แน่ใจว่าผู้เชี่ยวชาญบางคนอาจยืนยัน?
Ondra Žižka

4

ฉันต้องการสิ่งนี้สำหรับสคริปต์การปรับใช้และฉันไม่สามารถใช้วิธีการใด ๆ ที่กล่าวถึงข้างต้น ฉันหาวิธีแก้ปัญหาที่ต่างออกไปแทน:

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME

ปัญหาของ read-tree / checkout-index หรือ solution archive เป็นอย่างไร เท่าที่ฉันสามารถบอกได้ว่าคุณได้ทำสิ่งที่เทียบเท่าmkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"แต่ยืดเยื้อ
CB Bailey

1
ฉันไม่สามารถอ่านทรีให้ทำงานจากที่เก็บระยะไกลได้และโซลูชันการเก็บถาวรไม่ทำงานกับ github
troelskn

ใช่ด้วยการเก็บถาวรได้รับคำสั่งไม่ถูกต้อง: 'ข้อผิดพลาด' git-upload-archive '... และฉันไม่มีตัวเลือก core.gitProxy config และชุดตัวแปรสภาพแวดล้อม
GIT_PROXY_COMMAND

4

ด้วยวิธีที่ง่ายนี่คือฟังก์ชั่นสำหรับ. bash_profile มันคลายซิปที่เก็บถาวรในตำแหน่งปัจจุบันโดยตรงกำหนดค่าก่อน [url: path] ตามปกติของคุณ หมายเหตุ: ด้วยฟังก์ชั่นนี้คุณจะหลีกเลี่ยงการทำงานของโคลนได้โดยตรงจาก repo ระยะไกล

gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "$1" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "$2" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH="$2"
    fi
    echo "Getting $1/$TREEISH..."
    git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}

นามแฝงสำหรับ. gitconfig ต้องการการกำหนดค่าแบบเดียวกัน (ใช้เวลาดูแลการดำเนินการคำสั่งภายในโครงการ. git มันมักจะกระโดดไปที่ฐาน dir ก่อนหน้านี้ตามที่กล่าวไว้ที่นี่จนกว่าจะได้รับการแก้ไขฉันเองชอบฟังก์ชั่น

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -

4

โดยวิธีที่ง่ายที่สุดที่ฉันเคยเห็น (และทำงานบน windows ด้วย) คือgit bundle:

git bundle create /some/bundle/path.bundle --all

ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม: ฉันจะคัดลอกที่เก็บ git ของฉันจากเครื่อง windows ไปยังเครื่อง linux ผ่านไดรฟ์ usb ได้อย่างไร


git bundleรวมถึง.gitโฟลเดอร์ซึ่งเป็นสิ่งที่ OP ไม่ต้องการ git archiveดูเหมือนวิธีที่เหมาะสมกว่า
ssc

เอกสารเกี่ยวกับ--allสวิตช์อยู่ที่ไหน
Garret Wilson

4

ฉันมีวิธีแก้ไขปัญหาอื่นที่ใช้งานได้ดีถ้าคุณมีสำเนาของที่เก็บในเครื่องที่คุณต้องการสร้างการส่งออก ในกรณีนี้ย้ายไปยังไดเรกทอรีที่เก็บนี้และป้อนคำสั่งนี้:

GIT_WORK_TREE=outputdirectory git checkout -f

สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณจัดการเว็บไซต์ด้วยที่เก็บ git และต้องการเช็คเอาท์เวอร์ชั่น/var/www/ใหม่ ในกรณีนี้เพิ่มคำสั่งนี้ใน.git/hooks/post-receiveสคริปต์ ( hooks/post-receiveบนพื้นที่เก็บข้อมูลเปล่าซึ่งเหมาะสมกว่าในสถานการณ์นี้)


3

ฉันคิดว่าโพสต์ของ@Aredridelอยู่ใกล้ที่สุด แต่ก็มีอะไรเพิ่มเติมอีกหน่อย - ดังนั้นฉันจะเพิ่มที่นี่ สิ่งนั้นคือsvnถ้าคุณอยู่ในโฟลเดอร์ย่อยของ repo และคุณ:

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

จากนั้นsvnจะส่งออกไฟล์ทั้งหมดที่อยู่ภายใต้การควบคุมการแก้ไข (พวกเขาอาจเพิ่มสดใหม่หรือแก้ไขสถานะ) - และถ้าคุณมี "ขยะ" อื่น ๆ ในไดเรกทอรีนั้น (และฉันไม่นับ.svnโฟลเดอร์ย่อยที่นี่ แต่สิ่งที่มองเห็นได้เช่น.oไฟล์) มันจะไม่ถูกส่งออก; เฉพาะไฟล์ที่ลงทะเบียนโดย repo SVN เท่านั้นที่จะถูกส่งออก สำหรับฉันสิ่งหนึ่งที่ดีคือการส่งออกนี้มีไฟล์ที่มีการเปลี่ยนแปลงในเครื่องซึ่งยังไม่ได้ทำ และสิ่งที่ดีอีกอย่างก็คือการประทับเวลาของไฟล์ที่ส่งออกนั้นเหมือนกับของดั้งเดิม หรือตามที่svn help exportวางไว้:

  1. เอ็กซ์พอร์ตแผนผังไดเร็กทอรีแบบคลีนจากสำเนาการทำงานที่ระบุโดย PATH1, ที่ revision REV หากกำหนดไว้, ไม่เช่นนั้นที่ WORKING, ไปที่ PATH2. ... หากไม่ได้ระบุ REV การเปลี่ยนแปลงในระบบทั้งหมดจะถูกเก็บไว้ ไฟล์ที่ไม่อยู่ภายใต้การควบคุมเวอร์ชันจะไม่ถูกคัดลอก

หากต้องการทราบว่าgitจะไม่เก็บบันทึกเวลาให้เปรียบเทียบผลลัพธ์ของคำสั่งเหล่านี้ (ในโฟลเดอร์ย่อยของgitrepo ที่คุณเลือก):

/media/disk/git_svn/subdir$ ls -la .

... และ:

/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)

... และฉันไม่ว่าในกรณีใดก็ตามให้สังเกตว่าgit archiveการประทับเวลาทั้งหมดของไฟล์ที่เก็บถาวรจะเหมือนกัน! git help archiveพูดว่า:

เก็บถาวร git ทำงานแตกต่างกันเมื่อได้รับรหัสต้นไม้เมื่อเทียบกับเมื่อได้รับการกระทำ ID หรือแท็ก ID ในกรณีแรกเวลาปัจจุบันถูกใช้เป็นเวลาการแก้ไขของแต่ละไฟล์ในไฟล์เก็บถาวร ในกรณีหลังนี้ใช้เวลาการส่งมอบตามที่บันทึกไว้ในการส่งมอบวัตถุอ้างอิงแทน

... แต่เห็นได้ชัดว่าทั้งสองกรณีตั้งค่า "เวลาแก้ไขของแต่ละไฟล์"; จึงไม่ได้เก็บรักษาบันทึกเวลาที่เกิดขึ้นจริงของไฟล์เหล่านั้น!

ดังนั้นเพื่อรักษาเวลาประทับต่อไปนี้เป็นbashสคริปต์ซึ่งจริงๆแล้วเป็น "หนึ่งซับ" แม้ว่าจะค่อนข้างซับซ้อน - ดังนั้นด้านล่างจะโพสต์ในหลายบรรทัด:

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

โปรดทราบว่ามีการสันนิษฐานว่าคุณกำลังส่งออกเนื้อหาในไดเรกทอรี "ปัจจุบัน" (ด้านบน/media/disk/git_svn/subdir) - และปลายทางที่คุณส่งออกไปนั้นค่อนข้างไม่สะดวก แต่อยู่ในDESTตัวแปรสภาพแวดล้อม โปรดทราบว่าด้วยสคริปต์นี้ คุณต้องสร้างDESTไดเรกทอรีด้วยตนเองก่อนที่จะเรียกใช้สคริปต์ข้างต้น

หลังจากรันสคริปต์แล้วคุณควรจะสามารถเปรียบเทียบ:

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

... และหวังว่าจะเห็นการประทับเวลาเดียวกัน (สำหรับไฟล์ที่อยู่ภายใต้การควบคุมเวอร์ชัน)

หวังว่านี่จะช่วยใครซักคน
ไชโย!


3

git ส่งออกไปยังไฟล์ zip ในขณะที่เพิ่มคำนำหน้า (เช่นชื่อไดเรกทอรี):

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip

2

หากคุณต้องการ submodules เช่นนี้ควรทำเคล็ดลับ: https://github.com/meitar/git-archive-all.sh/wiki


ที่จริงแล้วดูเหมือนว่าจะมีปัญหาเล็ก ๆ น้อย ๆ ดังนั้นจึงอาจยังไม่พร้อมสำหรับช่วงเวลาสำคัญ
แบรนดอน

1

ฉันมีฟังก์ชั่นยูทิลิตี้ต่อไปนี้ในไฟล์. bashrc ของฉัน: มันสร้างการเก็บถาวรของสาขาปัจจุบันในที่เก็บ git

function garchive()
{
  if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
    cat <<EOF
Usage: garchive <archive-name>
create zip archive of the current branch into <archive-name>
EOF
  else
    local oname=$1
    set -x
    local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
    git archive --format zip --output ${oname} ${bname}
    set +x
  fi
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.