Użyj podmodułu git foreach z funkcją

10

Moje wcięcie polega na tym, aby mieć skrypt aktualizujący wszystkie podmoduły git zgodnie z gałęzią. Jeśli nie ma takiej gałęzi dla submodułu, używany jest master.

Oto co mam teraz:

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

Ale podczas uruchamiania tego skryptu pojawia się błąd:

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.

Domyślam się, że git submodule foreachwykorzystuje eval (zgodnie z dokumentacją ), którego nie używam poprawnie w tym kontekście.

Istnieją miliardy przykładów użycia tego polecenia z „wbudowanym wywołaniem zwrotnym”, ale nie udało mi się znaleźć ani jednego z wywołaniem zwrotnym w postaci funkcji. Masz pomysł, jak to rozwiązać?

oleq
źródło

Odpowiedzi:

7

Rozwiązałem problem, umieszczając funkcję w cudzysłowie jako wywołanie zwrotne:

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

Zauważ, że zmienne podobne $1są zmiennymi z przestrzeni nazw skryptu. „Te, które uciekły” $\(bar), \$branchsą oceniane w ramach „wywołania zwrotnego”. To było dość łatwe.

oleq
źródło
7

Możesz korzystać z funkcji, ale najpierw musisz je wyeksportować:

export -f pbranch

Ponadto, jeśli chcesz rozszerzeń składni bash, możesz wymusić uruchomienie powłoki bash:

git submodule foreach bash -c 'pbranch'
nschum
źródło
5

Funkcja powłoki istnieje tylko wewnątrz powłoki, w której jest zdefiniowana. Podobnie metoda Java istnieje tylko w instancji programu, w której jest zdefiniowana i tak dalej. Nie można wywoływać funkcji powłoki z innego programu, nawet jeśli ten program jest inną powłoką uruchamianą przez proces potomny oryginalnej powłoki.

Zamiast definiować funkcję, utwórz pbranchosobny skrypt. Umieść to w swojej ŚCIEŻCE.

#!/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 programowania uwaga: zawsze umieszczone w cudzysłowie zmiennych podstawienia i podstawień komend: "$foo", "$(foo)", chyba że wiesz, że trzeba pozostawić cytaty na zewnątrz. Niechronione podstawienia są interpretowane jako rozdzielone spacjami listy wzorców globów, co prawie nigdy nie jest pożądane. Ponadto, nie używaj backicks, z podobnych powodów, użyj $(…)zamiast tego. Tutaj nie ma to żadnego znaczenia, ponieważ nazwy gałęzi git nie zawierają znaków specjalnych i ponieważ [ -z $branch ]są parsowane, [ -z ]co jest również prawdą, gdy branchjest puste. Ale nie przyzwyczajaj się do pomijania cytatów, wróci i cię ugryzie.

Powiedzmy, że skrypt jest wywoływany pbranch-submodule, a następnie możesz go uruchomić

git submodule foreach pbranch-submodule
Gilles „SO- przestań być zły”
źródło
A jeśli nazwiesz to git-pbranch-submodule, może zachowywać się jak wbudowane polecenie git: git pbranch-submodulelub git submodule foreach git pbranch-submodule. (Zauważ, że foreach akceptuje polecenie powłoki, a nie polecenie git).
idbrii