関数でgitサブモジュールforeachを使用する


10

私のインデントは、与えられたブランチに従ってすべてのgitサブモジュールを更新するスクリプトを作成することです。サブモジュールにそのようなブランチがない場合は、マスターが使用されます。

これは私が今持っているものです:

#!/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シェルを強制的に起動することもできます。

git submodule foreach bash -c 'pbranch'

5

シェル関数は、それが定義されているシェルの内部にのみ存在します。同様に、Javaメソッドは、それが定義されているプログラムインスタンスにのみ存在します。別のプログラムが元のシェルの子プロセスによって実行されている別のシェルであっても、そのプログラムからシェル関数を呼び出すことはできません。

関数を定義する代わりにpbranch、別のスクリプトを作成します。PATHに入れます。

#!/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)"で囲みます。ただし、引用符を省略する必要があることがわかっている場合を除きます。保護されていない置換は、空白パターンで区切られたグロブパターンのリストとして解釈されます。また、同様の理由でバックティックを使用しないでください$(…)。代わりに使用してください。gitのブランチ名に特殊文字が含まれていない、とためをするのでここでは、実際には問題ではない[ -z $branch ]として解析され[ -z ]たときにも真であるbranch空です。しかし、引用を省略する習慣をつけないでください、それは戻ってきてあなたを噛みます。

スクリプトがと呼ばれているとしましょう。pbranch-submoduleその後、実行できます

git submodule foreach pbranch-submodule

そしてgit-pbranch-submodule、それに名前を付けると、組み込みのgitコマンドのように動作できます:git pbranch-submoduleまたはgit submodule foreach git pbranch-submodule。(foreachはgitコマンドではなく、シェルコマンドを受け入れることに注意してください。)
idbrii
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.