如何将当前git分支的名称转换为shell脚本中的变量?

Ben*_*Ben 69 linux git bash shell ubuntu

我是shell脚本的新手,无法解决这个问题.如果您不熟悉,命令git branch会返回类似的内容

* develop
  master
Run Code Online (Sandbox Code Playgroud)

,星号标记当前签出的分支.当我在终端中运行以下内容时:

git branch | grep "*"
Run Code Online (Sandbox Code Playgroud)

我明白了:

* develop
Run Code Online (Sandbox Code Playgroud)

正如所料.

但是,当我跑

test=$(git branch | grep "*")
Run Code Online (Sandbox Code Playgroud)

要么

test=`git branch | grep "*"`
Run Code Online (Sandbox Code Playgroud)

然后

echo $test
Run Code Online (Sandbox Code Playgroud)

,结果只是目录中的文件列表.我们如何使test ="*develop"的价值?

然后下一步(一旦我们将"*develop"变成一个名为test的变量),就是得到子串.这只是以下几点吗?

currentBranch=${test:2} 
Run Code Online (Sandbox Code Playgroud)

我正在玩那个子串函数,我得到了很多"坏替换"错误,不知道为什么.

wic*_*ich 87

*被扩展,你可以做的是使用sed而不是grep并立即得到分支的名称:

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

还有一个使用git symbolic-ref的版本,正如Noufal Ibrahim所建议的那样

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

为了详细说明扩展(如marco已经做的那样),扩展发生在echo中,当你echo $test使用$ test包含"*master"时,*会根据正常的扩展规则进行扩展.要压制这个,就必须引用变量,如marco所示:echo "$test".或者,如果你在回音之前摆脱了星号,一切都会好的,例如echo ${test:2}只会回应"主人".或者,您可以按照您的建议重新分配:

branch=${test:2}
echo $branch
Run Code Online (Sandbox Code Playgroud)

这将像你想要的那样回应"主人".

  • 如果您使用其中的元素来更新您的答案,那么提及我的答案将是礼貌的. (2认同)
  • 好的,所以我尝试了这两种方法,我必须说`symbolic-ref` 并不总是有效。例如:如果你检出一些旧的提交,它会抛出错误,而 `sed` 命令给出类似 `(HEAD detached at 1qw23er)` (2认同)
  • 注意:即使分支名称中有正斜杠(例如,因为它是一个问题 URL),第一种技术也能工作,为什么在这种情况下第二种技术只采用最后一段。 (2认同)

joe*_*ler 82

扩展Noufal Ibrahim的答案,使用--short旗帜git-symbolic-ref,无需大惊小怪sed.

我一直在钩子中使用这样的东西,它运作良好:

#!/bin/bash

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

echo
echo "**** Running post-commit hook from branch $branch"
echo
Run Code Online (Sandbox Code Playgroud)

输出"****从分支主机运行post-commit hook"

请注意,git-symbolic-ref仅当您在存储库中时才有效.幸运的是.git/HEAD,作为Git早期的遗留物,它包含了相同的符号引用.如果你想获得几个git存储库的活动分支,而不遍历目录,你可以像这样使用bash单行:

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

哪个输出如下:

repo1 : master  
repo2 : dev  
repo3 : issue12
Run Code Online (Sandbox Code Playgroud)

如果你想更进一步,包含的完整ref .git/HEAD也是包含分支最后一次提交的SHA-1哈希的文件的相对路径.

  • `alias currentgitbranch ='git symbolic-ref --short HEAD'` (4认同)
  • 这是最好的答案,使用 `--short` 可以得到你正在寻找的字符串。谢谢! (2认同)

Nou*_*him 30

我会git-symbolic-ref在git核心中使用该命令.如果你说git-symbolic-ref HEAD,你将获得当前分支的名称.

  • 在更高版本的git中,您将不得不使用git symbolic-ref HEAD. (13认同)
  • 您希望使用--short标志仅获取分支名称。例如:在master分支上,git-symbolic-ref HEAD输出refs / heads / master,而git-symbolic-ref --short HEAD仅输出master。 (4认同)

Nul*_*uli 14

git describe --contains --all HEAD 在我的git helper脚本中使用它

例:

#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname
Run Code Online (Sandbox Code Playgroud)

我把它放在一个名为的文件gpull~/scripts

编辑:

对于很多CI环境,他们会以"独立头"状态检查你的代码,所以我将使用:

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


mar*_*rco 7

问题依赖于:

echo $test
Run Code Online (Sandbox Code Playgroud)

事实上,变量测试包含一个由shell扩展的通配符.为避免这种情况,请使用双引号保护$ test:

echo "$test"
Run Code Online (Sandbox Code Playgroud)