Linux 如何将当前git分支的名称放入shell脚本中的变量中?
我不熟悉shell脚本,无法理解这一点。如果您不熟悉,那么命令git branch将返回如下内容Linux 如何将当前git分支的名称放入shell脚本中的变量中?,linux,git,bash,shell,ubuntu,Linux,Git,Bash,Shell,Ubuntu,我不熟悉shell脚本,无法理解这一点。如果您不熟悉,那么命令git branch将返回如下内容 * develop master ,其中星号标记当前签出的分支。在终端中运行以下命令时: git branch | grep "*" 我得到: * develop 正如所料 然而,当我跑的时候 test=$(git branch | grep "*") 或 然后 echo $test ,结果只是目录中的文件列表。我们如何使test=“*开发”的价值 然后下一步(一旦我们将“*devel
* develop
master
,其中星号标记当前签出的分支。在终端中运行以下命令时:
git branch | grep "*"
我得到:
* develop
正如所料
然而,当我跑的时候
test=$(git branch | grep "*")
或
然后
echo $test
,结果只是目录中的文件列表。我们如何使test=“*开发”的价值
然后下一步(一旦我们将“*develope”变成一个名为test的变量),就是获取子字符串。那会是以下情况吗
currentBranch=${test:2}
我在玩那个子字符串函数,我经常遇到“坏替换”错误,不知道为什么。扩展了*后,您可以使用sed而不是grep,并立即获得分支的名称:
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
以及一个使用git符号ref的版本,正如努法尔·易卜拉欣所建议的那样
branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
为了详细说明扩展,(正如marco所做的那样,)扩展发生在echo中,当您使用包含*master
的$test
执行$test
时,*
将根据正常扩展规则进行扩展。要抑制此项,必须引用变量,如marco所示:echo“$test”
。或者,如果在回显之前去掉星号,一切都会好的,例如,echo${test:2}
只回显master
。或者,您可以按照您的建议重新分配:
branch=${test:2}
echo $branch
这将根据您的需要回显
master
。我将在git内核中使用git symbolic ref
命令。如果您说git symbolic ref HEAD
,您将得到当前分支的名称。禁用子shell全局扩展
test=$(set -f; git branch)
问题在于:
echo $test
事实上,变量test包含一个通配符,该通配符由shell展开。要避免这种情况,请使用双引号保护$test:
echo "$test"
继续展开,将--short
标志与git symbolic ref
一起使用,无需对sed
大惊小怪
我一直在hooks中使用类似的东西,效果很好:
#!/bin/bash
branch=$(git symbolic-ref --short HEAD)
echo
echo "**** Running post-commit hook from branch $branch"
echo
输出“****从分支主节点运行提交后钩子”
请注意,git symbolic ref
仅在存储库中工作。幸运的是,.git/HEAD
,作为git早期的一个遗留版本,包含了相同的符号ref。如果您想获得多个git存储库的活动分支,而不需要遍历目录,您可以使用如下bash one行文:
for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} : ${branch##*/}; done
其输出类似于:
repo1 : master
repo2 : dev
repo3 : issue12
如果您想更进一步,则.git/HEAD
中包含的完整ref也是包含分支上次提交的SHA-1散列的文件的相对路径 我用这个
git descripe--contains--all HEAD
在我的git助手脚本中
例如:
#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname
我在~/scripts
编辑:
对于许多CI环境,他们会以“分离头”状态签出您的代码,因此我将使用:
BRANCH=$(\
git for-each-ref \
--format='%(objectname) %(refname:short)' refs/heads \
| awk "/^$(git rev-parse HEAD)/ {print \$2}"\
)
如果您使用其中的元素更新您的答案,请您提及我的答案,这将是非常礼貌的。当然,我很抱歉,我在离开之前更新得很快,错过了属性。好的,所以我尝试了这两种方法,我必须说,
symbolic ref
并不总是有效。例如:如果您签出一些旧的提交,它会抛出错误,而sed
命令会给出类似于(头在1qw23er处分离)
的内容。注意:第一种技术即使分支名称中有正向斜杠(例如,因为它是一个问题URL),也会起作用,为什么在这种情况下第二个只取最后一段。这不是扩展发生的地方,而是在回音中,正如marco已经详细阐述的那样。在git的更高版本中,您将不得不使用git symbolic ref HEAD。您希望使用--short标志只获取分支名称。例如:在主分支上,git symbolic ref HEAD
outputsrefs/heads/master
但是`git symbolic ref--short HEAD`只输出master
试试。如果在星号周围使用单引号:“*”
而不是“*”
@glenn这不是扩展发生的地方,正如marco已经详细阐述的那样,它在echo中。git descripe--contains--all HEAD
并没有给我当前的分支,正如用git branch
突出显示的那样。这在jenkins构建脚本中很有用,谢谢注意:用git descripe,如果头部有一个标记,它将为您提供标记名,而不是分支名。alias currentgitbranch='git symbolic ref--short HEAD'
这是最好的答案,使用--short
可以得到您正在寻找的字符串。谢谢
BRANCH=$(\
git for-each-ref \
--format='%(objectname) %(refname:short)' refs/heads \
| awk "/^$(git rev-parse HEAD)/ {print \$2}"\
)