【问题标题】:How to get the current branch name in Git?如何在 Git 中获取当前分支名称?
【发布时间】:2011-09-08 21:20:15
【问题描述】:

我来自 Subversion 背景,当我有一个分支时,我知道我正在处理“这些工作文件指向这个分支”。

但使用 Git 时,我不确定何时在 NetBeans 或 Notepad++ 中编辑文件,它是绑定到主分支还是其他分支。

git 在 bash 中没有问题,它告诉我我在做什么。

【问题讨论】:

标签: git branch git-branch


【解决方案1】:
git branch

应该显示你的 repo 的所有本地分支。加星号的分支是您当前的分支。

如果您只想检索您所在分支的名称,您可以这样做:

git rev-parse --abbrev-ref HEAD

或使用 Git 2.22 及更高版本:

git branch --show-current

【讨论】:

  • 但这对我使用 Notepad++ 和 Netbeans 没有帮助。只是 git bash (和可能的 Vim),我提到了这一点。我正在尝试使用其他没有命令行的 Ide 和文本编辑器。
  • 如果您愿意在 Eclipse 中工作,有一个名为“eGit”的程序,它有一个 GUI,可以告诉您其中所有 repos 的当前分支。否则,我不知道..您将受制于您想要使用的与您选择的程序兼容的任何插件的创建者(如果有的话)。
  • 在执行git checkout --orphan foo 之后,git branch 无法显示分支foo。而git symbolic-ref HEAD 建议另一个答案有效。
  • 否决,我们只希望当前分支作为标准输出,而不是所有分支
  • git rev-parse --abbrev-ref HEAD 到底是做什么的?我以前使用git describe --contains --all HEAD,但有时会中断,我不太确定为什么。
【解决方案2】:

您可以在 Linux 上的存储库目录中输入命令行(控制台):

$ git status

你会看到一些文字,其中类似于:

...
On branch master
...

这意味着您目前在master 分支上。如果您当时正在编辑任何文件并且它位于同一个本地存储库(包含受 Git 版本控制管理的文件的本地目录),那么您正在编辑此分支中的文件。

【讨论】:

  • 根据您想要执行的操作,您可以使用git status 并使用git status | head -1 仅获取第一行输出,这会产生类似# On branch master 的内容。我相信版本差异也需要考虑在内。
  • @JoshPinter:您也可以使用git status | grep 'On branch',它应该具有相同的效果(应该,并不意味着如果您的Git版本显示不同就会有)。或git branch | grep '*',它将显示分支的名称,并以星号开头。
  • 是的,这也很有效,而且可能更灵活。我在开发 Rails 应用程序中仅显示分支名称的最终结果是:<tick>git status | head -1<tick>.gsub('# On branch ', '')
  • git status 如果管理的文件很多,可能需要很长时间才能返回值。
  • 是的,如果你想在网页上打印分支,例如,git status 可能会消耗整个页面的生成时间。
【解决方案3】:

为什么不使用 git-aware shell prompt,它会告诉你当前分支的名称? git status 也有帮助。


contrib/ 中的git-prompt.sh 是如何做到的(git 版本 2.3.0),如__git_ps1 辅助函数中所定义:

  1. 首先,如果检测到 rebase 正在进行,则存在特殊情况。 Git 在 rebase 过程中使用未命名的分支(分离的 HEAD)使其原子化,并将原始分支保存在其他地方。

  2. 如果.git/HEAD 文件是符号链接(非常罕见的情况,来自Git 的古代历史),它使用git symbolic-ref HEAD 2>/dev/null

  3. 否则,它读取.git/HEAD 文件。后续步骤取决于其内容:

    • 如果此文件不存在,则没有当前分支。如果存储库是裸露的,这通常会发生。

    • 如果它以'ref: ' 前缀开头,那么.git/HEAD 是symref(符号引用),我们在正常分支上。去掉这个前缀得到全名,去掉refs/heads/得到当前分支的简称:

      b="${head#ref: }"
      # ...
      b=${b##refs/heads/}
      
    • 如果不是以'ref: '开头,那么它就是分离的HEAD(匿名分支),直接指向某个提交。使用git describe ... 以人类可读的形式编写当前提交。

希望对你有帮助。

【讨论】:

  • 如果你正在开发一个支持 git 的 shell 提示符,你应该使用这里的哪个答案?海龟一路向下。
  • 这似乎是在做git describe --contains --all HEAD,我目前在此页面的其他地方没有看到。我相信你知道,StackOverflow 上不建议使用仅链接的答案。
  • @tripleee:我已经添加了一个解释git-prompt.sh(又名__git_ps1)是如何做到的......
【解决方案4】:
#!/bin/bash
function git.branch {
  br=`git branch | grep "*"`
  echo ${br/* /}
}
git.branch

【讨论】:

    【解决方案5】:

    很简单,我把它放在一个衬里(bash)中

    git branch | sed -n '/\* /s///p'
    

    (来源:有限赎罪)

    当我在那里的时候,一个班轮得到远程跟踪分支(如果有的话)

    git rev-parse --symbolic-full-name --abbrev-ref @{u}
    

    【讨论】:

    • 斜线太多! :) sed -n 's/\* //p' 成功了。虽然我倾向于偏执,所以我会用sed -n 's/^\* //p'来锚定它。
    【解决方案6】:

    您还拥有git symbolic-ref HEAD,它显示了完整的参考规范。

    在 Git v1.8 及更高版本中仅显示分支名称(感谢 Greg 指出):

    git symbolic-ref --short HEAD
    

    在 Git v1.7+ 上,您还可以:

    git rev-parse --abbrev-ref HEAD
    

    如果您在一个分支上,两者都应该给出相同的分支名称。如果你是超然的,答案会有所不同。

    注意:

    在较早的客户端上,这似乎可行:

    git symbolic-ref HEAD | sed -e "s/^refs\/heads\///"
    

    Darien 2014 年 3 月 26 日

    【讨论】:

    • 与所有其他答案一样,当您处于“分离 HEAD”状态时,这不起作用
    • @CarlosCampderrós:如果您处于分离的 HEAD 状态,则没有当前分支之类的东西。毕竟,您所在的提交可能会被零个、一个或多个分支访问。
    • 当没有 HEAD 时,这会在空的 git 存储库中产生问题
    • 使用 git 版本 2.4.4 git rev-parse --abbrev-ref HEAD 在您处于分离状态时显示 HEAD
    • 最好的答案仍然是git symbolic-ref HEAD | sed -e "s/^refs\/heads\///" ,因为它在处于分离状态时会显示一个类似HEAD detached at a63917f 的字符串,这与其他答案不显示任何内容或 HEAD 不同。这很重要。
    【解决方案7】:

    在 Netbeans 中,确保启用版本控制注释(查看 -> 显示版本控制 标签)。然后您可以在项目名称旁边看到分支名称。

    http://netbeans.org/bugzilla/show_bug.cgi?id=213582

    【讨论】:

    • 启用版本注释后,您只需将鼠标悬停在项目(或文件或收藏夹)文件夹上即可查看当前分支。
    【解决方案8】:

    要显示您所在的当前分支,而不列出其他分支,您可以执行以下操作:

    git rev-parse --abbrev-ref HEAD
    

    参考:

    【讨论】:

    • @ChrisNelson,因为它只显示当前分支,而不是所有分支的长列表。
    • 好一个,遗憾的是,如果您处于“分离 HEAD”状态(它只是输出“HEAD”,完全没用),它就不起作用。
    • 我猜从 git 内部结构来看,如果您处于“分离 HEAD”状态,则不会跟踪它所属的分支,因为 git branch 显示 * (no branch),这也是无用的.. .
    • "git symbolic-ref --short HEAD" 也适用于同样的目的
    • git rev-parse --abbrev-ref HEAD 2>/dev/null /dev/null 部分可防止您在刚刚创建尚未 HEAD 的新存储库时看到错误。
    【解决方案9】:

    这个呢?

    { git symbolic-ref HEAD 2> /dev/null || git rev-parse --short HEAD 2> /dev/null } | sed "s#refs/heads/##"
    

    【讨论】:

    • 更好的答案,因为它可以很好地处理分离的 HEAD 案例。
    • 看来你应该使用 () 而不是 { } 来包装 git 命令
    • @Pat 没有必要为此生成一个单独的子shell,就像 ( ) 那样。 { } 很好,除了你需要添加一个 ;或 } 之前的换行符。实际上,除非您需要对命令进行分组,否则您可以完全不使用 { }。
    • 难道symbolic-ref 部分也需要--short 以避免在分支名称前加上refs/heads/ 前缀吗?
    【解决方案10】:
    git branch | grep "*" | sed "s/* //" | awk '{printf $0}' | pbcopy
    

    直接将结果复制到粘贴板。感谢@olivier-refalo 的开始……

    【讨论】:

    • 呃。 grep | sed | awk 通常可以很容易地重构为一个 awk 脚本。 (无论如何,printf $0 有什么意义?修剪最后的换行符?tr -d '\n' 做得更好。)另外,grep "*" 在技术上是一个语法错误。无论如何,git branch | awk '/\*/ { gsub(/\* /,""); printf $0 } | pbcopy 是对脚本的简单重构。
    • ... 和 git branch | awk '/^\*/ { printf $2 }'(如上文所述)要好得多。
    • sedawk 便宜:git branch | sed -ne '/^\* / { s///; p; q }'
    【解决方案11】:
    git symbolic-ref -q --short HEAD
    

    我在需要当前分支名称的脚本中使用它。它将向您显示当前对 HEAD 的简短符号引用,这将是您当前的分支名称。

    【讨论】:

    • 谢谢,效果很好! - 我还在我的脚本中添加了“-C path_to_folder”。
    • 这是一个不错的解决方案,因为使用 -q 选项它会在“分离 HEAD”状态下返回错误代码,但不会将任何内容打印到 stderr。
    • 这是唯一一个在没有任何提交的情况下对我有用的新回购解决方案
    【解决方案12】:

    作为我自己的参考(但它可能对其他人有用)我概述了这个线程中提到的大多数(基本命令行)技术,每个技术都适用于几个用例:HEAD 是(指向):

    • 本地分支(主)
    • 远程跟踪分支,与本地分支同步(origin/master 与 master 提交相同)
    • 远程跟踪分支,与本地分支不同步(origin/feature-foo)
    • 标签 (v1.2.3)
    • 子模块(在子模块目录中运行)
    • 一般分离头(以上都不是)

    结果:

    • git branch | sed -n '/\* /s///p'
      • 本地分支:master
      • 远程跟踪分支(同步):(detached from origin/master)
      • 远程跟踪分支(不同步):(detached from origin/feature-foo)
      • 标签:(detached from v1.2.3)
      • 子模块:(HEAD detached at 285f294)
      • 通用分离头:(detached from 285f294)
    • git status | head -1
      • 本地分支:# On branch master
      • 远程跟踪分支(同步):# HEAD detached at origin/master
      • 远程跟踪分支(不同步):# HEAD detached at origin/feature-foo
      • 标签:# HEAD detached at v1.2.3
      • 子模块:# HEAD detached at 285f294
      • 通用分离头:# HEAD detached at 285f294
    • git describe --all
      • 本地分支:heads/master
      • 远程跟踪分支(同步):heads/master(注意:不是remotes/origin/master
      • 远程跟踪分支(不同步):remotes/origin/feature-foo
      • 标签:v1.2.3
      • 子模块:remotes/origin/HEAD
      • 通用分离头:v1.0.6-5-g2393761
    • cat .git/HEAD:
      • 本地分支:ref: refs/heads/master
      • 子模块:cat: .git/HEAD: Not a directory
      • 所有其他用例:相应提交的 SHA
    • git rev-parse --abbrev-ref HEAD
      • 本地分支:master
      • 所有其他用例:HEAD
    • git symbolic-ref --short HEAD
      • 本地分支:master
      • 所有其他用例:fatal: ref HEAD is not a symbolic ref

    (仅供参考,这是使用 git 版本 1.8.3.1 完成的)

    【讨论】:

    • 总而言之,似乎没有人能像我那样手工完成。
    • 这对我很有帮助:git describe --all --exact-match 2>/dev/null | sed 's=.*/==' 对我来说是最好的解决方案(标签和分支头的好名字,随机分离头没有输出。
    • 但是,我刚刚发现,当有多个分支引用同一个提交时,使用 git describe 会出现严重失败,例如在git checkout -b foo 之后 - 它任意使用其中一个(似乎可能是最近创建的一个)。我将更改策略以使用来自git branch 的过滤输出,并且仅在结果与头部分离时使用git describe
    • 这对我真的很有帮助不止一次,谢谢你这么周到!
    • “当前分支”(由checkout foo 设置)和“当前提交”是两个不同的概念。 symbolic-ref 只查看活动分支。 describe 只查看一个提交,并从所有指向它(或靠近它)的分支/标签中启发式地选择。像 branchstatus 这样的 DWIM 命令在定义时使用当前分支,但 all 在所有“分离的 HEAD”情况下都会进行启发式选择。
    【解决方案13】:

    找到了一个和Oliver Refalo's一样长的命令行解决方案,用好老的awk:

    git branch | awk '/^\*/{print $2}'
    

    awk 读作“在匹配正则表达式的行上执行{} 中的内容”。默认情况下,它假定以空格分隔的字段,因此您打印第二个。如果您可以假设只有您的分支所在的行有 *,您可以删除 ^。啊,打高尔夫球!

    【讨论】:

      【解决方案14】:

      如果你在 Jenkins 中运行,你可以使用 GIT_BRANCH 变量,如下所示: https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin

      git 插件设置了几个可以在脚本中使用的环境变量:

      GIT_COMMIT - 当前的 SHA

      GIT_BRANCH - 当前正在使用的分支的名称,例如“master”或“origin/foo”

      GIT_PREVIOUS_COMMIT - 来自同一分支的先前构建提交的 SHA(第一次构建分支的当前 SHA)

      GIT_URL - 存储库远程 URL

      GIT_URL_N - 当有超过 1 个遥控器时存储库远程 URL,例如GIT_URL_1、GIT_URL_2

      GIT_AUTHOR_EMAIL - 提交者/作者电子邮件

      GIT_COMMITTER_EMAIL - 提交者/作者电子邮件

      【讨论】:

        【解决方案15】:

        随着时间的推移,我们可能会有很长的分支列表。

        虽然其他一些解决方案很棒,但这是我所做的(从 Jacob 的回答中简化):

        git branch | grep \*
        

        现在,

        git status
        

        有效,但如果有任何本地更改

        【讨论】:

          【解决方案16】:

          如果您真的希望最后一个分支/标记也以分离的 HEAD 状态检出。

          git reflog HEAD | grep 'checkout:' | head -1 | rev | cut -d' ' -f1 | rev
          

          更新 如果你有并且不害怕 awk,那就更好了。

          git reflog HEAD | grep 'checkout:' | head -1 | awk '{print $NF}'
          

          【讨论】:

          • rev | cut -d' ' -f1| rev 可以简化为awk '{print $NF}'
          • 虽然这也不是万无一失的,因为您可以通过哈希检查特定的修订,因此 reflog 只显示 checkout: moving from ba7571b7fc5b8f31b8d0625821269afaa655577e to f68be8cf7bea917a5a0562b619e50368de0068a9 它仍然是一个有用的技巧,可能有助于消除某些情况的歧义。
          • 进一步缩短为git reflog | awk '$3=="checkout:" {print $NF; exit}'
          【解决方案17】:

          我知道这已经很晚了,但是在 linux/mac 上,您可以从终端使用以下命令。

          git status | sed -n 1p
          

          解释:

          git status -> 获取工作树状态
          sed -n 1p -> 从状态正文中获取第一行

          对上述命令的响应如下:

          "On branch your_branch_name"
          

          【讨论】:

          • head -1 会像往常一样
          【解决方案18】:

          另一种选择:

          git name-rev --name-only HEAD
          

          【讨论】:

          • 也可以用echo ${$(git symbolic-ref --quiet HEAD)#refs/heads/}检索
          • 如果 HEAD 对于 master 和 feature 分支相同(例如在合并期间),则它不起作用。即使在功能分支上执行,它也会返回“master”。
          • git checkout master && git name-rev --name-only HEAD # ac-187 没有按预期工作
          • 我在合并之前将它保存到一个变量中,如果我签出一个特定的提交,我的 HEAD 可能会被解除连接。在这些情况下,这可以正常工作。
          • 我正在通过 Jenkins 管道执行此操作。所以这似乎是目前对我来说最好的答案。做git branch --list 只是说* (HEAD detached at 7127db5)。做git rev-parse --abbrev-ref HEAD 只是说HEAD 等等。
          【解决方案19】:

          抱歉,这是另一个命令行答案,但这正是我在发现这个问题时所寻找的,其中许多答案很有帮助。我的解决方案是以下 bash shell 函数:

          get_branch () {
              git rev-parse --abbrev-ref HEAD | grep -v HEAD || \
              git describe --exact-match HEAD 2> /dev/null || \
              git rev-parse HEAD
          }
          

          这应该总是给我一些既可读又可直接用作git checkout的参数的东西。

          • 在本地分支上:feature/HS-0001
          • 在标记的提交上(分离):v3.29.5
          • 在远程分支上(分离,未标记):SHA1
          • 在任何其他分离的提交上:SHA1

          【讨论】:

          • 感谢您发布此内容,其他答案似乎都不关心总是产生可用作git checkout 的参数。
          【解决方案20】:

          我有一个名为 git-cbr (current branch) 的简单脚本,它打印出当前分支名称。

          #!/bin/bash
          
          git branch | grep -e "^*"
          

          我将此脚本放在自定义文件夹 (~/.bin) 中。该文件夹位于$PATH

          所以现在当我在 git repo 中时,我只需输入 git cbr 即可打印出当前分支名称。

          $ git cbr
          * master
          

          之所以有效,是因为git 命令采用其第一个参数并尝试运行名为git-arg1 的脚本。例如,git branch 尝试运行名为 git-branch 的脚本等。

          【讨论】:

            【解决方案21】:
            git branch | grep -e "^*" | cut -d' ' -f 2
            

            将只显示分支名称

            【讨论】:

            • 如果你的分支显示类似“*(HEAD detached at SUM_BRANCH_01)”,那么试试这个“git branch | grep -e "^*" | cut -d' ' -f 5 | cut -d ')' -f 1"
            • 我刚刚创建了这个完全相同的脚本来获取当前分支名称。我认为它可能对差异有所帮助。
            【解决方案22】:

            使用早期的想法;假设 sha1 是 40 个字符;和追逐参考(是的,应该删除调试打印行:-):

            git reflog | awk '
            $3 == "checkout:" && (sha == "" || sha == $1 ) {
              from=$(NF - 2)
              to=$NF
              print from, to, length(from) > "/dev/stderr"
              if (length(from) != 40) { print from ; exit; }
              sha=substr(from, 1, 7)
              print sha > "/dev/stderr"
            }
            '
            

            给出原始输出:

            $ git status
            HEAD detached at 147049c
            [...]
            $ ./gime-branch.sh
            a47be8d2167641088b66bf8f5c2bf7d3da0c642c HEAD^ 40
            a47be8d
            master HEAD^ 6
            master
            

            【讨论】:

              【解决方案23】:

              您可以永久设置 bash 输出以显示您的 git-branch 名称。当您使用不同的分支时,它非常方便,无需一直输入$ git status。 Github 仓库git-aware-prompt .

              打开终端(ctrl-alt-t)并输入命令

              mkdir ~/.bash
              cd ~/.bash
              git clone git://github.com/jimeh/git-aware-prompt.git
              

              使用sudo nano ~/.bashrc 命令(适用于 Ubuntu)编辑您的 .bashrc 并将以下内容添加到顶部:

              export GITAWAREPROMPT=~/.bash/git-aware-prompt
              source "${GITAWAREPROMPT}/main.sh"
              

              然后粘贴代码

              export PS1="\${debian_chroot:+(\$debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] \[$txtcyn\]\$git_branch\[$txtred\]\$git_dirty\[$txtrst\]\$ "
              

              在您之前将安装代码粘贴到的同一文件的末尾。这将为您提供彩色输出:

              【讨论】:

                【解决方案24】:

                使用 Mac 将其添加到 PS1

                PS1='\W@\u >`[ -d .git ] && git branch | grep  ^*|cut -d" " -f2`> $ '
                

                在运行上述命令之前:

                运行该命令后:

                不用担心,如果不是 GIT 存储库,它不会显示错误,因为 [-d .git] 会检查 .git 文件夹是否存在。

                【讨论】:

                  【解决方案25】:

                  下面的 shell 命令告诉你当前所在的分支。

                  git branch | grep ^\*
                  

                  如果您不想每次想知道分支时都输入那么长的命令并且您正在使用 Bash,请给命令一个短别名,例如别名 cb,就像这样。

                  alias cb='git branch | grep ^\*'
                  

                  当你在 branch master 并且你的提示是$,你会得到* master,如下所示。

                  $ cb
                  * master
                  

                  【讨论】:

                  • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
                  • 你为什么这么认为?
                  • 你应该为 OP 评论和描述你的帖子,这样你的帖子会更容易理解。
                  • 说得通。
                  • 如果您使用 zsh,您需要将 grep 正则表达式用单引号括起来:git branch | grep '^\*'
                  【解决方案26】:

                  你可以在工作目录上使用 git bash 命令如下

                  git status -b
                  

                  它会告诉你你在哪个分支 有很多有用的命令,其中一些是

                  -s
                  

                  --短 以短格式给出输出。

                  -b - 分支 即使以短格式显示分支和跟踪信息。

                  --瓷器[=] 以易于解析的格式为脚本提供输出。这与短输出类似,但在 Git 版本之间以及无论用户配置如何都将保持稳定。详情见下文。

                  version参数用于指定格式版本。这是可选的,默认为原始版本 v1 格式。

                  --长 以长格式给出输出。这是默认设置。

                  -v --详细 除了已更改文件的名称外,还显示暂存待提交的文本更改(即,如 git diff --cached 的输出)。如果 -v 指定了两次,则还显示工作树中尚未暂存的更改(即,如 git diff 的输出)。

                  【讨论】:

                    【解决方案27】:

                    在分离头时返回分支名称或 SHA1:

                    git rev-parse --abbrev-ref HEAD | grep -v ^HEAD$ || git rev-parse HEAD
                    

                    这是@dmaestro12 答案的简短版本,没有标签支持。

                    【讨论】:

                    • 更好:git symbolic-ref --quiet --short HEAD || git rev-parse --short HEAD
                    【解决方案28】:

                    只需将以下行添加到您的~/.bash_profile

                    branch_show() {
                         git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
                    }
                    export PS1="\u@\h \[\033[32m\]\w\[\033[33m\]\$(branch_show)\[\033[00m\] $ "
                    

                    这样就可以在Terminal中拥有当前的分支名称

                    由 Coderwall.com 提供

                    【讨论】:

                      【解决方案29】:
                      git status 
                      

                      还会给出分支名称以及更改。

                      例如

                      >git status
                      On branch master // <-- branch name here
                      .....
                      

                      【讨论】:

                        【解决方案30】:

                        我建议使用这两个命令中的任何一个。

                        git branch | grep -e "^*" | cut -d' ' -f 2

                        git status | sed -n 1p | cut -d' ' -f 3

                        OR(更详细)

                        git status -uno -bs| cut -d'#' -f 3 | cut -d . -f 1| sed -e 's/^[ \t]//1'| sed -n 1p

                        【讨论】:

                          猜你喜欢
                          • 2023-03-09
                          • 2013-09-10
                          • 1970-01-01
                          • 2018-01-25
                          • 2011-12-25
                          • 1970-01-01
                          • 2022-06-16
                          • 1970-01-01
                          相关资源
                          最近更新 更多