ฉันจะลบ submodule ได้อย่างไร


3539

ฉันจะลบ submodule Git ได้อย่างไร

มีเหตุผลอะไรที่ฉันทำ git submodule rm whateverไม่ได้เหรอ?


109
stackoverflow.com/a/21211232/94687คำตอบง่ายๆตอนนี้เป็นคำตอบที่ถูกต้องและควรทำเครื่องหมายเช่นนั้น ตอนนี้มันเป็นเพียง git rm modulenameและrm -rf .git/modules/modulename
Imz - อีวาน Zakharyaschev

10
ที่จริงไม่จริง คำตอบที่ไม่ได้อยู่ที่การเอารายการ submodule .git/configจาก คำตอบที่ยอมรับแสดงให้เห็นถึงวิธีการที่ทันสมัยเพื่อลบอย่างเต็มที่ submodule คำอธิบายนี้มีคำอธิบายเพิ่มเติมอย่างกระชับยิ่งขึ้น: stackoverflow.com/a/36593218/1562138
fvgs

ฉันพบบทความนี้มีประโยชน์มากในการลบ submodules ซึ่งจะรวมถึงข้อมูลเกี่ยวกับการลบรายการใน .gitsubmodules และ .git / config ไฟล์เชื่อมโยง
Ri_

12
โปรดช่วยตัวเองซักครู่และตอบคำตอบที่ได้ผลโดยตรง (ในปี 2560): stackoverflow.com/a/36593218/528313
Vincenzo Pii

ฉันปล้ำปัญหา submodule สองวัน การพัฒนามาเมื่อฉันพบนี้: forums.developer.apple.com/thread/13102 โดยทั่วไป Xcode และแอปอื่นอาจพยายามขยาย URL ที่มี '~' เมื่อฉันเปลี่ยน ssh: //username@server.remoteHost.com/~/git/MyRepo.git เป็น ssh: //username@server.remoteHost.com/home/username/git/MyRepo.git (ค้นหาเส้นทางที่แท้จริง บนเซิร์ฟเวอร์ของคุณ) ความแปลกประหลาดทั้งหมดหายไปสิบนาที ดูstackoverflow.com/questions/32833100/…
Elise van Looij

คำตอบ:


2213

ตั้งแต่git1.8.3 (วันที่ 22 เมษายน 2013) :

ไม่มีทางที่จะพูดว่า "ฉันไม่สนใจ submodule นี้อีกต่อไป" เมื่อคุณแสดงความสนใจใน submodule ด้วย " submodule init"
" submodule deinit" เป็นวิธีที่จะทำเช่นนั้น

กระบวนการลบใช้git rm(ตั้งแต่ git1.8.5 ตุลาคม 2013)

สรุป

กระบวนการลบ 3 ขั้นตอนจะเป็น:

0. mv a/submodule a/submodule_tmp

1. git submodule deinit -f -- a/submodule    
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)

# or, if you want to leave it in your working tree and have done step 0
3.   git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule

คำอธิบาย

rm -rf: สิ่งนี้ถูกกล่าวถึงในคำตอบของDaniel SchroederและสรุปโดยEonilในความคิดเห็น :

ใบนี้.git/modules/<path-to-submodule>/ไม่เปลี่ยนแปลง
ดังนั้นหากคุณลบ submodule ด้วยวิธีนี้และเพิ่มใหม่อีกครั้งมันจะเป็นไปไม่ได้เพราะพื้นที่เก็บข้อมูลเสียหาย


git rm: ดูความมุ่งมั่น 95c16418 :

ขณะนี้การใช้ " git rm" บนซับโดuleจะลบแผนผังการทำงานของซับไดuleออกจากซูเปอร์โปรเจ็กต์และ gitlink จากดัชนี
แต่ในส่วนของ submodule .gitmodulesนั้นไม่มีการแตะต้องซึ่งเป็นส่วนที่เหลือของ submodule ที่ถูกลบไปแล้วและอาจทำให้ผู้ใช้เกิดความรำคาญ (ตรงข้ามกับการตั้งค่าใน.git/configสิ่งนี้จะต้องเป็นตัวเตือนว่าผู้ใช้แสดงความสนใจใน submodule นี้ เมื่อการกระทำที่เก่ากว่าถูกทำเครื่องหมายไว้)

ให้ " git rm" ช่วยผู้ใช้โดยไม่เพียง แต่ลบการเปลี่ยนชื่อไฟล์ออกจากแผนผังงานเท่านั้น แต่ยังลบส่วน " submodule.<submodule name>" ออกจาก.gitmodulesไฟล์และลำดับขั้นด้วย


git submodule deinit: มันเกิดจากแพทช์นี้ :

ด้วยgit submodule initผู้ใช้จะสามารถบอกคอมไพล์ได้ว่าพวกเขาสนใจเกี่ยวกับ submodules อย่างน้อยหนึ่งรายการและต้องการให้มันมีประชากรในการโทรครั้งต่อไปที่ " git submodule update"
แต่ในปัจจุบันไม่มีวิธีง่ายๆที่พวกเขาสามารถบอกคอมไพล์พวกเขาไม่สนใจเกี่ยวกับ submodule อีกต่อไปและต้องการกำจัดแผนผังการทำงานในพื้นที่ (เว้นแต่ผู้ใช้รู้มากเกี่ยวกับ submodule internals และลบการsubmodule.$name.urlตั้งค่า "" ออกจาก.git/configกันพร้อมกับงาน ต้นไม้เอง)

ช่วยเหลือผู้ใช้เหล่านั้นด้วยการให้deinitคำสั่ง ''
สิ่งนี้จะลบsubmodule.<name>ส่วนทั้งหมดออกจาก.git/configทั้งสำหรับ submodule ที่ระบุ (หรือสำหรับทุกสิ่งที่ได้รับการกำหนดค่าเริ่มต้นหากได้รับ ' .')
ล้มเหลวหากแผนผังการทำงานปัจจุบันมีการแก้ไขยกเว้นถูกบังคับ
บ่นเมื่อสำหรับ submodule ที่ให้ไว้ในบรรทัดคำสั่งการตั้งค่า url ไม่สามารถพบได้.git/configแต่กระนั้นก็ไม่ได้ล้มเหลว

สิ่งนี้จะดูแลว่า (de) ขั้นตอนการเริ่มต้น ( .git/configและ.git/modules/xxx)

ตั้งแต่ git1.8.5 ที่git rmใช้เวลานอกจากนี้ยังดูแลของ:

  • ' add' ขั้นตอนที่บันทึก URL ของ submodule ใน.gitmodulesไฟล์: คุณจำเป็นต้องลบมันออก
  • รายการพิเศษ submodule (ตามภาพประกอบโดยคำถามนี้ ): git rm ลบออกจากดัชนี:
    git rm --cached path_to_submodule(ไม่มีเครื่องหมายทับ)
    ที่จะลบไดเรกทอรีนั้นที่เก็บอยู่ในดัชนีด้วยโหมดพิเศษ "160000" ทำเครื่องหมายว่าเป็นไดเรกทอรีราก submodule .

หากคุณลืมขั้นตอนสุดท้ายและลองเพิ่มสิ่งที่เป็น submodule เป็นไดเรกทอรีปกติคุณจะได้รับข้อความแสดงข้อผิดพลาดเช่น:

git add mysubmodule/file.txt 
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'

หมายเหตุ: ตั้งแต่ Git 2.17 (Q2 2018) git submodule deinit จะไม่เป็นเชลล์สคริปต์อีกต่อไป
เป็นการเรียกใช้ฟังก์ชัน C

ดูกระทำ 2e61273 , กระทำ 1342476 (14 มกราคม 2018) โดยPrathamesh Chavan (pratham-pc )
(ผสานโดยJunio ​​C Hamano - gitster- in ead8dbe , 13 Feb 2018)

git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
  ${GIT_QUIET:+--quiet} \
  ${prefix:+--prefix "$prefix"} \
  ${force:+--force} \
  ${deinit_all:+--all} "$@"

18
คุณสามารถยกตัวอย่างการใช้งานได้submodule deinitหรือไม่?
zakdances

5
@yourfriendzak นี่เป็นตัวอย่างหนึ่งของคนที่ประสบความสำเร็จในการใช้มัน: stackoverflow.com/a/16161950/6309 แต่โปรดจำไว้ว่าในทางตรงกันข้ามกับสิ่งที่ฉันเชื่อในตอนแรก 1.8.3 ยังไม่ออก! บน Unix คุณสามารถรวบรวมได้จากแหล่งต่าง ๆ
VonC

2
@HamishDowner รายการพิเศษควรจะหายไป (ไดเรกทอรีไม่ได้เป็น submodule อีกต่อไป) และ.gitmodulesควรจะเป็น ok แต่ฉันจะยังคงตรวจสอบสิ่งที่มี.gitไดเรกทอรี (เช่นการกำหนดค่าท้องถิ่นภายใน repo ท้องถิ่นของคุณ: นั่นไม่ใช่ แก้ไขโดยกgit pull)
VonC

2
@Jayen ใช่ถ้าคุณยอมรับการลบ.gitmodulesรายการและการลบรายการพิเศษในดัชนีและกด repo นั้นผู้อื่นสามารถดึงมันและ submodule นั้นจะหายไป
VonC

3
ในคอมไพล์ปัจจุบัน (v1.9 +) ผู้เฒ่าธรรมดาgit rm submoduleทำสิ่งที่คุณต้องการอย่างที่คนอื่น ๆ พูดไปแล้ว
Pete Peterson

3445

ผ่านหน้าหลักGit Submodule Tutorial :

ในการลบ submodule คุณต้อง:

  1. ลบส่วนที่เกี่ยวข้องออกจาก.gitmodulesไฟล์
  2. ระยะการ.gitmodulesเปลี่ยนแปลง:
    git add .gitmodules
  3. .git/configลบส่วนที่เกี่ยวข้องจาก
  4. ลบไฟล์ submodule ออกจากแผนผังการทำงานและดัชนี:
    git rm --cached path_to_submodule(ไม่มีเครื่องหมายทับ)
  5. ลบ.gitไดเรกทอรีของ submodule :
    rm -rf .git/modules/path_to_submodule
  6. ยอมรับการเปลี่ยนแปลง:
    git commit -m "Removed submodule <name>"
  7. ลบไฟล์ submodule ที่ไม่ได้ติดตามตอนนี้:
    rm -rf path_to_submodule

ดูเพิ่มเติม : ขั้นตอนทางเลือกด้านล่าง


410
"และโดยวิธีการที่มีเหตุผลที่ฉันไม่สามารถเพียงแค่ยอมจำนน submodule rm อะไร?" ?
abernier

48
@abernier คำตอบสั้น ๆ อาจเป็น "เพราะไม่มีคำสั่งดังกล่าวอยู่" ฉันเดาว่าพวกเขากำลังพยายามลบไฟล์ submodule และการกำหนดค่า submodule อย่างชัดเจนเพื่อหลีกเลี่ยงการสูญเสียข้อมูลโดยไม่ตั้งใจ บางทีคนคนหนึ่งอาจคิดว่าgit submodule rmเพียงแค่ลบการลงทะเบียน submodule และจะแปลกใจถ้าคำสั่งลบที่เก็บในเครื่องด้วย การเปลี่ยนแปลงในท้องถิ่นใด ๆ จะหายไปอย่างถาวร และบางทีบุคคลอื่นอาจคิดว่ามีเพียงไฟล์เท่านั้นที่จะถูกลบ
John Douthat

119
ตรงไปตรงมาฉันไม่รู้ว่าทำไม ฉันหวังว่าพวกเขาจะเพิ่มคำสั่ง 4 ขั้นตอนเหล่านี้ซับซ้อนเกินไป
John Douthat

25
นี่คือสคริปต์ทุบตีที่ลบ submodule เพียงสร้างนามแฝง git สำหรับ submodule-rm;) gist.github.com/2491147
Capi Etheriel

33
ยังต้องการ rm -rf .git \ modules \ ชื่อ submodule หรือไม่
rogerdpack

484

เพียงแค่ทราบ ตั้งแต่ git 1.8.5.2 คำสั่งสองคำสั่งจะทำ:

git rm the_submodule
rm -rf .git/modules/the_submodule

เนื่องจากคำตอบของ @Mark Cheverton ชี้ให้เห็นอย่างถูกต้องหากไม่ได้ใช้บรรทัดที่สองแม้ว่าคุณจะลบ submodule ออกไปในตอนนี้โฟลเดอร์. git / modules / the_submodule ที่เหลืออยู่จะป้องกันไม่ให้มีการเพิ่มหรือเปลี่ยนซับมิดในอนาคต . เช่นเดียวกับ @VonC ที่กล่าวถึงgit rmจะทำงานส่วนใหญ่ใน submodule

- อัปเดต (07/05/2017) -

เพียงเพื่อชี้แจงthe_submoduleเป็นเส้นทางสัมพัทธ์ของ submodule ภายในโครงการ ยกตัวอย่างเช่นมันเป็นsubdir/my_submoduleถ้า submodule subdirอยู่ภายในไดเรกทอรีย่อย

ตามที่ระบุไว้อย่างถูกต้องในความคิดเห็นและคำตอบอื่น ๆทั้งสองคำสั่ง (แม้ว่าจะมีฟังก์ชั่นเพียงพอที่จะลบซับไดโทล) ให้ทิ้งร่องรอยไว้ใน[submodule "the_submodule"]ส่วนของ.git/config(ณ เดือนกรกฎาคม 2017) ซึ่งสามารถลบออกได้โดยใช้คำสั่งที่สาม:

git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null

5
ฉันใช้ git เวอร์ชั่น 2.4.9 (Apple Git-60) และสิ่งที่ฉันต้องทำคือ rm the_submodule ฉันผลักที่แล้วเพิ่มโฟลเดอร์ชื่อเดียวกันกับ submodule อีกครั้งและทำงานโดยไม่มีปัญหา
David Silva Smith

19
นี้ไม่ได้ลบรายการ submodule .git/configจาก ดูstackoverflow.com/a/36593218/1562138สำหรับวิธีการที่สมบูรณ์ในการลบ submodule
fvgs

2
@drevicko ฉันเพิ่งทดสอบสิ่งนี้ด้วย Git 2.11.1 และฉันสังเกตเห็นพฤติกรรมเหมือนเดิม git init && git submodule add <repository> && git rm <name>ออกจาก.git/configรายการและ.git/modules/<name>ไดเรกทอรีและเนื้อหา คุณอาจไม่ได้เริ่มต้น submodule ก่อนที่จะลบหรือไม่
fvgs

2
ฉันรู้สึกปลอดภัยมากขึ้นในการใช้งานครั้งแรก .. git submodule deinit -f the_submodule
danday74

1
@ JarrodSmith ใช่มันเป็นเส้นทาง โปรดดูการปรับปรุง
tinlyx

478

คำตอบส่วนใหญ่สำหรับคำถามนี้ล้าสมัยไม่สมบูรณ์หรือซับซ้อนเกินความจำเป็น

submodule ที่ถูกโคลนโดยใช้ git 1.7.8 หรือใหม่กว่านั้นจะทิ้งร่องรอยของตัวเองไว้ไม่เกินสี่ตัวใน repo ท้องถิ่นของคุณ กระบวนการสำหรับการลบการติดตามทั้งสี่นั้นได้รับคำสั่งจากสามคำสั่งด้านล่าง:

# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule

39
ทำไมคำตอบนี้มี upvotes น้อยมาก? คำตอบยอดนิยมทั้งหมดที่พลาดบางสิ่งนี่เป็นเพียงคำเดียวที่จะลบร่องรอยทั้งหมดของ submodule ในวิธีที่ง่ายที่สุดที่เป็นไปได้ และหมายเหตุ: ลำดับของคำสั่งมีความสำคัญ
mbdevpl

2
หากต้องการตอบคำถามของฉันเอง: stackoverflow.com/questions/97875/rm-rf-equivalent-for-windows
Thomas

5
@mbdevpl มา 3 ปีหลังจากคำตอบที่ได้รับการยอมรับและฉันเดาว่าไม่มีใครสามารถโน้มน้าวใจ OP ให้ยอมรับสิ่งนี้ได้
Andy

10
นี่เป็นคำตอบที่ไม่ซับซ้อนในปี 2018 ใช่ไหม
Warren P

9
.gitmodulesไฟล์ยังดูเหมือนว่าได้รับผลกระทบใช้คำสั่งเหล่านี้
Fractalf

206

ขั้นตอนง่าย ๆ

  1. ลบรายการกำหนดค่า:
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. ลบไดเรกทอรีออกจากดัชนี:
    git rm --cached $submodulepath
  3. ผูกมัด
  4. ลบไฟล์ที่ไม่ได้ใช้:
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename

โปรดทราบ: $submodulepathไม่มีเครื่องหมายนำหน้าหรือต่อท้าย

พื้นหลัง

เมื่อคุณทำgit submodule addก็เพียง แต่เพิ่มมัน.gitmodulesแต่เมื่อคุณทำมันเพิ่มไปgit submodule init.git/config

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

git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath

มันเป็นความคิดที่ดีที่จะทำgit rebase HEADก่อนและgit commit ท้ายที่สุดถ้าคุณใส่มันลงในสคริปต์

ดูที่คำตอบสำหรับฉันฉันสามารถปลดเครื่องหมาย submodule ของ Git ได้หรือไม่? .


1
ฉันมี submodules จำนวนมาก (และระเบียบที่ใหญ่กว่า) ดังนั้นฉันจึงต้องผ่านพวกเขาผ่านสำหรับวง เนื่องจากส่วนใหญ่ของพวกเขาที่อยู่ภายใต้ไดเรกทอรีที่เฉพาะเจาะจงและการส่งออกของ LS มีเครื่องหมายทับ for dir in directory/*; do git rm --cached $dir; doneฉันไม่ได้สิ่งที่ต้องการ
Pablo Olmos de Aguilera C.

จะได้รับนี้รายการซึ่งสามารถนำมาใช้ในสคริปต์สำหรับการลบ recursive - git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//'- - ดูเหมือนว่าคุณจะต้องทำจริงๆในกรณีนี้หากมีสิ่ง messed ขึ้นมิฉะนั้นเพียงgit submodule | grep -v '^+' | cut -d' ' -f3
errordeveloper

2
เพื่อรับรายการโมดูลที่ไม่มีการเปลี่ยนแปลงในเครื่อง -git submodule | grep '^+' | cut -d' ' -f2
พัฒนาซอฟต์แวร์ errordeveloper

โปรดทราบฉันต้องรวมsubmodulenameอยู่ในเครื่องหมายคำพูดคู่"submodulename".. อ้างอิง.git/configไฟล์
muon

ง่าย ที่มีประสิทธิภาพ ใน 2.25.0 หลังจากขั้นตอนที่ 1 คุณจะต้องเปลี่ยนขั้นตอน. gitmodules ก่อนขั้นตอนที่ 2
Michel Donais

83

นอกเหนือจากคำแนะนำฉันยังrm -Rf .git/modules/path/to/submoduleต้องสามารถเพิ่ม submodule ใหม่ด้วยชื่อเดียวกัน (ในกรณีของฉันฉันกำลังแทนที่ fork ด้วยต้นฉบับ)


1
ฉันมีปัญหากับสิ่งนี้เช่นกัน หากคุณพยายามติดตั้ง submodule ใหม่ให้กับพา ธ เดียวกันมันจะเก็บข้อมูลสาขาไว้ในตำแหน่งที่คุณกล่าวถึงซึ่งทำให้เกิดความยุ่งเหยิง
jangosteve

ขอบคุณฉันต้องการมันด้วย @ แอนตันฉันเห็นด้วยและฉันได้แก้ไขคำตอบที่ได้รับความนิยมสูงสุดเพื่อเพิ่มข้อมูลนี้
William Denniss

ฉันใช้ตัวเลือก - ชื่อเพื่อให้งานแทนที่ ... ดูstackoverflow.com/questions/14404704/…
joseph.hainline

60

ในการลบ submodule ที่เพิ่มโดยใช้:

git submodule add blah@blah.com:repos/blah.git lib/blah

วิ่ง:

git rm lib/blah

แค่นั้นแหละ.

สำหรับ git รุ่นเก่า (ประมาณ ~ 1.8.5) ให้ใช้:

git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah

1
+1 แน่นอน นี่เป็นคำตอบเดียวที่ถูกต้องจาก git 1.8.3 เป็นต้นไป ควรได้รับการยอมรับว่าเป็นสิ่งที่ถูกต้อง
Xananax

6
git rm.git/modules/ยังคงทิ้งสิ่งที่อยู่ใน (2.5.4)
Rudolf Adamkovič

1
@RudolfAdamkovic มันใช้งานได้สำหรับฉัน โปรดสังเกตว่าจะลบเฉพาะรายการ submodule หากเส้นทางที่ตรงกันตรงกันเท่านั้น หากคุณย้าย submodule แล้วใช้git rmไม่ได้ การทดสอบอย่างรวดเร็วด้วย 2.5.4 บน mac ของฉันอัปเดตไฟล์. gitmodules ตามที่อธิบายไว้ในเอกสารประกอบที่นี่: git-scm.com/docs/git-rm#_submodules ... แต่ถ้าคุณพบว่ามีการรวมกันของแพลตฟอร์มบางอย่าง / รุ่นที่สิ่งนี้ไม่ได้เกิดขึ้นคุณอาจจะมีข้อผิดพลาดเกี่ยวกับมัน
Doug

2
คำตอบนี้ไม่ถูกต้องทั้งหมด git rmปล่อยเนื้อหาไว้ใน.git/modules/dir และ .git/configไฟล์ (Ubuntu, git 2.7.4) คำตอบอื่น ๆ ใช้งานได้ 100%: stackoverflow.com/a/36593218/4973698
mbdevpl

50

คุณต้องลบรายการใน.gitmodulesและ.git/configและลบไดเรกทอรีของโมดูลออกจากประวัติ:

git rm --cached path/to/submodule

หากคุณเขียนในรายชื่อผู้รับจดหมายของ git คงมีคนทำเชลล์สคริปต์ให้คุณ


ไม่จำเป็นต้องมีเชลล์สคริปต์ใด ๆ คำตอบอื่น ๆ มีคำสั่งสำหรับลบร่องรอยทั้งหมดของ submodule: stackoverflow.com/a/36593218/4973698
mbdevpl

42

คุณสามารถใช้นามแฝงเพื่อทำให้โซลูชันที่ผู้อื่นทำให้เป็นแบบอัตโนมัติ:

[alias]
  rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"

วางสิ่งนั้นไว้ในการกำหนดค่า git ของคุณแล้วคุณสามารถ git rms path/to/submodule


-1 เนื่องจากนี่ผิดธรรมดาเกินไป FIRST: นี้อนุมานว่าชื่อ submodule และเส้นทางที่เหมือนกันซึ่งเป็นส่วนใหญ่มักจะไม่ได้กรณีที่ git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms twoIE วินาที: คุณต้องดำเนินการนี้จากเส้นทางที่ถูกต้อง gitนามแฝงควรทำงานที่ใดก็ได้ใน worktree (หรือล้มเหลวอย่างงดงาม) ที่สาม: git config -f .git/configล้มเหลวภายใน submodules .gitโดยปกติจะเป็นไฟล์ที่นั่น
Tino

42

เพื่อสรุปนี่คือสิ่งที่คุณควรทำ:

  1. ตั้งค่าpath_to_submodulevar (ไม่มีสแลชต่อท้าย):

    path_to_submodule=path/to/submodule

  2. ลบบรรทัดที่เกี่ยวข้องออกจากไฟล์. gitmodules:

    git config -f .gitmodules --remove-section submodule.$path_to_submodule

  3. ลบส่วนที่เกี่ยวข้องออกจาก. git / config

    git config -f .git/config --remove-section submodule.$path_to_submodule

  4. เลิกทำและลบ $ path_to_submodule จากดัชนีเท่านั้น (เพื่อป้องกันการสูญหายของข้อมูล)

    git rm --cached $path_to_submodule

  5. ติดตามการเปลี่ยนแปลงที่ทำกับ. gitmodules

    git add .gitmodules

  6. คอมมิท Superproject

    git commit -m "Remove submodule submodule_name"

  7. ลบไฟล์ submodule ที่ไม่ได้ติดตามตอนนี้

    rm -rf $path_to_submodule

    rm -rf .git/modules/$path_to_submodule


ดังนั้นทุกคนที่ดึงการเปลี่ยนแปลงของฉันจะต้องเรียกใช้ rm -rf $ path_to_submodule rm -rf .git / modules / $ path_to_submodule เพื่อลบแคช submodule?
j2emanue

git submodule updateผมขอแนะนำให้ปรับปรุง และหากเส้นทาง submodules ไม่ได้รับการปรับปรุงอย่างถูกต้อง (git พ่นข้อผิดพลาด) ให้ลบออก:rm -rf .git/modules/<submodule> && rm -rf <submodule> && git submodule update
luissquall

40

หาก submodule ได้ตั้งใจเพิ่มเพราะคุณเพิ่มความมุ่งมั่นและผลักโฟลเดอร์ที่มีอยู่แล้วที่เก็บ Git (บรรจุ.git), คุณจะไม่ได้มีไฟล์ที่จะแก้ไขหรืออะไรใน.gitmodules ในกรณีนี้สิ่งที่คุณต้องมีคือ:.git/config

git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push

FWIWฉันยังลบโฟลเดอร์ก่อนที่จะทำ.gitgit add


กรณีของฉัน
zhekaus

37

ฉันพบว่าใช้deinitงานได้ดีสำหรับฉัน:

git submodule deinit <submodule-name>    
git rm <submodule-name>

จากgit docs :

deinit

ยกเลิกการลงทะเบียน submodules ที่กำหนดเช่นลบทั้งsubmodule.$name ส่วนออกจาก. git / config พร้อมกับแผนผังการทำงาน


เห็นด้วยเห็นด้วยโซลูชั่นเดียวกัน มันเป็นวิธีที่ดีที่สุดในวันนี้ในปี 2018)
woto

1
มันไม่ได้ลบ. git / modules / .. คุณควรลบออกดูคำตอบโดย @fvgs
Vilém Kurz

ไม่ทราบสาเหตุที่วิธีแก้ปัญหาที่ง่ายและไม่ง่ายนี้ไม่ใช่หมายเลข 1
Marc Magon

AFAICS นี้น่าจะเป็นคำตอบที่ปลอดภัยที่สุดมากที่สุดสำหรับใหม่gitsซึ่งทราบว่าdeinitเป็นคำตอบอื่น ๆเอา.git/modules/submoduleไดเรกทอรีเร็วเกินไปซึ่งดูเหมือนว่าจะทำให้ใหม่gitที่จะล้มเหลวในขณะนี้หรือแล้ว นอกจากนี้ (ดูความคิดเห็นของฉันที่นั่น) การลบ.git/modules/submoduleอาจเป็นเส้นทางที่ไม่ถูกต้องดังนั้นนี่เป็นขั้นตอนที่อันตรายซึ่งควรดำเนินการในภายหลังเฉพาะเมื่อมีการgitร้องเรียน (หรือถ้าคุณ 299% แน่ใจว่าสิ่งที่คุณต้องการคือเส้นทางที่ถูกต้องและจำเป็นจริงๆ)
Tino

ฉันยังจำเป็นgit commitที่จะกระทำการเปลี่ยนแปลงฉากใน dir ทำงาน: และmodified .gitmodules deleted <submodule-path>
Yuriy Pozniak

20

หลังจากทดลองกับคำตอบที่แตกต่างกันทั้งหมดในเว็บไซต์นี้ฉันลงเอยด้วยวิธีแก้ปัญหานี้:

#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
  echo "$path is no valid git submodule"
  exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path

สิ่งนี้จะเรียกคืนสถานะที่แน่นอนเหมือนก่อนที่คุณจะเพิ่ม submodule คุณสามารถเพิ่ม submodule ได้อีกครั้งซึ่งไม่สามารถทำได้ด้วยคำตอบส่วนใหญ่ที่นี่

git submodule add $giturl test
aboveScript test

นี่จะทำให้คุณมีการชำระเงินที่สะอาดและไม่มีการเปลี่ยนแปลงที่จะกระทำ

นี่คือการทดสอบด้วย:

$ git --version
git version 1.9.3 (Apple Git-50)

ทำไมคุณใช้git rm --cached $pathแล้วrm -rf $pathแทนgit rm -r $path?
bfontaine

-1 ไม่ทำงานหากคุณพยายามลบ submodule ภายใน submodule (submodule สามารถสร้าง tree!) นอกจากนี้ยังมีรถบักกี้เนื่องจากการอ้างข้อความที่ขาดหายไป! ตัวอย่างgit submodule add https://github.com/hilbix/empty.git 'dangerous .. submodule'-> เมื่อคุณพยายามที่จะลบ 'อันตราย .. submodule' ด้วยสคริปต์ของคุณสิ่งนี้จะrm -rf ..เป็นไปได้มากที่สุดที่คุณไม่ต้องการ ..
Tino

17

สิ่งที่ฉันกำลังทำธันวาคม 2012 (รวมคำตอบส่วนใหญ่เหล่านี้):

oldPath="vendor/example"
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove src (optional)
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional housekeeping)
git add .gitmodules
git commit -m "Removed ${oldPath}"

15

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

1. ) ลบส่วนที่เกี่ยวข้องออกจากไฟล์. gitmodules คุณสามารถใช้คำสั่งด้านล่าง:

git config -f .gitmodules --remove-section "submodule.submodule_name"

2. ) จัดลำดับ.gitmodulesการเปลี่ยนแปลง

git add .gitmodules

3. ) .git/configลบส่วนที่เกี่ยวข้องจาก คุณสามารถใช้คำสั่งด้านล่าง:

git submodule deinit -f "submodule_name"

4. ) ลบ gitlink (ไม่มีเครื่องหมายทับ):

git rm --cached path_to_submodule

5. ) ล้างข้อมูล.git/modules:

rm -rf .git/modules/path_to_submodule

6. ) ความมุ่งมั่น:

git commit -m "Removed submodule <name>"

7. ) ลบไฟล์ submodule ที่ไม่ได้ติดตามตอนนี้

rm -rf path_to_submodule

ขอบคุณสำหรับสิ่งนี้. สำหรับฉันฉันต้องจัดเรียงลำดับสามขั้นตอนแรกเป็น 3), 1), 2) การทำ 1) ให้fatal: no submodule mapping found in .gitmodules for path 'submodule_name'ขั้นตอนที่ 3 ก่อนเป็นขั้นตอนที่จำเป็น (git v2.8.2)
U007D

13

ฉันเพิ่งพบโครงการ git ซึ่งรวมถึงคำสั่งที่เกี่ยวข้องกับคอมไพล์ที่มีประโยชน์มากมาย: https://github.com/visionmedia/git-extras

ติดตั้งและพิมพ์:

git-delete-submodule submodule

จากนั้นก็ทำสิ่งต่าง ๆ ไดเรกทอรี submodule จะถูกลบออกจาก repo ของคุณและยังคงอยู่ในระบบไฟล์ของคุณ git commit -am "Remove the submodule"จากนั้นคุณสามารถกระทำการเปลี่ยนแปลงเช่น:


คุณสามารถเรียกสิ่งนี้ว่าเป็นgit delete-submoduleตามที่git-extrasจะต้องอยู่ในเส้นทางที่จะทำงาน นอกจากนี้โปรดทราบว่าฉันไม่แนะนำให้ใช้git-extrasเนื่องจากส่วนต่าง ๆ ของรถนั้นอันตรายมาก IE git-delete-submoduleอาจลบเส้นทางที่ไม่ถูกต้องด้านล่าง.git/modules/*เนื่องจากถือว่าโมดูลและเส้นทางเหมือนกัน (ซึ่งมักจะไม่ใช่กรณี) และมันจะไม่ทำงานอย่างถูกต้องหากคุณพยายามที่จะลบ submodule ภายใน submodule git-extrasอาจเป็นประโยชน์ 99% แต่โปรดอย่าบ่นหากมีสิ่งผิดพลาดเกิดขึ้นกับการใช้งานอย่างเต็มที่ คุณได้รับการเตือนแล้ว!
Tino

10

ฉันต้องทำตามขั้นตอนของ John Douthat อีกขั้นหนึ่งและcdไปยังไดเรกทอรีของ submodule แล้วลบที่เก็บ Git:

cd submodule
rm -fr .git

จากนั้นฉันสามารถส่งไฟล์เป็นส่วนหนึ่งของที่เก็บ Git หลักโดยไม่มีการอ้างอิงเก่าไปยัง submodule


ฉันต้องทำเช่นนี้เพื่อให้ผ่านข้อผิดพลาด "ร้ายแรง: ไม่ใช่ที่เก็บ git:" เมื่อพยายามทำตามgit rm --cacheขั้นตอน
RickDT

9

ต่อไปนี้เป็น 4 ขั้นตอนที่ฉันพบว่าจำเป็นหรือมีประโยชน์ (สำคัญก่อน):

git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."

ในทางทฤษฎี , git rmในขั้นตอนที่ 1ควรดูแลมัน หวังว่าส่วนที่สองของคำถาม OP สามารถตอบได้ในเชิงบวกในหนึ่งวัน (ซึ่งสามารถทำได้ในคำสั่งเดียว)

แต่ ณ เดือนกรกฎาคม 2017 ขั้นตอนที่ 2จำเป็นต้องลบข้อมูลออก.git/modules/เป็นอย่างอื่นคุณไม่สามารถเพิ่ม submodule กลับได้ในอนาคต

คุณสามารถหลีกเลี่ยงสองขั้นตอนข้างต้นสำหรับ git 1.8.5+ ตามคำตอบของ tinlyxเนื่องจากgit submoduleคำสั่งทั้งหมดดูเหมือนจะทำงานได้

ขั้นตอนที่ 3 เอาส่วนสำหรับในแฟ้มthe_submodule .git/configสิ่งนี้ควรทำเพื่อความสมบูรณ์ (รายการอาจทำให้เกิดปัญหาสำหรับรุ่น git ที่เก่ากว่า แต่ฉันไม่มีการทดสอบ)

git submodule deinitสำหรับเรื่องนี้คำตอบส่วนใหญ่แนะนำให้ใช้ git config -f .git/config --remove-sectionฉันคิดว่ามันชัดเจนมากขึ้นและน้อยลงทำให้เกิดความสับสนกับการใช้งาน อ้างอิงถึงเอกสาร-git submodule , git deinit:

ยกเลิกการลงทะเบียน submodules ให้ ... ถ้าคุณต้องการที่จะลบ submodule จากพื้นที่เก็บข้อมูลและการกระทำที่ใช้ Git-RM [1] แทน

สุดท้าย แต่ไม่ท้ายสุดถ้าคุณไม่ทำ git commitคุณจะ / อาจได้รับข้อผิดพลาดเมื่อทำgit submodule summary(ณ คอมไพล์ 2.7):

fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:

สิ่งนี้ไม่ว่าคุณจะทำตามขั้นตอนที่ 2 หรือ 3


7
project dir:     ~/foo_project/
submodule:       ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
  1.   cd ~/foo_project
  2.   git rm lib/asubmodule && 
          rm .git/modules/lib/asubmodule && 
            git submodule lib/asubmodule deinit --recursive --force

7

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

สังเกตเห็นไม่มีใครโพสต์การลบด้วยตนเองดังนั้นจึงเพิ่ม


มันคือ.gitmodules
Arialdo Martini

7

ด้วย git 2.17 ขึ้นไปเป็นเพียง:

git submodule deinit -f {module_name}
git add {module_name}
git commit

ไม่ได้ทำงานค่าสำหรับมิได้git 2.17.1 git 2.20.1อย่างไรก็ตามการใช้git rmแทนที่จะใช้git addงานได้กับทั้งคู่ หมายเหตุ: -fไม่จำเป็นหากสิ่งต่าง ๆ สะอาด อย่าใช้ตัวเลือกด้วยgitหากคุณต้องการป้องกันการสูญหายของข้อมูลโดยไม่ได้ตั้งใจ โปรดทราบว่าสิ่งนี้ยังคง.git/modules/{module_name}อยู่ เป็นวิธีปฏิบัติที่ดีที่สุดที่จะเก็บไว้ที่นั่นเพราะgitพิมพ์ (!) ที่ถูกต้องช่วยวิธีดำเนินการถ้ามีบางสิ่งถูกบล็อกเนื่องจากสิ่งนี้
Tino

4

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


3

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

submodule="path/to/sub"              # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
  • หากสิ่งนี้ไม่ได้ผลสำหรับคุณดูด้านล่าง
  • ไม่มีตัวเลือก ไม่มีอะไรอันตราย และอย่าแม้แต่จะคิดที่จะทำมากขึ้น!
  • ทดสอบกับ Debian Buster 2.20.1และ Ubuntu 18.042.17.118.04
  • "$submodule" เป็นเพียงการเน้นที่จะใส่ชื่อและคุณต้องระวังช่องว่างและไม่ชอบ
  • หากใน Windows เพิกเฉยบรรทัดแรกและแทนที่"$submodule"ด้วยวิธี Windows ของเส้นทางที่ระบุอย่างถูกต้องไปยัง submodule (ฉันไม่ใช่ Windows)

คำเตือน!

อย่าแตะต้องภายใน.gitไดเรกทอรีด้วยตัวเอง! แก้ไขข้างใน.gitเข้าสู่ด้านมืด อยู่ให้ไกล!

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

git submoduleผมคิดว่ามีเป็นส่วนหนึ่งที่อันตรายมากในเอกสารประกอบของ แนะนำให้ลบ$GIT_DIR/modules/<name>/ตัวคุณเอง ในความเข้าใจของฉันนี้ไม่เพียงผิดธรรมดามันเป็นอันตรายอย่างยิ่งและกระตุ้นให้เกิดอาการปวดหัวที่สำคัญในอนาคต ดูด้านล่าง

สังเกตได้ว่า

git module deinit

เป็นสิ่งที่ตรงกันข้ามโดยตรงกับ

git module init

แต่

git submodule deinit -- module
git rm -- module

ยังค่อนข้างตรงกันข้ามกับ

git submodule add -- URL module
git submodule update --init --recursive -- module

เพราะโดยทั่วไปคำสั่งบางอย่างจำเป็นต้องทำมากกว่าสิ่งเดียว:

  • git submodule deinit -- module
    • (1) อัปเดต .git/config
  • git rm
    • (2) ลบไฟล์ของโมดูล
    • (3) ดังนั้นการลบซ้ำ submodules ของ submodule
    • (4) อัปเดต .gitmodules
  • git submodule add
    • ดึงข้อมูลไปที่ .git/modules/NAME/
    • (1) ทำgit submodule initเช่นนั้นอัปเดต.git/config
    • (2) ทำgit submodule updateเช่นนั้นโดยไม่ตรวจสอบโมดูล
    • (4) อัปเดต .gitmodules
  • git submodule update --init --recursive -- module
    • ดึงข้อมูลเพิ่มเติมหากจำเป็น
    • (3) ตรวจสอบ submodules ของ submodule ซ้ำ

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

สิ่งนี้ทำให้งงกับผู้มาใหม่ แต่โดยพื้นฐานแล้วเป็นสิ่งที่ดี gitเพียงทำในสิ่งที่เห็นได้ชัดและทำในสิ่งที่ถูกต้องและไม่พยายามทำมากขึ้น gitเป็นเครื่องมือที่ต้องทำงานที่เชื่อถือได้แทนที่จะเป็น "Eierlegende Wollmilchsau" อีกครั้ง ("Eierlegende Wollmilchsau" แปลให้ฉันเป็น "มีดกองทัพสวิสรุ่นชั่วร้าย")

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

หากล้มเหลว

คำสั่งด้านบนอาจล้มเหลวเนื่องจากสาเหตุดังต่อไปนี้:

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

การแก้ไขที่เป็นไปได้ดังต่อไปนี้

ใช้ใหม่กว่า git

ถ้าเครื่องของคุณเก่าเกินไปไม่มีในของคุณsubmodule deinit gitหากคุณไม่ต้องการ (หรือสามารถ) อัปเดตของคุณgitให้ใช้เครื่องอื่นที่ใหม่กว่าgit! gitมีวัตถุประสงค์เพื่อเผยแพร่อย่างเต็มที่ดังนั้นคุณสามารถใช้งานอื่นgitเพื่อให้งานสำเร็จลุล่วง:

  • workhorse:~/path/to/worktree$ git status --porcelain ต้องไม่ส่งออกอะไร! ถ้าเป็นเช่นนั้นให้ล้างข้อมูลก่อน!
  • workhorse:~/path/to/worktree$ ssh account@othermachine
  • othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
  • ตอนนี้ทำสิ่ง submodule
  • othermachine:~/TMPWORK$ git commit . -m . && exit
  • workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
  • workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD. หากไม่สามารถใช้งานได้ให้ใช้git reset --soft FETCH_HEAD
  • ทีนี้ล้างข้อมูลจนกว่าgit statusจะสะอาดอีกครั้ง คุณสามารถทำได้เนื่องจากคุณเคยทำความสะอาดมาก่อนต้องขอบคุณขั้นตอนแรก

นี่othermachineอาจเป็น VM หรือ Ubuntu WSL ภายใต้ Windows ไม่ว่าจะเป็นอะไรก็ตาม แม้แต่ a chroot(แต่ฉันคิดว่าคุณไม่ใช่คนรูทเพราะถ้าคุณเป็นคนrootนั้นมันควรจะอัปเดตเป็นรุ่นใหม่ได้ง่ายกว่าgit)

โปรดทราบว่าหากคุณไม่สามารถเข้าร่วมได้sshจะมีวิธีการขนส่งที่gitเก็บข้อมูล คุณสามารถคัดลอก worktree ของคุณใน USB stick (รวมถึง.gitไดเรกทอรี) และโคลนจากแท่ง คัดลอกโคลนเพียงเพื่อให้ได้สิ่งที่สะอาดอีกครั้ง นี่อาจเป็น PITA ในกรณีที่ submodules ของคุณไม่สามารถเข้าถึงได้จากเครื่องอื่น ๆ โดยตรง แต่มีวิธีแก้ปัญหาสำหรับสิ่งนี้เช่นกัน:

git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX

$HOME/.gitconfigคุณสามารถใช้คูณนี้และนี้จะถูกบันทึกลง สิ่งที่ต้องการ

git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/

เขียน URL ใหม่เช่น

https://github.com/XXX/YYY.git

เข้าไป

/mnt/usb/repo/XXX/YYY.git

ง่ายถ้าคุณเริ่มคุ้นเคยกับgitคุณสมบัติที่ทรงพลังเช่นนี้

ล้างข้อมูลก่อน

การทำความสะอาดด้วยตนเองนั้นดีเพราะบางทีคุณอาจตรวจพบบางสิ่งที่คุณลืม

  • หากคอมไพล์บ่นเกี่ยวกับสิ่งที่ไม่ได้บันทึกกระทำและผลักดันมันที่ไหนสักแห่งที่ปลอดภัย
  • หากคอมไพล์บ่นเกี่ยวกับสิ่งที่เหลืออยู่git statusและgit clean -ixfdเป็นเพื่อนของคุณ
  • พยายามที่จะหลีกเลี่ยงตัวเลือกจากrmและdeinitตราบเท่าที่คุณสามารถ ตัวเลือก (เช่น-f) gitเป็นสิ่งที่ดีถ้าคุณเป็นมืออาชีพ แต่เมื่อคุณมาที่นี่คุณอาจไม่มีประสบการณ์ในsubmoduleพื้นที่ ปลอดภัยกว่าดีกว่าขออภัย

ตัวอย่าง:

$ git status --porcelain
 M two
$ git submodule deinit two
error: the following file has local modifications:
    two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
    md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
    tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
  NEW
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each
    5: quit                 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'

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

ทำไมไม่เอา$GIT_DIR/modules/<name>/?

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

ตัวอย่าง:

mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two

บรรทัดสุดท้ายแสดงข้อผิดพลาดต่อไปนี้:

A git directory for 'two' is found locally with remote(s):
  origin    https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
  https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

ทำไมข้อผิดพลาดนี้? เพราะ.git/modules/two/ก่อนหน้านี้มีประชากรจากhttps://github.com/hilbix/empty.gitและตอนนี้จะเป็นอีกครั้งที่มีประชากรจากสิ่งอื่นคือhttps://github.com/hilbix/src.git คุณจะไม่เห็นสิ่งนี้หากคุณเติมข้อมูลอีกครั้งจากhttps://github.com/hilbix/empty.git

ต้องทำอะไรตอนนี้ ดีเพียงทำตามที่บอก! ใช้--name someunusedname

git submodule add --name someunusedname https://github.com/hilbix/src.git two

.gitmodules แล้วดูเหมือนว่า

[submodule "someunusedname"]
    path = two
    url = https://github.com/hilbix/src.git

ls -1p .git/modules/ จะช่วยให้

someunusedname/
two/

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

  • สิ่งนี้ไม่เพียงเป็นความจริงสำหรับคุณ นอกจากนี้ยังเป็นจริงสำหรับผู้อื่นทั้งหมดที่ใช้ที่เก็บของคุณ
  • และคุณจะไม่สูญเสียประวัติศาสตร์ ในกรณีที่คุณลืมที่จะผลักดัน submodule เวอร์ชั่นเก่ามากล่าสุดคุณสามารถป้อนสำเนาโลคัลและดำเนินการในภายหลัง โปรดทราบว่ามันเป็นเรื่องธรรมดาที่บางคนลืมที่จะผลักดัน submodules (เพราะนี่คือ PITA สำหรับผู้มาใหม่จนกระทั่งพวกเขาคุ้นเคยกับมันgit)

อย่างไรก็ตามหากคุณลบไดเรกทอรีที่เก็บไว้ทั้งเช็คเอาต์ที่แตกต่างกันจะสะดุดซึ่งกันและกันเพราะคุณจะไม่ใช้--nameตัวเลือกใช่มั้ย ดังนั้นทุกครั้งที่คุณชำระเงินคุณอาจต้องลบ.git/modules/<module>/ไดเรกทอรีซ้ำแล้วซ้ำอีก มันยุ่งยากมากและทำให้ยากต่อการใช้งานgit bisectนี้จะยุ่งยากมากและทำให้ยากที่จะใช้สิ่งที่ต้องการ

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

เหตุผลเพิ่มเติมแสดงไว้ด้านบน ดูที่ls. คุณเห็นอะไรที่นั่น?

ทีนี้ตัวแปรที่สองของโมดูลtwo/ไม่ได้อยู่ภายใต้.git/modules/two/มันอยู่ภายใต้.git/modules/someunusedname/! ดังนั้นสิ่งต่าง ๆgit rm $module; rm -f .git/module/$moduleที่ผิดอย่างสิ้นเชิง! คุณต้องปรึกษาmodule/.gitหรือ.gitmodulesค้นหาสิ่งที่ถูกต้องที่จะลบ!

ดังนั้นไม่เพียง แต่คำตอบส่วนใหญ่เท่านั้นที่ตกอยู่ในกับดักอันตรายนี้แม้กระทั่งgitส่วนขยายที่ได้รับความนิยมอย่างมากก็มีบั๊กนี้ ( ตอนนี้ได้รับการแก้ไขแล้ว )! ดังนั้นควรรักษา.git/ไดเรกทอรีไว้ถ้าคุณไม่ทำสิ่งที่คุณกำลังทำ!

และจากมุมมองทางปรัชญาการล้างประวัตินั้นผิดเสมอ! ยกเว้นกลศาสตร์ควอนตัมตามปกติ แต่นี่เป็นสิ่งที่แตกต่างอย่างสิ้นเชิง

FYI คุณอาจเดาได้: hilbixเป็นบัญชี GitHub ของฉัน


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

2

เพื่อสรุปนี่คือสิ่งที่คุณควรทำ:

ตั้งค่า path_to_submodule var (ไม่มีเครื่องหมายทับ):

path_to_submodule=path/to/submodule

ลบบรรทัดที่เกี่ยวข้องออกจากไฟล์. gitmodules:

git config -f .gitmodules --remove-section submodule.$path_to_submodule

ลบส่วนที่เกี่ยวข้องออกจาก. git / config

git config -f .git/config --remove-section submodule.$path_to_submodule

เลิกทำและลบ $ path_to_submodule จากดัชนีเท่านั้น (เพื่อป้องกันการสูญเสียข้อมูล)

git rm --cached $path_to_submodule

ติดตามการเปลี่ยนแปลงที่ทำกับ. gitmodules

git add .gitmodules

คอมมิท Superproject

git commit -m "Remove submodule submodule_name"

ลบไฟล์ submodule ที่ไม่ได้ติดตามตอนนี้

rm -rf $path_to_submodule

rm -rf .git/modules/$path_to_submodule

ดูเพิ่มเติม: เส้นบอกแนวทางเลือก


คุณช่วยกรุณาขยายสิ่งนี้ด้วยวิธีการลบ submodule โดยทำตาม 'git submodule add' แต่ไม่ต้องทำมัน? ฉันคิดว่าในกรณีนั้นไม่จำเป็นต้องมีความมุ่งมั่นที่จะลบ submodule ใช่ไหม?
Carlo Wood

ฉันคิดว่าคุณต้องสลับgit rm --cached $path_to_submoduleและgit add .gitmodulesไม่? ฉันไม่ได้รับข้อผิดพลาดในคำสั่งแรก: fatal: Please stage your changes to .gitmodules or stash them to proceedเพราะผมมีการเปลี่ยนแปลง unstaged .gitmodulesไป การgit add .gitmodulesแก้ไขข้อแรกนั้น
Carlo Wood

2

นั่นเป็นเรื่องง่าย:

  1. ลบส่วนจาก .gitmodules
  2. โทร: git add .gitmodules
  3. โทร: git submodule deinit <path to submodule>
  4. โทร: git rm <path to submodule>
  5. มุ่งมั่นและผลักดัน

คุณจะต้องลบไฟล์โมดูลในโครงการของคุณด้วยตนเอง


2
สำหรับผมมันก็มากพอที่จะเรียกและgit submodule deinit <submodule_name> คำสั่งสุดท้ายโดยอัตโนมัติลบรายการภายในgit rm <path_to_submodule> .gitmodulesGit 2.17
Dmytro Ovdiienko

1

ฉันได้สร้างสคริปต์ทุบตีเพื่อให้ขั้นตอนการลบง่ายขึ้น นอกจากนี้ยังตรวจสอบว่ามีการเปลี่ยนแปลงในธุรกรรมซื้อคืนที่ไม่ได้บันทึกและขอการยืนยัน มันได้รับการทดสอบแล้วos xว่าน่าสนใจหากรู้ว่ามันทำงานได้เหมือนกันบน linux distros ทั่วไปเช่นกัน:

https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f


0

ใน git ล่าสุดเพียงแค่การดำเนินการ 4 จำเป็นต้องมีการลบ submodule git

  • ลบรายการที่เกี่ยวข้องใน .gitmodules
  • การเปลี่ยนแปลงขั้นตอน git add .gitmodules
  • ลบไดเรกทอรี submodule git rm --cached <path_to_submodule>
  • กระทำมัน git commit -m "Removed submodule xxx"

0

ในกรณีที่คุณต้องทำในหนึ่งบรรทัดคำสั่งด้วยสคริปต์ทุบตีด้านล่าง:

$ cd /path/to/your/repo && /bin/bash $HOME/remove_submodule.sh /path/to/the/submodule

สร้างไฟล์สคริปต์ทุบตีใน$HOMEdir ชื่อ ie remove_submodule.sh:

#!/bin/bash

git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet


0
  • submodule git rm <submodule path> && git commitจะถูกลบโดยการทำงาน git revertนี้สามารถยกเลิกได้โดยใช้
    • การลบจะลบข้อมูลการติดตามของ superproject ซึ่งเป็นทั้งรายการ gitlink และส่วนใน.gitmodulesไฟล์
    • ไดเร็กทอรีการทำงานของ submodule จะถูกลบออกจากระบบไฟล์ แต่ไดเรกทอรี Git จะถูกเก็บไว้รอบ ๆ เพื่อให้สามารถชำระเงินที่ผ่านมาได้โดยไม่ต้องดึงข้อมูลจากที่เก็บอื่น
  • ที่จะสมบูรณ์ลบ submodule $GIT_DIR/modules/<name>/ที่ยังลบด้วยตนเอง

ที่มา: git help submodules


-1

การลบ submodule คอมไพล์

หากต้องการลบgitsubmodule ที่ต่ำกว่า 4 ขั้น

  1. ลบรายการที่เกี่ยวข้องใน .gitmodulesไฟล์ รายการอาจมีลักษณะดังกล่าวด้านล่าง
[submodule "path_to_submodule"]
    path = path_to_submodule
    url = url_path_to_submodule
  1. การเปลี่ยนแปลงขั้นตอน git add .gitmodules
  2. git rm --cached <path_to_submodule>ลบไดเรกทอรี submodule
  3. กระทำgit commit -m "Removed submodule xxx"และผลักดัน

เพิ่มเติม 2 ขั้นตอนเพิ่มเติมที่กล่าวถึงด้านล่างมีความจำเป็นในการทำความสะอาด submodule อย่างสมบูรณ์ในการคัดลอกโคลนในท้องถิ่น

  1. ลบรายการที่เกี่ยวข้องใน.git/configไฟล์ รายการอาจมีลักษณะดังกล่าวด้านล่าง
[submodule "path_to_submodule"]
    url = url_path_to_submodule
  1. ทำ rm -rf .git/modules/path_to_submodule

ขั้นตอนที่ 5 และ 6 เหล่านี้ไม่ได้สร้างการเปลี่ยนแปลงใด ๆ ที่จำเป็นต้องกระทำ


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