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