Use o submódulo git paraeach com função

8

Meu recuo é ter um script que atualize todos os submódulos git de acordo com a ramificação que é dada. Se não houver tal ramo para um submódulo, o mestre é usado.

Isso é 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 este script, o erro é lançado:

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 foreach utiliza eval (de acordo com a documentação ), que eu 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 em forma de função. Alguma ideia de como resolver isso?

    
por oleq 18.07.2013 / 11:56

3 respostas

5

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 $1 são aquelas do espaço de nomes do script. Os "escapados" como $\(bar) , \$branch são avaliados dentro do "retorno de chamada". Foi bem fácil.

    
por 22.07.2013 / 09:45
6

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

export -f pbranch

Além disso, se você quiser extensões de sintaxe bash, você pode querer forçar um shell bash a ser iniciado:

git submodule foreach bash -c 'pbranch'
    
por 15.04.2015 / 15:19
5

Uma função shell existe somente 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 que é executado por um processo filho do shell original.

Em vez de definir uma função, torne pbranch um script separado. Coloque em 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"

Nota de programação da shell: sempre coloque aspas duplas em torno de substituições de variáveis e substituições de comandos: "$foo" , "$(foo)" , a menos que você saiba que precisa deixar as aspas. As substituições desprotegidas são interpretadas como listas separadas por espaços em branco de padrões globais, o que quase nunca é desejado. Além disso, não use backticks, por motivos semelhantes, use $(…) . Aqui, não importa realmente porque os nomes das ramificações git não contêm caracteres especiais e porque [ -z $branch ] é analisado como [ -z ] , o que também é verdade quando branch está vazio. Mas não adquira o hábito de omitir as citações, ele voltará e morderá você.

Digamos que o script seja chamado de pbranch-submodule , você pode executar

git submodule foreach pbranch-submodule
    
por 22.07.2013 / 03:56

Tags