Use o submódulo git foreach com a função

10

Minha intenção é ter um script que atualize todos os sub-módulos git de acordo com o ramo. Se não houver tal ramificação para um submódulo, o mestre será usado.

Isto é o que eu tenho agora:

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

Mas ao executar esse script, o erro é gerado:

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.

Meu palpite é que git submodule foreachutiliza eval (de acordo com a documentação ), que não uso corretamente neste contexto.

Existem bilhões de exemplos de como usar este comando com "retorno de chamada em linha", mas não consegui encontrar um único com o retorno de chamada na forma da função. Alguma idéia de como resolver isso?

oleq
fonte

Respostas:

7

Resolvi meu problema colocando a função dentro das aspas como um retorno de chamada:

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

Observe que variáveis ​​como $1são as do espaço para nome do script. Os "escapados" $\(bar), como , \$branchsão avaliados dentro do "retorno de chamada". Foi bem fácil.

oleq
fonte
7

Você pode usar funções, mas precisa exportá-las primeiro:

export -f pbranch

Além disso, se você deseja extensões de sintaxe do bash, pode forçar o início de um shell do bash:

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

Uma função shell existe apenas dentro do shell onde está definida. Da mesma forma, um método Java existe apenas na instância do programa em que está definido e assim por diante. Você não pode invocar uma função de shell de outro programa, mesmo que esse programa seja outro shell executado por um processo filho do shell original.

Em vez de definir uma função, crie pbranchum script separado. Coloque no seu CAMINHO.

#!/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 nota programação: sempre colocar aspas em torno substituições de variáveis e substituições de comando: "$foo", "$(foo)", a menos que você sabe que você precisa para deixar as citações fora. Substituições não protegidas são interpretadas como listas de padrões glob separados por espaços em branco, o que quase nunca é desejado. Além disso, não use backticks, por razões semelhantes, use em seu $(…)lugar. Aqui, isso realmente não importa, porque os nomes das ramificações git não contêm caracteres especiais e porque [ -z $branch ]são analisados ​​como [ -z ]também são verdadeiros quando branchestão vazios. Mas não adquira o hábito de omitir as aspas, ele voltará e morderá você.

Vamos dizer que o script é chamado pbranch-submodule, então você pode executar

git submodule foreach pbranch-submodule
Gilles 'SO- parar de ser mau'
fonte
E se você escolher git-pbranch-submodule, ele pode se comportar como um comando git embutido: git pbranch-submoduleou git submodule foreach git pbranch-submodule. (Note-se que foreach aceita um comando da shell e não um comando git.)
idbrii