ฉันจะเพิ่ม submodule ในไดเรกทอรีย่อยได้อย่างไร


310

ฉันมี repo คอมไพล์~/.janus/กับพวงของ submodules ในนั้น ฉันต้องการเพิ่ม submodule ใน~/.janus/snipmate-snippets/snippets/แต่เมื่อฉันทำงานgit submodule add <git@github.com:...>ในsnipmate-snippetsไดเรกทอรีฉันได้รับข้อความแสดงข้อผิดพลาดต่อไปนี้:

You need to run this command from the toplevel of the working tree.

ดังนั้นคำถามคือฉันจะเพิ่ม submodule ในsnipmate-snippetsไดเรกทอรีได้อย่างไร


ไปที่ไดเรกทอรีรากของ repo git สำหรับคำสั่ง submodule จะไม่เป็นข้อกำหนดอีกต่อไป (เร็ว ๆ นี้) ดูคำตอบของฉันด้านล่าง
— VonC

3
git submodule add -b <branch> <url> <relative_path_4m_root>
— parasrish

คำตอบ:


438

คุณเข้าสู่~/.janusและทำงาน:

git submodule add <git@github ...> snipmate-snippets/snippets/

หากคุณต้องการข้อมูลเพิ่มเติมเกี่ยวกับ submodules (หรือ git โดยทั่วไป) ProGitค่อนข้างมีประโยชน์


ดูเหมือนว่าเป็นความคิดที่ดีที่จะเพิ่มสาขาเมื่อเพิ่มมิฉะนั้น HEAD ก็จะถูกถอดออกง่าย: git submodule เพิ่ม -b <branch> <repository> [<submodule-path>]
— deann

1
สำหรับฉันนี้เป็นสาเหตุของ(ผมใช้เป็นโครงการย่อยชื่อไดเรกทอรี)'subprojects' already exists in the index สิ่งที่ช่วยได้คือคำตอบของ VonC ด้านล่างคือทำcd subprojectsแล้วgit submodule add <get@github …>ไม่มีทาง
— Hi-Angel

83

โปรดทราบว่าการเริ่มต้นgit1.8.4 (กรกฎาคม 2013) คุณไม่จำเป็นต้องกลับไปที่ไดเรกทอรีรากอีกต่อไป

 cd ~/.janus/snipmate-snippets
 git submodule add <git@github ...> snippets

( Bouke Versteegh แสดงความคิดเห็นว่าคุณไม่จำเป็นต้องใช้/.เหมือนในsnippets/.: snippetsก็เพียงพอแล้ว)

ดูการยอมรับ 091a6eb0feed820a43663ca63dc2bc0bb247bbae :

submodule: วางข้อกำหนดระดับบนสุด

ใช้rev-parse --prefixอ็อพชันใหม่เพื่อประมวลผลพา ธ ทั้งหมดที่กำหนดให้กับคำสั่ง submodule โดยปล่อยข้อกำหนดที่ต้องรันจากระดับบนสุดของที่เก็บ

เนื่องจากการตีความของ URL submodule สัมพัทธ์ขึ้นอยู่กับว่าremote.origin.urlมีการกำหนดค่าหรือไม่ " " ให้ปิดกั้น URL สัมพัทธ์ใน " git submodule add" เมื่อไม่อยู่ที่ระดับบนสุดของแผนผังการทำงาน

ลงชื่อออกโดย: John Keeping

ขึ้นอยู่กับการยอมรับ 12b9d32790b40bf3ea49134095619700191abf1f

นี้ทำให้ ' git rev-parse' ประพฤติตัวเป็นถ้ามันถูกเรียกจากไดเรกทอรีย่อยที่กำหนดพื้นที่เก็บข้อมูลที่มีความแตกต่างที่เส้นทางไฟล์ใด ๆ ที่พิมพ์จะมีคำนำหน้าเส้นทางแบบเต็มจากด้านบนของต้นทำงาน

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


ขอบคุณมาก! ฉันสังเกตเห็นว่าการลาก/.ไม่จำเป็น git จะสร้างส่วนย่อยของไดเรกทอรีโดยไม่ใช้มัน
— Bouke Versteegh

@BoukeVersteegh ที่น่าสนใจ ฉันได้รวมความคิดเห็นของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น
— VonC

ฉันใช้งานคอมไพล์รุ่น 2.7.4 แต่ฉันก็ยังได้รับข้อความแสดงข้อผิดพลาดนี้Relative path can only be used from the toplevel of the working treeอยู่ ฉันกำลังทำgit submodule add ../../../functest
— FlyingAura

@ user3426358 ใช่เป็นไปตามที่คาดไว้: คำตอบข้างต้นระบบปฏิบัติการเกี่ยวกับความสามารถในการทำ git submoduel เพิ่มจากโฟลเดอร์ย่อยของ repo หลักใด ๆ ไม่ใช่แค่จากโฟลเดอร์รูท มันไม่เกี่ยวกับการอ้างอิง repo ระยะไกล repo กับเส้นทางสัมพัทธ์ หากคุณคุณจะได้รับข้อความแสดงข้อผิดพลาดที่คุณเห็น
— VonC

@ user3426358 และโดยวิธีข้อความข้อผิดพลาดที่ (ที่คุณเห็น: " Relative path can only be used from the toplevel of the working tree") ไม่ใช่หนึ่งในคำถามเดิม (" You need to run this command from the toplevel of the working tree")
— VonC

17

ฉันมีปัญหาที่คล้ายกัน แต่ทาสีตัวเองให้เป็นมุมด้วยเครื่องมือ GUI

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

เมื่อต้องการออกจากความยุ่งเหยิงนี้ฉันต้องบอก Git ให้หยุดติดตามโฟลเดอร์ย่อย (โดยไม่ลบไฟล์):

proj> git rm -r --cached ./ui/jslib

จากนั้นฉันต้องบอกว่ามี submodule ที่นั่น (ซึ่งคุณไม่สามารถทำได้ถ้ามีอะไรที่กำลังถูกติดตามโดย git):

proj> git submodule add ./ui/jslib

ปรับปรุง

วิธีที่เหมาะในการจัดการเรื่องนี้เกี่ยวข้องกับอีกไม่กี่ขั้นตอน เป็นการดีที่ repo ที่มีอยู่จะถูกย้ายออกไปยังไดเรกทอรีของตัวเองโดยไม่ต้องมีโมดูล git หลักใด ๆ ที่คอมมิตและถูกผลักดัน

proj> git submodule add git@bitbucket.org:user/jslib.git ui/jslib

ที่จะโคลน repo git เป็น submodule - ซึ่งเกี่ยวข้องกับขั้นตอนการโคลนมาตรฐาน แต่ยังมีอีกหลายขั้นตอนการกำหนดค่าปิดบังอื่น ๆ ที่ git ใช้ในนามของคุณเพื่อให้ได้ submodule ที่ทำงาน ความแตกต่างที่สำคัญที่สุดคือมันวางไฟล์. git แบบง่าย ๆ ไว้ที่นั่นแทนที่จะเป็นไดเร็กตอรี่. git ซึ่งมีการอ้างอิงพา ธ ไปยังตำแหน่งที่ git dir ตัวจริงอาศัยอยู่ - โดยทั่วไปอยู่ที่รูทโปรเจ็กต์หลัก

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

ดังนั้นย้ายกด git เพิ่ม submodule เป็นตัวเลือกที่สะอาดที่สุด


16

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

.git / config (การตั้งค่าส่วนตัว)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules (กำหนดค่าการแชร์แบบกำหนดไว้)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

ดูสิ่งนี้เช่นกัน - ความแตกต่างระหว่าง. gitmodules และการระบุ submodules ใน. git / config?


2

สคริปต์ทุบตีสายการบินเดียวที่จะช่วยให้คำตอบของคริสสะดวกขึ้นเพราะฉันได้ทาสีตัวเองในมุมหนึ่งเช่นกันโดยใช้การอัปเดต Vundle กับสคริปต์. vim ของฉัน DESTเป็นเส้นทางไปยังไดเรกทอรีที่มี submodules ของคุณ ทำเช่นนี้หลังจากทำgit rm -r $DEST

DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

ไชโย

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