将 git submodule foreach 与函数一起使用

ole*_*leq 11 bash git

我的缩进是有一个脚本,根据给定的分支更新所有 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
Run Code Online (Sandbox Code Playgroud)

但是在运行这个脚本时,会抛出错误:

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.
Run Code Online (Sandbox Code Playgroud)

我的猜测是git submodule foreach利用 eval (根据文档),我在这种情况下没有正确使用它。

有数十亿个示例说明如何将此命令与“内联回调”一起使用,但我找不到一个带有函数形式的回调的示例。知道如何解决这个问题吗?

ole*_*leq 9

我通过将函数放在引号内作为回调来解决我的问题:

#!/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;
"
Run Code Online (Sandbox Code Playgroud)

请注意,这些变量$1来自脚本的命名空间。“转义”之类的$\(bar),\$branch在“回调”中进行评估。这很容易。


小智 7

您可以使用函数,但您需要先导出它们:

export -f pbranch
Run Code Online (Sandbox Code Playgroud)

此外,如果您想要 bash 语法扩展,您可能需要强制启动 bash shell:

git submodule foreach bash -c 'pbranch'
Run Code Online (Sandbox Code Playgroud)


Gil*_*il' 5

shell 函数只存在于定义它的 shell 内部。同样,Java 方法只存在于定义它的程序实例中,依此类推。您不能从另一个程序调用 shell 函数,即使该程序恰好是由原始 shell 的子进程运行的另一个 shell。

与其定义一个函数,不如创建pbranch一个单独的脚本。把它放在你的 PATH 中。

#!/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"
Run Code Online (Sandbox Code Playgroud)

Shell 编程注意事项:始终在变量替换和命令替换周围放置双引号:"$foo", "$(foo)",除非您知道需要将引号排除在外。未受保护的替换被解释为以空格分隔的 glob 模式列表,这几乎是不需要的。另外,不要使用反引号,出于类似的原因,请$(…)改用。在这里,它实际上并不重要,因为 git 分支名称不包含特殊字符,并且因为[ -z $branch ]被解析为[ -z ]which 当branch为空时也是如此。但是不要养成省略引号的习惯,它会回来咬你。

假设脚本被调用pbranch-submodule,然后您可以运行

git submodule foreach pbranch-submodule
Run Code Online (Sandbox Code Playgroud)