ฉันจะเพิ่ม 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.