Gunakan git submodule foreach dengan fungsi

10

Indentasi saya adalah memiliki skrip yang memperbarui semua submodules git sesuai dengan cabang yang diberikan. Jika tidak ada cabang seperti itu untuk submodule, master digunakan.

Inilah yang saya miliki sekarang:

#!/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

Tetapi ketika menjalankan skrip ini, kesalahan terjadi:

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.

Dugaan saya adalah yang git submodule foreachmenggunakan eval (sesuai dengan dokumentasi ), yang saya tidak gunakan dengan benar dalam konteks ini.

Ada miliaran contoh cara menggunakan perintah ini dengan "inline callback" tetapi saya tidak dapat menemukan satu pun dengan callback dalam bentuk fungsi. Ada ide untuk mengatasi ini?

oleq
sumber

Jawaban:

7

Saya menyelesaikan masalah saya dengan meletakkan fungsi di dalam tanda kutip sebagai panggilan balik:

#!/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;
"

Perhatikan bahwa variabel suka $1adalah variabel dari namespace skrip. Seperti "yang lolos" $\(bar), \$branchdievaluasi dalam "panggilan balik". Itu sangat mudah.

oleq
sumber
7

Anda dapat menggunakan fungsi, tetapi Anda harus mengekspornya terlebih dahulu:

export -f pbranch

Juga, jika Anda menginginkan ekstensi bash sintaks, Anda mungkin ingin memaksa bash shell untuk dimulai:

git submodule foreach bash -c 'pbranch'
nschum
sumber
5

Fungsi shell hanya ada di dalam shell di mana ia didefinisikan. Demikian pula, metode Java hanya ada dalam contoh program di mana ia didefinisikan, dan seterusnya. Anda tidak dapat menjalankan fungsi shell dari program lain, bahkan jika program itu kebetulan adalah shell lain yang dijalankan oleh proses turunan dari shell asli.

Alih-alih mendefinisikan fungsi, buat pbranchskrip terpisah. Masukkan ke dalam PATH Anda.

#!/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"

Shell pemrograman catatan: selalu menempatkan tanda kutip ganda sekitar substitusi variabel dan substitusi perintah: "$foo", "$(foo)", kecuali jika Anda tahu bahwa Anda perlu meninggalkan tanda kutip keluar. Substitusi yang tidak dilindungi ditafsirkan sebagai daftar pola glob yang dipisahkan oleh spasi, yang hampir tidak pernah diinginkan. Juga, jangan gunakan backticks, karena alasan yang sama, gunakan $(…)sebaliknya. Di sini, sebenarnya tidak masalah karena nama cabang git tidak mengandung karakter khusus, dan karena [ -z $branch ]diuraikan seperti [ -z ]yang juga benar ketika branchkosong. Tapi jangan terbiasa menghilangkan tanda kutip, itu akan kembali dan menggigit Anda.

Katakanlah skrip dipanggil pbranch-submodule, Anda kemudian dapat menjalankan

git submodule foreach pbranch-submodule
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Dan jika Anda beri nama git-pbranch-submodule, itu bisa berperilaku seperti perintah built-in git: git pbranch-submoduleatau git submodule foreach git pbranch-submodule. (Perhatikan bahwa foreach menerima perintah shell dan bukan perintah git.)
idbrii