如何以编程方式确定当前签出的Git分支
在Unix或GNU脚本环境(例如Linux发行版,Cygwin,OSX)中,确定当前在工作目录中检出哪个Git分支的最佳方法是什么?
这种技术的一个用途就是自动标记一个发行版(就像svnversion
会用Subversion一样)。
请参阅我的相关问题: 如何以编程方式确定Git签出是否是标记,如果是,则标记名称是什么?
正确的解决scheme是在contrib / completions / git-completion.bash中查看__git_ps1
bash提示符。 删除所有额外的东西,如select如何描述分离的HEAD情况,即当我们在未命名的分支时,它是:
branch_name="$(git symbolic-ref HEAD 2>/dev/null)" || branch_name="(unnamed branch)" # detached HEAD branch_name=${branch_name##refs/heads/}
git symbolic-ref用于从符号引用中提取完全限定的分支名称; 我们将它用于HEAD,这是目前检出分支。
备用解决scheme可以是:
branch_name=$(git symbolic-ref -q HEAD) branch_name=${branch_name##refs/heads/} branch_name=${branch_name:-HEAD}
在最后一行我们处理分离的HEAD情况,用“HEAD”来表示这种情况。
添加11-06-2013
Junio C. Hamano(git maintainer)博客文章,从2013年6月10日起以编程方式检查当前分支 ,更详细地解释了whys (和hows)。
有没有人看到有什么不对,只是要求Git描述你所在的分支?
git rev-parse --symbolic-full-name --abbrev-ref HEAD
这可以在$()中使用,并在Bash,Powershell,Perl等中轻松传递。如果您在提交时有多个分支,并且如果您当前不在分支上,用“HEAD”回复。
或者,您可以使用
git symbolic-ref --short -q HEAD
哪个会给你相同的输出,但是如果你被分离,它将不会返回任何东西。 如果你想在分离的时候想要一个错误,那么这个是有用的,只需要删除-q。
你可以使用git name-rev --name-only HEAD
从这个答案: https : //stackoverflow.com/a/1418022/605356 :
$ git rev-parse --abbrev-ref HEAD master
显然可以使用Git 1.6.3或更新的版本。
试试:
git symbolic-ref --short -q HEAD
或者你用git branch
用--no-color
强制简单的纯string输出:
git branch --no-color
使用正则expression式模式( -E
)grep你可以检查是否存在字符'*':
git branch --no-color | grep -E '^\*'
其结果类似于:
* currentBranch
您可以使用下一个选项:
sed 's/\*[^az]*//g' cut -d ' ' -f 2 awk '{print $2}'
例如:
git branch --no-color | grep -E '^\*' | sed 's/\*[^az]*//g' git branch --no-color | grep -E '^\*' | sed cut -d ' ' -f 2 git branch --no-color | grep -E '^\*' | awk '{print $2}'
如果存在一个错误,你不能使用默认值:
cmd || echo 'defualt value';
全部进入bash函数:
function get_branch() { git branch --no-color | grep -E '^\*' | awk '{print $2}' \ || echo "default_value" # or # git symbolic-ref --short -q HEAD || echo "default_value"; }
使用:
branch_name=`get_branch`; echo $branch_name;
使接受的答案适应Windows PowerShell的:
Split-Path -Leaf (git symbolic-ref HEAD)
这个在bash文件中为我工作。
git branch | grep '^*' | sed 's/* //' ################bash file################### #!/bin/bash BRANCH=$(git branch | grep '^*' | sed 's/* //' ) echo $BRANCH
这个为我工作。 如果你想要一个简单的string, --no-color
部分是,或者可以是重要的。
git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
这是我做的:
git branch | sed --quiet 's/* \(.*\)/\1/p'
输出结果如下所示:
$ git branch | sed --quiet 's/* \(.*\)/\1/p' master $
我正在尝试这里最简单,最明显的方法:
git status | grep "On branch" | cut -c 11-
我发现了两个非常简单的方法来做到这一点:
$ git status | head -1 | cut -d ' ' -f 4
和
$ git branch | grep "*" | cut -d ' ' -f 2
有人提到用bashless于三个任务做…这样一些混乱的控制stream如何:
branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"
如果您使用的是旧的NT命令行,则可以使用以下命令:
@for /f "usebackq" %i in (`git symbolic-ref -q HEAD`) do @echo %~ni
要在batch file中使用,你必须加倍%:
@for /f "usebackq" %%i in (`git symbolic-ref -q HEAD`) do @echo %%~ni
这是我的解决scheme,适合在PS1中使用,或自动标记发布
如果您在分支机构签出,则会获得分行名称。
如果你在一个刚刚开始的git项目中,你只要得到'@'
如果你是无头的,你会得到一个相对于某个分支或标签的好名字,在名字前面有一个“@”。
如果你是无头的,而不是一个分支或标签的祖先,你只需要短的SHA1。
function we_are_in_git_work_tree { git rev-parse --is-inside-work-tree &> /dev/null } function parse_git_branch { if we_are_in_git_work_tree then local BR=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD 2> /dev/null) if [ "$BR" == HEAD ] then local NM=$(git name-rev --name-only HEAD 2> /dev/null) if [ "$NM" != undefined ] then echo -n "@$NM" else git rev-parse --short HEAD 2> /dev/null fi else echo -n $BR fi fi }
如果你愿意的if we_are_in_git_work_tree
你可以删除if we_are_in_git_work_tree
位。 我只是在PS1中的另一个函数中使用它,您可以在这里完整地查看: PS1行与git当前分支和颜色
使用–porcelain可以轻松parsing向后兼容的输出:
git status --branch --porcelain | grep '##' | cut -c 4-
从文档:
瓷器格式类似于短格式,但保证不会在Git版本之间或基于用户configuration的后向不兼容的方式改变。 这使得它非常适合通过脚本parsing。
我发现调用git相当慢(任何子命令),尤其是对于更新提示。 时间在回购的根目录内的.1和.2秒之间,以及回购之外,在顶尖的机器上(raid 1,8GB内存,8个硬件线程)超过0.2秒。 它确实运行Cygwin。
所以我为速度写了这个脚本:
#!/usr/bin/perl $cwd=$ENV{PWD}; #`pwd`; chomp $cwd; while (length $cwd) { -d "$cwd/.git" and do { -f "$cwd/.git/HEAD" and do { open IN, "<", "$cwd/.git/HEAD"; $_=<IN>; close IN; s@ref: refs/heads/@@; print $_; }; exit; }; $cwd=~s@/[^/]*$@@; }
可能需要一些调整。
这是一个解决scheme。 如果你把它添加到你的.bashrc中,它会在控制台中显示当前分支。
# git branch parse_git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /' } $PS1="\$(parse_git_branch)$PS1"
但是它非常有限。 但是有一个叫做git sh的伟大项目,正是这样做(还有更多)。
如果你正在使用gradle,
“`
def gitHash = new ByteArrayOutputStream() project.exec { commandLine 'git', 'rev-parse', '--short', 'HEAD' standardOutput = gitHash } def gitBranch = new ByteArrayOutputStream() project.exec { def gitCmd = "git symbolic-ref --short -q HEAD || git branch -rq --contains "+getGitHash()+" | sed -e '2,\$d' -e 's/\\(.*\\)\\/\\(.*\\)\$/\\2/' || echo 'master'" commandLine "bash", "-c", "${gitCmd}" standardOutput = gitBranch }
“`
如果你是一个独立的头(即你已经签出一个版本),并从git状态输出,如
HEAD detached at v1.7.3.1
而你想发行的版本,我们使用下面的命令…
git status --branch | head -n1 | tr -d 'A-Za-z: '
这返回1.7.3.1,我们用parameters.yml(Symfony)replace
# RevNum=`svn status -u | grep revision | tr -d 'A-Za-z: '` # the old SVN version RevNum=`git status --branch | head -n1 | tr -d 'A-Za-z: '` # Git (obvs) sed -i "/^ app_version:/c\ app_version:$RevNum" app/config/parameters.yml
希望这有助于:)显然,如果您的分支名称中包含非数字,则需要更改tr命令的参数。