มีวิธีทำให้ git pull อัปเดต submodules โดยอัตโนมัติหรือไม่?


203

มีวิธีที่จะมีโดยอัตโนมัติgit submodule update(หรือgit submodule update --initเรียกว่ายิ่งเมื่อใดก็ตามที่git pullจะทำ?

กำลังมองหาการตั้งค่าการตั้งค่า git หรือนามแฝง git เพื่อช่วยในเรื่องนี้


4
ที่เกี่ยวข้อง: stackoverflow.com/questions/1899792/…
philfreo

1
เหตุใดนามแฝง git จึงนิยมใช้นามแฝงของเชลล์
wnoise

20
นามแฝง git นั้นดีเพราะมันสรุปคำสั่งในเนมสเปซ "git" คุณอาจถามว่าทำไมคำสั่ง git ทั้งหมดเริ่มต้นด้วย "git" แทนที่จะมีชื่อของตัวเอง
Lily Ballard

5
สำหรับทุกคนที่พบสิ่งนี้คำตอบที่ได้รับการโหวตสูงนั้นล้าสมัยแล้ว คำตอบของ Kane นั้นถูกต้อง: stackoverflow.com/a/49427199/3499424
John Neuhaus

คำตอบ:


176

ในฐานะของGit 2.14คุณสามารถใช้git pull --recurse-submodules(และใช้นามแฝงกับสิ่งที่คุณต้องการ)

ในฐานะของGit 2.15คุณสามารถตั้งค่าsubmodule.recurseเป็นจริงเพื่อเปิดใช้งานพฤติกรรมที่ต้องการ

คุณสามารถทำได้ทั่วโลกโดยเรียกใช้:

git config --global submodule.recurse true

3
ได้รับการยืนยันกับ 2.16, การตั้งค่านี้เป็น true จะทำให้git pullยังเรียก submodule submodule updateและเรียกใช้ นี่จำเป็นต้องเป็นคำตอบที่ได้รับการยอมรับในขณะนี้
John Neuhaus

1
ในการตั้งค่านี้ทั่วโลก:git config --global submodule.recurse true
wintersolutions

14
ฉันรู้สึกหงุดหงิดจาก submodules แล้วฉันก็ทำแบบนี้ ตอนนี้พวกเขาทำงานเหมือนที่ฉันคาดหวัง มีเหตุผลที่ฉันไม่คิดว่านี่ไม่ใช่พฤติกรรมเริ่มต้นหรือไม่
เบ็น

9
พวกเขาควรเปิดใช้งานสิ่งนั้นด้วยgit cloneเช่นกัน และทำให้มันเป็นค่าเริ่มต้น มิฉะนั้นจะเป็นต้านทานขนาดใหญ่เพื่อใช้ submodules เป็นโมดูลของผู้คนมักจะได้รับออกจากซิงค์ :-(
Ciro Santilli郝海东冠状病六四事件法轮功

1
@CiroSantilli新疆改造中心法轮功六四事件Santilli คอมไพล์คำสั่ง (เช่นcommit, fetch, pullฯลฯ ) ถูกออกแบบมาเพื่อนำมาประยุกต์ใช้กับที่เก็บในปัจจุบัน submodule เป็นที่เก็บอื่นและไม่ควรได้รับผลกระทบจากคำสั่งที่ดำเนินการในพื้นที่เก็บข้อมูลหลักโดยค่าเริ่มต้น นี่เป็นการตัดสินใจออกแบบโดยนักพัฒนาคอมไพล์
ประจุลบ

113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

หากคุณต้องการให้อาร์กิวเมนต์ส่งผ่านไปยัง git pull ให้ใช้สิ่งนี้แทน:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'

4
อย่าลืมใช้ "git config --global" ถ้าคุณต้องการนามแฝงนี้กับ repos git ทั้งหมดที่คุณใช้
yoyo

43

เริ่มต้นด้วย Git 1.7.5 ควรอัปเดต submodules โดยอัตโนมัติตามค่าเริ่มต้นที่คุณต้องการ

[แก้ไข: ตามความคิดเห็น: พฤติกรรม 1.7.5 ใหม่คือการดึงข้อมูลการส่งล่าสุดสำหรับการส่งข้อมูลโดยอัตโนมัติแต่จะไม่อัปเดตพวกเขา (ตามgit submodule updateความหมาย) ดังนั้นข้อมูลในคำตอบนี้จึงเกี่ยวข้องกับพื้นหลัง แต่ไม่ใช่คำตอบที่สมบูรณ์ด้วยตัวเอง คุณยังต้องใช้นามแฝงเพื่อดึงและอัปเดต submodules ในคำสั่งเดียว]

พฤติกรรมเริ่มต้น "ตามคำขอ" คือการอัปเดต submodules ทุกครั้งที่คุณดึงข้อมูลคอมมิชชันที่อัพเดทการยอมรับ submodule และการกระทำนี้ไม่ได้อยู่ในโคลนในเครื่องของคุณ
นอกจากนี้คุณยังสามารถอัปเดตได้ทุกครั้งที่ดึงข้อมูลหรือไม่ (พฤติกรรม 1.7 ก่อนที่ฉันคิด) ตัวเลือกการตั้งค่าที่จะเปลี่ยนพฤติกรรมนี้
fetch.recurseSubmodules

on-demandตัวเลือกนี้สามารถตั้งค่าได้อย่างใดอย่างหนึ่งให้เป็นค่าบูลีนหรือ
การตั้งค่าเป็นบูลีนจะเปลี่ยนพฤติกรรมของfetchและpullเพื่อชดเชยให้เป็นแบบไม่ จำกัด เมื่อตั้งค่าเป็นจริงหรือไม่รับเลยเมื่อตั้งค่าเป็นเท็จ

เมื่อตั้งค่าon-demand(ค่าเริ่มต้น) fetchและpull จะ recurse เป็น submodule ประชากรเมื่อ superproject มันดึงกระทำการปรับปรุงที่อ้างอิง

ดู:

สำหรับข้อมูลเพิ่มเติม.

git fetch --recurse-submodules[=yes|on-demand|no]

27
ระวัง: ตามคำตอบด้านล่างนี้จะทำการดึงข้อมูลการเปลี่ยนแปลงโดยอัตโนมัติคุณยังต้องทำการอัปเดต submodule - ดังนั้นคำตอบแทนจะถูกต้อง
Artem

4
@ บทความถูกต้อง คำตอบนี้มีประโยชน์ แต่ไม่ได้ตอบคำถามทั้งหมด การตั้งค่านี้ก็จะดำเนินการไม่ได้git fetch git submodule update
Andrew Ferrier

2
คำตอบนี้หลอกลวงอย่างมาก แม้เมื่อใช้กับgit pullแทนที่จะใช้git fetchตัวเลือกนี้จะทำให้การเรียกซ้ำเกิดขึ้น มันจะไม่เปลี่ยนแปลงสิ่งที่กระทำถูกตรวจสอบใน submodules เลย ดังนั้นgit submodule updateยังคงมีความจำเป็นตามที่ระบุไว้โดย @Atem
Mark Amery

31

ฉันประหลาดใจที่ไม่มีใครพูดถึงการใช้ hooks git เพื่อทำสิ่งนี้!

เพียงเพิ่มไฟล์ที่มีชื่อpost-checkoutและpost-mergeใน.git/hooksไดเรกทอรีของที่เก็บที่เกี่ยวข้องและใส่ต่อไปนี้ในแต่ละไฟล์:

#!/bin/sh
git submodule update --init --recursive

เนื่องจากคุณถามชื่อแทนอย่างเจาะจงโดยสมมติว่าคุณต้องการมีสิ่งนี้สำหรับที่เก็บหลาย ๆ แห่งคุณสามารถสร้างนามแฝงที่เพิ่มสิ่งเหล่านี้ลงในที่เก็บของของ.git/hooksคุณได้


2
มีวิธีที่จะทำให้การตั้งค่าระดับโลกนี้หรือไม่? หรือที่คุณได้รับโดยอัตโนมัติเมื่อตรวจสอบที่เก็บ?
Raoul Steffen

3
git รุ่นล่าสุด 2.9 ได้เพิ่มการตั้งค่าชื่อcore.hooksPathสำหรับไดเรกทอรี hooksดูเอกสารสำหรับgit-configรายละเอียดเพิ่มเติม
taleinat

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

1
ฉันเห็นว่านั่นอาจเป็นปัญหาด้านความปลอดภัย ท้ายที่สุด, ฉันต้องการใช้มันเพื่อรันโค้ดโปรแกรมฉันบนคอมพิวเตอร์ของเพื่อนร่วมงานโดยไม่ต้องสั่งสอนพวกเขา
Raoul Steffen

1
วิธีนี้เป็นความคิดแรกของฉัน แต่แล้วฉันก็รู้ว่ามันจะไม่ครอบคลุมคนที่ใช้git pull --rebase:(
Vaz

8

นามแฝงตามที่เควินบัลลาร์ดแนะนำเป็นทางออกที่ดีอย่างสมบูรณ์แบบ เพียงแค่โยนตัวเลือกอื่นออกไปคุณสามารถใช้ตะขอหลังที่ทำการรวมซึ่งทำงานgit submodule update [--init]ได้ง่าย


7

คุณสามารถสร้างนามแฝงสำหรับคำสั่ง git ที่จัดการการปรับปรุง submodule โดยอัตโนมัติ เพิ่มต่อไปนี้ใน. bashrc ของคุณ

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}

1
แทนที่จะเป็นนามแฝงสำหรับ git คุณสามารถเพิ่มนามแฝงเพื่อ git ผ่านคำสั่ง alias หรือโดยการสร้างคำสั่งในเส้นทางของคุณที่เริ่มต้นด้วย git- (git-bettermodule)
idbrii

7

ตามที่คนอื่นพูดถึงคุณสามารถตั้งค่านี้ด้วย:

git config --global submodule.recurse true

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

[submodule]
  recurse = true

0

วิธีเดียวที่ฉันจะได้รับ submodules และซ้อน submodules เพื่ออัปเดต:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

ฉันพยายามสร้างนามแฝงผ่านทางเทอร์มินัลเนื่องจากวงเล็บดังนั้นฉันจึงต้องเพิ่มสิ่งนี้ลงใน. gitconfig สำหรับทั่วโลก:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

คำแนะนำสำหรับวิธีการเรียกใช้คำสั่งหรือนามแฝงโดยอัตโนมัติ?

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