Verwenden Sie das Git-Submodul für jedes mit Funktion

10

Ich möchte ein Skript haben, das alle Git-Submodule entsprechend der angegebenen Verzweigung aktualisiert. Wenn es für ein Submodul keinen solchen Zweig gibt, wird der Master verwendet.

Das habe ich jetzt:

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

Beim Ausführen dieses Skripts wird jedoch der folgende Fehler ausgegeben:

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.

Ich vermute, dass git submodule foreacheval (laut Dokumentation ) verwendet wird, was ich in diesem Zusammenhang nicht richtig verwende.

Es gibt Milliarden von Beispielen für die Verwendung dieses Befehls mit "Inline-Rückruf", aber ich konnte keinen einzigen mit dem Rückruf in Form der Funktion finden. Irgendeine Idee, wie man das löst?

oleq
quelle

Antworten:

7

Sie können Funktionen verwenden, müssen diese jedoch zuerst exportieren:

export -f pbranch

Wenn Sie Bash-Syntaxerweiterungen wünschen, möchten Sie möglicherweise das Starten einer Bash-Shell erzwingen:

git submodule foreach bash -c 'pbranch'
nschum
quelle
6

Ich habe mein Problem behoben, indem ich die Funktion als Rückruf in die Anführungszeichen eingefügt habe:

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

Beachten Sie, dass Variablen wie $1die aus dem Namespace des Skripts stammen. Die "entkommenen" mögen $\(bar), \$branchwerden innerhalb des "Rückrufs" ausgewertet. Es war ziemlich einfach.

oleq
quelle
5

Eine Shell-Funktion existiert nur innerhalb der Shell, in der sie definiert ist. Ebenso existiert eine Java-Methode nur in der Programminstanz, in der sie definiert ist, und so weiter. Sie können eine Shell-Funktion nicht von einem anderen Programm aus aufrufen, selbst wenn es sich bei diesem Programm zufällig um eine andere Shell handelt, die von einem untergeordneten Prozess der ursprünglichen Shell ausgeführt wird.

Erstellen Sie pbranchein separates Skript, anstatt eine Funktion zu definieren . Legen Sie es in Ihren Pfad.

#!/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 - Programmierung Anmerkung: immer setzen doppelte Anführungszeichen um variable Ersetzungen und Befehlsersetzungen: "$foo", "$(foo)", es sei denn , Sie wissen , dass Sie die Anführungszeichen weglassen müssen. Ungeschützte Substitutionen werden als durch Leerzeichen getrennte Listen von Glob-Mustern interpretiert, was fast nie erwünscht ist. Verwenden Sie aus ähnlichen Gründen auch keine Backticks $(…). Hier spielt es eigentlich keine Rolle, weil Git-Zweignamen keine Sonderzeichen enthalten und weil [ -z $branch ]analysiert wird, [ -z ]was auch dann wahr ist, wenn branches leer ist. Aber gewöhnen Sie sich nicht an, die Zitate wegzulassen, es wird zurückkommen und Sie beißen.

Angenommen, das Skript wird aufgerufen pbranch-submoduleund kann dann ausgeführt werden

git submodule foreach pbranch-submodule
Gilles 'SO - hör auf böse zu sein'
quelle
Und wenn Sie es benennen git-pbranch-submodule, kann es sich wie ein eingebauter git-Befehl verhalten: git pbranch-submoduleoder git submodule foreach git pbranch-submodule. (Beachten Sie, dass foreach einen Shell-Befehl und keinen Git-Befehl akzeptiert.)
idbrii