如何将当前 git 分支的名称放入 shell 脚本中的变量中?

我是 shell 脚本编程的新手,无法理解这一点。如果您不熟悉,命令 git 分支将返回类似于

* develop
master

,其中星号标记当前签出的分支。当我在终端中运行以下命令时:

git branch | grep "*"

我得到了:

* develop

不出所料。

但是,当我跑的时候

test=$(git branch | grep "*")

或者

test=`git branch | grep "*"`

然后

echo $test

,结果只是目录中的文件列表。我们如何确定 test = “ * development”的值?

然后下一步(一旦我们将“ * development”转换为名为 test 的变量)是获取子字符串。是不是只有以下这些?

currentBranch=${test:2}

我一直在玩那个子字符串函数,我得到了“坏替换”错误很多,不知道为什么。

80952 次浏览

如果 * 被展开,您可以使用 sed 代替 grep 并立即获取分支的名称:

branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')

以及 Noufal Ibrahim 建议的使用 git 符号引用的版本

branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

为了详细说明展开,(正如 Marco 已经做的那样)展开发生在回声中,当你用包含 * master$testecho $test时,那么 *将按照正常的展开规则展开。要抑制这个变量,必须引用变量,如 marco: echo "$test"所示。或者,如果你在回显星号之前去掉它,一切都会好起来,例如,echo ${test:2}将只回显 master。或者你可以按照你的建议重新分配:

branch=${test:2}
echo $branch

这将回声 master,如你所愿。

我将在 git 核心中使用 git-symbolic-ref命令。如果输入 git-symbolic-ref HEAD,就会得到当前分支的名称。

禁用子壳程序的全局扩展,

test=$(set -f; git branch)

问题在于:

echo $test

In fact the variable test contains a wildcard which is expanded by the shell. To avoid that just protect $test with double quotes:

echo "$test"

Noufal Ibrahim 的回答上展开,使用 --shortgit-symbolic-ref的标志,不需要与 sed大惊小怪。

I've been using something like this in hooks and it works well:

#!/bin/bash


branch=$(git symbolic-ref --short HEAD)


echo
echo "**** Running post-commit hook from branch $branch"
echo

输出“ * * * * 从分支主机运行提交后挂钩”

请注意,git-symbolic-ref只有在存储库中才能工作。幸运的是,作为 Git 早期遗留下来的 .git/HEAD包含相同的符号 ref。如果您希望获得几个 git 存储库的活动分支,而不需要遍历目录,那么您可以使用 bash 一行程序,如下所示:

for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} :  ${branch##*/}; done

其输出类似于:

repo1 : master
repo2 : dev
repo3 : issue12

如果您想进一步了解,.git/HEAD中包含的完整引用也是包含分支上次提交的 SHA-1散列的文件的相对路径。

我用这个 git describe --contains --all HEAD 在我的 git 助手脚本中

例如:

#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname

我在 ~/scriptsgpull文件里有这个

Edit:

对于许多 CI 环境,他们将以“分离头”状态检出您的代码,因此我将使用:

BRANCH=$(\
git for-each-ref \
--format='%(objectname) %(refname:short)' refs/heads \
| awk "/^$(git rev-parse HEAD)/ {print \$2}"\
)