【问题标题】:How to get the name of the current git branch into a variable in a shell script? [duplicate]如何将当前 git 分支的名称放入 shell 脚本中的变量中? [复制]
【发布时间】:2011-01-07 20:05:22
【问题描述】:

我是 shell 脚本的新手,无法弄清楚这一点。如果你不熟悉,命令 git branch 会返回类似

* develop
  master

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

git branch | grep "*"

我明白了:

* develop

正如预期的那样。

但是,当我运行时

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

test=`git branch | grep "*"`

然后

echo $test

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

然后下一步(一旦我们将“* develop”放入一个名为 test 的变量中),就是获取子字符串。会是以下吗?

currentBranch=${test:2} 

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

【问题讨论】:

  • 试试this blog post
  • 如果在星号周围使用单引号会怎样:'*' 而不是 "*"
  • @glenn 这不是扩展发生的地方,而是在回声中,正如 marco 已经详细阐述的那样。

标签: linux git bash shell ubuntu


【解决方案1】:

* 被扩展,你可以做的是使用 sed 代替 grep 并立即获取分支的名称:

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

Noufal Ibrahim 建议使用 git symbolic-ref 的版本

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

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

branch=${test:2}
echo $branch

这会像你想要的那样回显master

【讨论】:

  • 如果您使用其中的元素来更新您的答案,请提及我的答案。
  • 当然,很抱歉,我离开前更新很快,错过了归属。
  • 好的,所以我尝试了这两种方法,我必须说symbolic-ref 并不总是有效。例如:如果你签出一些旧的提交,它会抛出错误,而sed 命令给出类似(HEAD detached at 1qw23er)
  • 注意:即使分支名称中有正斜杠(例如,因为它是一个问题 URL),第一种技术仍然有效,为什么第二种技术在这种情况下只取最后一段。跨度>
【解决方案2】:

Noufal Ibrahim's answer 上扩展,使用--short 标志和git-symbolic-ref,无需大惊小怪sed

我一直在钩子中使用这样的东西,效果很好:

#!/bin/bash

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

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

输出“**** Running post-commit hook from branch master”

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

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 哈希的文件的相对路径。

【讨论】:

  • alias currentgitbranch='git symbolic-ref --short HEAD'
  • 这是最好的答案,使用 --short 可以得到你正在寻找的字符串。谢谢!
【解决方案3】:

我会在 git 核心中使用 git-symbolic-ref 命令。如果你说git-symbolic-ref HEAD,你会得到当前分支的名字。

【讨论】:

  • 在更高版本的 git 中,您将不得不使用 git symbolic-ref HEAD。
  • 您希望使用 --short 标志仅获取分支名称。举个例子:虽然在主分支上git-symbolic-ref HEAD 输出refs/heads/master 但`git-symbolic-ref --short HEAD` 只输出master
【解决方案4】:

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

示例:

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

我在 ~/scripts 中的一个名为 gpull 的文件中拥有它

编辑:

对于很多 CI 环境,他们会以“分离头”状态检查您的代码,所以我将使用:

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

【讨论】:

  • git describe --contains --all HEAD 没有给我当前分支,由带有git branch 的星号突出显示。
  • 这在 jenkins 构建脚本中很有用,谢谢
  • 注意:使用 git describe,如果你在 HEAD 上有一个标签,它会给你标签名称而不是分支名称。
【解决方案5】:

问题依赖于:

echo $test

实际上变量 test 包含一个由 shell 扩展的通配符。为了避免这种情况,只需用双引号保护 $test:

echo "$test"

【讨论】:

    【解决方案6】:

    禁用 subshel​​l glob 扩展,

    test=$(set -f; git branch)
    

    【讨论】:

    • 这不是扩展发生的地方,而是在回声中,正如 marco 已经阐述的那样。
    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 2014-02-28
    • 2011-09-08
    • 2023-03-09
    • 1970-01-01
    • 2011-06-12
    • 2011-12-25
    相关资源
    最近更新 更多