Используйте подмодуль git foreach с функцией

10

Я хочу иметь скрипт, который обновляет все подмодули git, в соответствии с тем, какая ветка дана. Если для подмодуля нет такой ветки, используется master.

Вот что у меня сейчас:

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

Но при запуске этого скрипта выдается ошибка:

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.

Я предполагаю, что git submodule foreachиспользует eval (согласно документации ), который я не правильно использую в этом контексте.

Есть миллиарды примеров использования этой команды с «встроенным обратным вызовом», но я не смог найти ни одного с обратным вызовом в форме функции. Есть идеи, как это решить?

oleq
источник

Ответы:

7

Я решил свою проблему, поместив функцию внутри кавычек в качестве обратного вызова:

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

Обратите внимание, что переменные, подобные переменным $1из пространства имен скрипта. В «сбежавших из них» , как $\(bar), \$branchоценивается в пределах «обратный вызова». Это было довольно легко.

oleq
источник
7

Вы можете использовать функции, но сначала вам нужно их экспортировать:

export -f pbranch

Также, если вам нужны расширения синтаксиса bash, вы можете принудительно запустить оболочку bash:

git submodule foreach bash -c 'pbranch'
nschum
источник
5

Функция оболочки существует только внутри оболочки, где она определена. Точно так же метод Java существует только в экземпляре программы, где он определен, и так далее. Вы не можете вызвать функцию оболочки из другой программы, даже если эта программа оказывается другой оболочкой, которая запускается дочерним процессом исходной оболочки.

Вместо определения функции создайте pbranchотдельный скрипт. Поместите это в свой ПУТЬ.

#!/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 программирование Примечание: всегда ставят двойные кавычки подстановок переменных и команд замен: "$foo", "$(foo)", если вы не знаете , что вам нужно выйти из цитаты. Незащищенные замены интерпретируются как разделенные пробелами списки шаблонов глобуса, что почти никогда не требуется. Кроме того, не используйте backticks, по аналогичным причинам, используйте $(…)вместо этого. Здесь это на самом деле не имеет значения, потому что имена веток git не содержат специальных символов, а также потому, что [ -z $branch ]анализируется, [ -z ]что также верно, когда branchпусто. Но не заводите привычку опускать кавычки, это вернется и укусит вас.

Допустим, скрипт называется pbranch-submodule, вы можете запустить

git submodule foreach pbranch-submodule
Жиль "ТАК - перестань быть злым"
источник
И если вы назовете его git-pbranch-submodule, он может вести себя как встроенная команда git: git pbranch-submoduleили git submodule foreach git pbranch-submodule. (Обратите внимание, что foreach принимает команду оболочки, а не команду git.)
idbrii