Usa git submodule foreach con la funzione


10

La mia intenzione è di avere uno script che aggiorni tutti i sottomoduli git in base al ramo dato. Se non esiste un ramo di questo tipo per un sottomodulo, viene utilizzato il master.

Questo è quello che ho ora:

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

Ma quando si esegue questo script, viene generato l'errore:

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.

La mia ipotesi è che git submodule foreachutilizzi eval (secondo la documentazione ), che non uso correttamente in questo contesto.

Ci sono miliardi di esempi su come usare questo comando con "callback inline" ma non sono riuscito a trovarne uno con il callback sotto forma di funzione. Qualche idea su come risolverlo?

Risposte:


7

Ho risolto il mio problema inserendo la funzione tra virgolette come callback:

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

Nota che variabili come $1quelle sono dallo spazio dei nomi dello script. I "caratteri di escape" come $\(bar), \$branchvengono valutati all'interno di "callback". È stato abbastanza facile.


7

Puoi usare le funzioni, ma devi prima esportarle:

export -f pbranch

Inoltre, se vuoi estensioni di sintassi bash, potresti voler forzare l'avvio di una shell bash:

git submodule foreach bash -c 'pbranch'

5

Una funzione di shell esiste solo all'interno della shell dove è definita. Allo stesso modo, esiste un metodo Java solo nell'istanza del programma in cui è definito e così via. Non è possibile richiamare una funzione di shell da un altro programma, anche se quel programma sembra essere un'altra shell che viene eseguita da un processo figlio della shell originale.

Invece di definire una funzione, crea pbranchuno script separato. Mettilo nel tuo PERCORSO.

#!/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 programmazione nota: sempre mettere i doppi apici intorno sostituzioni variabili e sostituzioni di comando: "$foo", "$(foo)", a meno che non si sa che è necessario lasciare le citazioni fuori. Le sostituzioni non protette vengono interpretate come elenchi separati da spazi bianchi di modelli glob, che non è quasi mai desiderato. Inoltre, non usare i backtick, per ragioni simili, usa $(…)invece. Qui, in realtà non importa perché i nomi dei rami git non contengono caratteri speciali e perché [ -z $branch ]viene analizzato come [ -z ]ciò è vero anche quando branchè vuoto. Ma non prendere l'abitudine di omettere le virgolette, tornerà e ti morderà.

Supponiamo che lo script venga chiamato pbranch-submodule, quindi puoi eseguirlo

git submodule foreach pbranch-submodule

E se lo chiami git-pbranch-submodule, può comportarsi come un comando git incorporato: git pbranch-submoduleo git submodule foreach git pbranch-submodule. (Nota che foreach accetta un comando shell e non un comando git.)
idbrii
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.