This question already has an answer here:
这个问题已经有了答案:
- How to programmatically determine the current checked out Git branch 20 answers
- 如何以编程方式确定当前签出的Git分支20的答案
I am new to shell scripting and can't figure this out. If you are unfamiliar, the command git branch returns something like
我是shell脚本的新手,我不知道这一点。如果您不熟悉,命令git分支会返回一些类似的东西。
* develop
master
, where the asterisk marks the currently checked out branch. When I run the following in the terminal:
,星号标记当前签出的分支。当我在终端机上运行如下:
git branch | grep "*"
I get:
我得到:
* develop
as expected.
像预期的那样。
However, when I run
然而,当我运行
test=$(git branch | grep "*")
or
或
test=`git branch | grep "*"`
And then
然后
echo $test
, the result is just a list of files in the directory. How do we make the value of test="* develop"?
,结果就是目录中的文件列表。如何使测试的值="* development "?
Then the next step (once we get "* develop" into a variable called test), is to get the substring. Would that just be the following?
然后下一步(一旦我们将“*”开发成一个名为test的变量),就是获取子字符串。会是这样吗?
currentBranch=${test:2}
I was playing around with that substring function and I got "bad substitution" errors a lot and don't know why.
我在玩子串函数,我有很多错误的替换错误,不知道为什么。
6 个解决方案
#1
61
The * is expanded, what you can do is use sed instead of grep and get the name of the branch immediately:
扩展了*,您可以使用sed而不是grep,并立即获得分支的名称:
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
And a version using git symbolic-ref, as suggested by Noufal Ibrahim
和一个版本使用git symbolic-ref,由Noufal Ibrahim建议
branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
To elaborate on the expansion, (as marco already did,) the expansion happens in the echo, when you do echo $test
with $test containing "* master" then the * is expanded according to the normal expansion rules. To suppress this one would have to quote the variable, as shown by marco: echo "$test"
. Alternatively, if you get rid of the asterisk before you echo it, all will be fine, e.g. echo ${test:2}
will just echo "master". Alternatively you could assign it anew as you already proposed:
要详细说明扩展,(如marco所做的),扩展发生在echo中,当您使用包含“* master”的$test进行echo $test时,*会根据正常的扩展规则进行扩展。要抑制这个变量,必须引用变量,如marco: echo“$test”所示。或者,如果您在回显之前去掉了星号,那么一切都会好起来,例如echo ${test:2}只回显“master”。或者,你可以按照你已经提出的建议重新分配它:
branch=${test:2}
echo $branch
This will echo "master", like you wanted.
这将呼应“master”,就像你想要的那样。
#2
49
Expanding on Noufal Ibrahim's answer, use the --short
flag with git-symbolic-ref
, no need to fuss with sed
.
根据Noufal Ibrahim的回答,使用带有git-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
That outputs "**** Running post-commit hook from branch master"
输出“****运行后分支主挂起”
Note that git-symbolic-ref
only works if you're in a repository. Luckily .git/HEAD
, as a leftover from Git's early days, contains the same symbolic ref. If you want to get the active branch of several git repositories, without traversing directories, you could use a bash one-liner like this:
请注意,git-symbolic-ref仅在存储库中才能工作。幸运的是,Git /HEAD作为Git早期遗留的内容,包含相同的符号引用。
for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} : ${branch##*/}; done
Which outputs something like:
输出类似:
repo1 : master
repo2 : dev
repo3 : issue12
If you want to go further, the full ref contained in .git/HEAD
is also a relative path to a file containing the SHA-1 hash of the branch's last commit.
如果您想更进一步,.git/HEAD中包含的完整的ref也是包含分支最后提交的SHA-1散列的文件的相对路径。
#3
26
I would use the git-symbolic-ref
command in the git core. If you say git-symbolic-ref HEAD
, you will get the name of the current branch.
我将在git核心中使用git- symbolicref命令。如果您使用git-symbolic-ref头,您将得到当前分支的名称。
#4
11
I use this git describe --contains --all HEAD
in my git helper scripts
我使用git描述——包含——在我的git助手脚本中
example:
例子:
#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname
I have that in a file called gpull
in ~/scripts
我有一个叫做gpull in ~/scripts的文件
#5
7
The problem relies on:
问题依赖于:
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:
实际上,变量测试包含由shell展开的通配符。为了避免这种情况,只需使用双引号保护$test:
echo "$test"
#6
1
disable subshell glob expansion,
禁用子shell水珠扩张,
test=$(set -f; git branch)
#1
61
The * is expanded, what you can do is use sed instead of grep and get the name of the branch immediately:
扩展了*,您可以使用sed而不是grep,并立即获得分支的名称:
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
And a version using git symbolic-ref, as suggested by Noufal Ibrahim
和一个版本使用git symbolic-ref,由Noufal Ibrahim建议
branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
To elaborate on the expansion, (as marco already did,) the expansion happens in the echo, when you do echo $test
with $test containing "* master" then the * is expanded according to the normal expansion rules. To suppress this one would have to quote the variable, as shown by marco: echo "$test"
. Alternatively, if you get rid of the asterisk before you echo it, all will be fine, e.g. echo ${test:2}
will just echo "master". Alternatively you could assign it anew as you already proposed:
要详细说明扩展,(如marco所做的),扩展发生在echo中,当您使用包含“* master”的$test进行echo $test时,*会根据正常的扩展规则进行扩展。要抑制这个变量,必须引用变量,如marco: echo“$test”所示。或者,如果您在回显之前去掉了星号,那么一切都会好起来,例如echo ${test:2}只回显“master”。或者,你可以按照你已经提出的建议重新分配它:
branch=${test:2}
echo $branch
This will echo "master", like you wanted.
这将呼应“master”,就像你想要的那样。
#2
49
Expanding on Noufal Ibrahim's answer, use the --short
flag with git-symbolic-ref
, no need to fuss with sed
.
根据Noufal Ibrahim的回答,使用带有git-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
That outputs "**** Running post-commit hook from branch master"
输出“****运行后分支主挂起”
Note that git-symbolic-ref
only works if you're in a repository. Luckily .git/HEAD
, as a leftover from Git's early days, contains the same symbolic ref. If you want to get the active branch of several git repositories, without traversing directories, you could use a bash one-liner like this:
请注意,git-symbolic-ref仅在存储库中才能工作。幸运的是,Git /HEAD作为Git早期遗留的内容,包含相同的符号引用。
for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} : ${branch##*/}; done
Which outputs something like:
输出类似:
repo1 : master
repo2 : dev
repo3 : issue12
If you want to go further, the full ref contained in .git/HEAD
is also a relative path to a file containing the SHA-1 hash of the branch's last commit.
如果您想更进一步,.git/HEAD中包含的完整的ref也是包含分支最后提交的SHA-1散列的文件的相对路径。
#3
26
I would use the git-symbolic-ref
command in the git core. If you say git-symbolic-ref HEAD
, you will get the name of the current branch.
我将在git核心中使用git- symbolicref命令。如果您使用git-symbolic-ref头,您将得到当前分支的名称。
#4
11
I use this git describe --contains --all HEAD
in my git helper scripts
我使用git描述——包含——在我的git助手脚本中
example:
例子:
#!/bin/bash
branchname=$(git describe --contains --all HEAD)
git pull --rebase origin $branchname
I have that in a file called gpull
in ~/scripts
我有一个叫做gpull in ~/scripts的文件
#5
7
The problem relies on:
问题依赖于:
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:
实际上,变量测试包含由shell展开的通配符。为了避免这种情况,只需使用双引号保护$test:
echo "$test"
#6
1
disable subshell glob expansion,
禁用子shell水珠扩张,
test=$(set -f; git branch)