ใช้ git submodule foreach พร้อมกับฟังก์ชั่น


10

การเยื้องของฉันคือการมีสคริปต์ที่อัปเดต submodules git ทั้งหมดตามสาขาที่ได้รับ หากไม่มีสาขาดังกล่าวสำหรับ submodule ระบบจะใช้ต้นแบบ

นี่คือสิ่งที่ฉันมีตอนนี้:

#!/bin/bash -x

if [ -z $1 ]; then
    echo "Branch name required."
    exit
fi

function pbranch {
    exists=`git show-ref refs/heads/$branch`

    if [ -z $exists ]; then
        branch="master"
    fi

    git co $branch
    git pull origin $branch
}

branch=$1

git submodule foreach pbranch

แต่เมื่อรันสคริปต์นี้ข้อผิดพลาดจะถูกโยน:

oleq@pc ~/project> git-fetchmodules major
+ '[' -z major ']'
+ branch=major
+ git submodule foreach pbranch
Entering 'submodule'
/usr/lib/git-core/git-submodule: 1: eval: pbranch: not found
Stopping at 'submodule'; script returned non-zero status.

ฉันเดาว่าgit submodule foreachใช้ eval (ตามเอกสาร ) ซึ่งฉันใช้ไม่ถูกต้องในบริบทนี้

มีตัวอย่างวิธีการใช้คำสั่งนี้กับ "การโทรกลับแบบอินไลน์" หลายพันล้านรายการแต่ฉันไม่พบรายการเดียวด้วยการติดต่อกลับในรูปแบบของฟังก์ชัน ความคิดวิธีการแก้ปัญหานี้?

คำตอบ:


7

ฉันแก้ไขปัญหาของฉันโดยใส่ฟังก์ชั่นไว้ในเครื่องหมายคำพูดเป็นการโทรกลับ:

#!/bin/bash

if [ -z $1 ]; then
    echo "Branch name required."
    exit
fi

git submodule foreach "
    branch=$1;
    exists=\$(git show-ref refs/heads/\$branch | cut -d ' ' -f1);

    if [ -z \$exists ]; then
        branch='master';
    fi;

    echo Checking branch \$branch for submodule \$name.;

    git fetch --all -p;
    git co \$branch;
    git reset --hard origin/\$branch;
"

โปรดทราบว่าตัวแปรเช่น$1นั้นมาจากเนมสเปซของสคริปต์ ว่า "คนที่หนีออกมา" ชอบ$\(bar), \$branchมีการประเมินภายใน "โทรกลับ" มันค่อนข้างง่าย


7

คุณสามารถใช้ฟังก์ชั่น แต่คุณต้องส่งออกก่อน:

export -f pbranch

นอกจากนี้หากคุณต้องการส่วนขยายไวยากรณ์ bash คุณอาจต้องการบังคับให้เริ่มใช้งาน bash shell:

git submodule foreach bash -c 'pbranch'

5

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

แทนที่จะกำหนดฟังก์ชั่นให้สร้างpbranchสคริปต์แยกกัน วางไว้ในเส้นทางของคุณ

#!/bin/sh
branch="$1"
ref="$(git show-ref "refs/heads/$branch")"
if [ -z "$ref" ]; then
    branch="master"
fi
git co "$branch"
git pull origin "$branch"

เชลล์ทราบการเขียนโปรแกรม: มักจะใส่คำพูดสองรอบแทนตัวแปรและแทนคำสั่ง"$foo", "$(foo)"เว้นแต่คุณจะรู้ว่าคุณต้องการที่จะออกจากคำพูดออกมา การทดแทนที่ไม่มีการป้องกันถูกตีความว่าเป็นรายการของรูปแบบ glob ที่คั่นด้วยช่องว่างซึ่งแทบไม่ต้องการเลย นอกจากนี้อย่าใช้ backticks ด้วยเหตุผลที่คล้ายคลึงกันให้ใช้$(…)แทน ที่นี่มันไม่สำคัญเพราะชื่อสาขา git ไม่มีอักขระพิเศษและเนื่องจาก[ -z $branch ]มีการแยกวิเคราะห์[ -z ]ซึ่งเป็นจริงเช่นกันเมื่อbranchไม่มีข้อมูล แต่อย่าไปยุ่งกับการละทิ้งคำพูดมันจะกลับมากัดคุณ

สมมติว่าสคริปต์นั้นมีชื่อว่าpbranch-submoduleคุณสามารถเรียกใช้ได้

git submodule foreach pbranch-submodule

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