ฉันจะทำงานกับที่เก็บ git ภายในที่เก็บอื่นได้อย่างไร


284

ฉันมีที่เก็บสื่อ Git ที่ฉันเก็บรักษาไฟล์ JavaScript และ CSS หลักทั้งหมดและสคริปต์ที่ฉันจะใช้ในโครงการต่างๆ

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


โปรดดูคำตอบทรีย่อย ด้านล่างจาก @ ruslan-kabalin หมายเหตุ: hooks ก่อนการกระทำ (หรือovercommit ) เป็นวิธีหนึ่งในการจัดการคัดค้านโดย Robert Dundon
Hedgehog

คำตอบ:


348

ที่สำคัญคือsubmodules คอมไพล์

เริ่มอ่านบท Submodules ของGit Community Bookหรือคู่มือผู้ใช้

สมมติว่าคุณมีที่เก็บ PROJECT1, PROJECT2 และ MEDIA ...

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

ทำซ้ำใน repo อื่น ๆ ...

ทีนี้สิ่งที่เจ๋งคือเมื่อใดก็ตามที่คุณทำการเปลี่ยนแปลงสื่อคุณสามารถทำสิ่งนี้ได้:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

นี่เพิ่งบันทึกความจริงที่ว่า submodule ของ MEDIA ภายใน PROJECT2 ตอนนี้เป็นเวอร์ชั่น XYZ

มันช่วยให้คุณควบคุมได้ 100% ว่า MEDIA เวอร์ชันใดที่แต่ละโครงการใช้ git submodulesนั้นยอดเยี่ยม แต่คุณต้องทำการทดลองและเรียนรู้เกี่ยวกับมัน

ด้วยพลังอันยิ่งใหญ่โอกาสที่ดีที่จะถูกกัดในตะโพก


เวิร์กโฟลว์นี้ทำให้ฉันนึกถึงการใช้โมดูล NPM ส่วนตัวstackoverflow.com/questions/7575627/…
cyrf

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

3
วิธีนี้จะทำงานร่วมกับ GitHub?
theonlygusti

27

พิจารณาใช้ทรีย่อยแทน submodules มันจะทำให้ผู้ใช้ repo ของคุณมีชีวิตที่ง่ายขึ้น คุณอาจจะพบคู่มือรายละเอียดเพิ่มเติมในหนังสือ Pro Git


6
นี่คือบทความข้อมูลอื่นเกี่ยวกับทรีย่อยและ submodule: blogs.atlassian.com/2013/05/..
Benny Neugebauer

3
จากบทความนั้นหนึ่งในข้อเสียคือ:> ความรับผิดชอบในการไม่ผสมโค้ดสุดยอดและรหัสโครงการย่อยที่เกี่ยวข้องกับคุณ ไม่มีใครมีเวลาสำหรับเรื่องนั้น (IMO)
Robert Dundon

20

หากฉันเข้าใจปัญหาของคุณเป็นอย่างดีคุณต้องการสิ่งต่อไปนี้:

  1. เก็บไฟล์สื่อของคุณไว้ในที่เก็บ git เดียวซึ่งถูกใช้โดยหลายโครงการ
  2. หากคุณแก้ไขไฟล์มีเดียในโปรเจ็กต์ใด ๆ ในเครื่องของคุณมันควรจะปรากฏขึ้นทันทีในทุกโปรเจ็กต์อื่น (ดังนั้นคุณไม่ต้องการคอมมิชชัน + push + pull ตลอดเวลา)

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

ก่อนอื่นคุณควรตัดสินใจเลือกสิ่งที่สำคัญ: คุณต้องการจัดเก็บสำหรับทุกรุ่นในที่เก็บโครงการของคุณเพื่ออ้างอิงถึงเวอร์ชันของไฟล์มีเดียหรือไม่? ตัวอย่างเช่นถ้าคุณมีโครงการที่ชื่อว่า example.com คุณจำเป็นต้องรู้หรือไม่ว่า style.css ที่ใช้เมื่อ 2 สัปดาห์ที่ผ่านมาหรือล่าสุดหรือที่ล่าสุดคือดีที่สุด

หากคุณไม่จำเป็นต้องรู้วิธีการแก้ปัญหานั้นง่าย:

  1. สร้างที่เก็บสำหรับไฟล์สื่อและหนึ่งไฟล์สำหรับแต่ละโครงการ
  2. สร้างลิงก์สัญลักษณ์ในโครงการของคุณซึ่งชี้ไปยังที่เก็บสื่อที่โคลนแบบโลคัล คุณสามารถสร้างลิงก์สัญลักษณ์สัมพัทธ์ (เช่น ../media) และสมมติว่าทุกคนจะชำระเงินโครงการเพื่อให้ไดเรกทอรีสื่ออยู่ในที่เดียวกันหรือเขียนชื่อของลิงก์สัญลักษณ์ลงใน. gitignore และทุกคนสามารถตัดสินใจได้ ตำแหน่งที่เขา / เธอวางไฟล์มีเดีย

อย่างไรก็ตามในกรณีส่วนใหญ่คุณต้องการทราบข้อมูลการกำหนดเวอร์ชันนี้ ในกรณีนี้คุณมีสองทางเลือก:

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

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

ถ้าฉันเป็นคุณฉันอาจจะเลือกวิธีที่หนึ่งหรือสาม (ลิงก์สัญลักษณ์หรือ submodules) หากคุณเลือกที่จะใช้ submodules คุณยังสามารถทำสิ่งต่าง ๆ มากมายเพื่อทำให้ชีวิตของคุณง่ายขึ้น:

  1. ก่อนที่จะกระทำคุณสามารถเปลี่ยนชื่อไดเรกทอรี submodule และวาง symlink ไว้ในไดเรกทอรีสื่อทั่วไป เมื่อคุณพร้อมที่จะส่งมอบคุณสามารถลบ symlink และลบ submodule กลับมาแล้วคอมมิท

  2. คุณสามารถเพิ่มหนึ่งในสำเนาของที่เก็บสื่อของคุณเป็นที่เก็บระยะไกลในโครงการทั้งหมดของคุณ

คุณสามารถเพิ่มโลคัลไดเร็กทอรีเป็นรีโมตด้วยวิธีนี้:

cd /my/project2/media
git remote add project1 /my/project1/media

หากคุณแก้ไขไฟล์ใน / my / project1 / media คุณสามารถคอมมิทและดึงไฟล์จาก / my / project2 / media โดยไม่ต้องพุชไปที่รีโมตเซิร์ฟเวอร์:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

คุณมีอิสระที่จะลบการกระทำเหล่านี้ในภายหลัง (ด้วยการรีเซ็ต git) เพราะคุณไม่ได้แชร์กับผู้ใช้รายอื่น


1
สำหรับโครงการที่เกี่ยวข้องกับเว็บที่คุณทำงานจากภายในwwwโฟลเดอร์ของ Apache คุณควรวาง.htaccessไฟล์ในรูทของทั้งwwwโฟลเดอร์หรือโครงการของคุณด้วยOptions +FollowSymLinksหรือดีกว่า<IfModule mod_rewrite.c>{new line}Options +FollowSymLinks{new line}RewriteEngine on{new line}</IfModule> (แทนที่{new line}ด้วยบรรทัดใหม่จริง `)

3

ฉันมีปัญหากับ subtrees และ submodules ที่คำตอบอื่น ๆ แนะนำ ... ส่วนใหญ่เป็นเพราะฉันใช้ SourceTree และดูเหมือนว่ารถค่อนข้าง

แต่ฉันลงเอยด้วยการใช้ SymLinks และดูเหมือนว่าจะทำงานได้ดีดังนั้นฉันจึงโพสต์ไว้ที่นี่เป็นทางเลือกที่เป็นไปได้

มีคำแนะนำที่สมบูรณ์ที่นี่: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

แต่โดยทั่วไปคุณเพียงแค่ต้อง mklink สองเส้นทางในพรอมต์คำสั่งที่ยกระดับ ตรวจสอบให้แน่ใจว่าคุณใช้คำนำหน้า / J hard link บางอย่างตามบรรทัดเหล่านี้: mklink / JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

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

ตัวอย่าง: mklink / J. \ Assets \ TaqtileTools .. \ TaqtileHoloTools

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

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

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