【问题标题】:How can I see which Git branches are tracking which remote / upstream branch?如何查看哪些 Git 分支正在跟踪哪个远程/上游分支?
【发布时间】:2011-06-24 10:58:25
【问题描述】:

我知道我可以做到git branch --all,它显示了本地和远程分支,但它在显示它们之间的关系方面没有多大用处。

如何以显示哪个本地分支正在跟踪哪个远程的方式列出分支?

【问题讨论】:

    标签: git


    【解决方案1】:

    非常漂亮的命令,如果你想用它来编写脚本就不好了:

    git branch -vv   # doubly verbose!
    

    请注意,在 git 1.8.3 中,上游分支以 蓝色 显示(请参阅“What is this branch tracking (if anything) in git?”)


    如果您想要干净的输出,请参阅arcresu's answer - 它使用了一个瓷器命令,我认为在我最初编写此答案时不存在,因此它更简洁一些,并且适用于为 rebase 配置的分支,而不是只是合并。

    【讨论】:

    • 上面的第一种方法没有为我提供所需的信息。第二个......似乎有点矫枉过正,尤其是因为库比的回答有效。我错过了什么吗?
    • @garyp 你不是问这个问题的人。第一个提供了 OP 所需的内容,第二个提供了完全他需要的内容,以防他希望它以干净的形式用于脚本编写,或者只想将其保存为别名。 (“Overkill”如果它可以让你得到你想要的并且你不必重复它就可以了。)从这个问题的角度来看,kubi 的回答提供了一些无关的信息,如果有多个遥控器,它不会'不显示所有内容,但如果它满足您的需求,请务必使用它。
    • 我欠道歉。当我最初运行第一个方法时,我得到no关于什么跟踪什么的信息,我应该明确说明这一点。但是现在我看到了跟踪信息,所以我的设置一定有问题。所以我错过了一些东西。
    • FWIW 我很困惑,因为 -v 和 -vv 显示了如此相似的输出。跟踪的分支显示在散列之后和最近提交之前的方括号中(在我的默认 OSX homebrew 安装上)。
    • 这对我来说就是打印出每个分支的最后提交哈希和注释。
    【解决方案2】:

    git remote show origin

    将“origin”替换为遥控器的名称。

    【讨论】:

    • 即使这个瓷器命令有点适用于人类(对于脚本来说不是那么多,因为它必须解析瓷器输出),我不喜欢这种方法是@987654324 @ 命令实际上连接到远程存储库...因此,如果您碰巧离线或由于某种原因无法连接到存储库,它会失败...
    • @pvandenberk 即使在离线状态下,您也可以使用git remote show -n origin 获取一些信息。来自git remote documentation:“使用 -n 选项,不会首先使用 git ls-remote 查询远程头;而是使用缓存信息。”
    • 这个命令有一个奇怪的地方:它将远程分支列为“跟踪”,即使没有为拉/推配置本地分支。我总是觉得这很令人困惑。我实际上并不清楚这个输出中的“跟踪”应该是什么意思。 The git docs on the subject 听起来好像远程分支只有在链接/绑定到本地分支以进行推/拉时才被“跟踪”...
    • 问题是我需要为所有远程名称调用它,直到我看到我真正在寻找什么。
    • @jolvi 你可以运行git remote show | xargs git remote show -n 来查看所有遥控器的组合跟踪信息。
    【解决方案3】:

    如果您查看git-rev-parse 的手册页,您会看到描述了以下语法:

    <branchname>@{upstream},例如master@{upstream}, @{u}

    分支名称的后缀@{upstream}(简称 <branchname>@{u}) 指的是分支指定的分支 branchname 设置为构建在其之上。缺少的分支名称默认值 到当前的。

    因此要找到分支master 的上游,你会这样做:

    git rev-parse --abbrev-ref master@{upstream}
    # => origin/master
    

    要打印出每个分支的信息,您可以执行以下操作:

    while read branch; do
      upstream=$(git rev-parse --abbrev-ref $branch@{upstream} 2>/dev/null)
      if [[ $? == 0 ]]; then
        echo $branch tracks $upstream
      else
        echo $branch has no upstream configured
      fi
    done < <(git for-each-ref --format='%(refname:short)' refs/heads/*)
    
    # Output:
    # master tracks origin/master
    # ...
    

    这比手动解析 refs 和配置更干净。

    【讨论】:

    • 我无法理解 rev-parse 中的那个位,尽管找到了它,所以感谢您的清晰解释!
    • 对于我们这些使用 git-flow,分支名为“feature/blahblah”的人,while 循环的结束语句应为:done &lt; &lt;(git for-each-ref --format='%(refname:short)' refs/heads/**) 注意两个星号在 glob 模式的末尾。
    • git rev-parse --abbrev-ref HEAD@{upstream} 似乎适用于当前分支。它还提供了一个不错的 git 别名。
    • while 循环语法对我来说有点奇怪。您可以只使用git for-each-ref ... | while read branch; do ...,它不需要 FIFO,并以与编写的命令相同的顺序运行。
    • 至少从 git 2.5.1 开始,你有一个带有 git for-each-ref --format='%(refname:short) tracks %(upstream:short)' refs/heads/* 的单行代码
    【解决方案4】:

    kubi 的替代方法是查看显示本地存储库配置的 .git/config 文件:

    cat .git/config

    【讨论】:

    • 还有git config --get-regex branch
    • 或者,更具体地说,'git config --get-regexp branch.*merge'
    【解决方案5】:
    git for-each-ref --format='%(refname:short) <- %(upstream:short)' refs/heads
    

    将为每个本地分支显示一行。跟踪分支如下所示:

    master <- origin/master
    

    一个非跟踪的看起来像:

    test <- 
    

    【讨论】:

    • 很好,添加一些排序和 TAB-bed 输出:git for-each-ref --sort upstream --format='%(refname:short)%09
    • 非常简洁,输出实际上比公认的git branch -vv更具可读性。 ?
    • 唯一的问题就是这个我记不起来了,所以我用git config --global alias.track 'for-each-ref --format='\''%(refname:short) &lt;- %(upstream:short)'\'' refs/heads'
    【解决方案6】:

    对于 current 分支,这里有两个不错的选择:

    % git rev-parse --abbrev-ref --symbolic-full-name @{u}
    origin/mainline
    

    % git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
    origin/mainline
    

    这个答案也是here,对于一个稍微不同的问题,它被(错误地)标记为重复。

    【讨论】:

    • 基于此,所有分支都可以以脚本友好的方式列出:git for-each-ref --shell --format='%(refname:short) %(upstream:short)' refs/heads
    【解决方案7】:

    对于当前分支,您也可以说git checkout(没有任何分支)。这是一个无操作,具有显示当前分支的跟踪信息(如果存在)的副作用。

    $ git checkout 
    Your branch is up-to-date with 'origin/master'.
    

    【讨论】:

    • 很公平,但您可能会不小心输入git checkout .,这不是空操作。
    • 你可以不小心输入任何东西,真的。
    【解决方案8】:

    这是一个简洁明了的。可以查看git remote -v,它显示了当前分支的所有来源和上游。

    【讨论】:

      【解决方案9】:

      我使用这个别名

      git config --global alias.track '!f() { ([ $# -eq 2 ] && ( echo "Setting tracking for branch " $1 " -> " $2;git branch --set-upstream $1 $2; ) || ( git for-each-ref --format="local: %(refname:short) <--sync--> remote: %(upstream:short)" refs/heads && echo --Remotes && git remote -v)); }; f'
      

      然后

      git track
      

      【讨论】:

      • 我认为值得注意的是,您的命令使用两个参数配置了一个轨道分支。
      • 请说明该命令的作用和使用方式。
      【解决方案10】:

      基于Olivier Refalo's answer

      if [ $# -eq 2 ] 
      then
          echo "Setting tracking for branch " $1 " -> " $2
          git branch --set-upstream $1 $2
      else
          echo "-- Local --" 
          git for-each-ref --shell --format="[ %(upstream:short) != '' ] && echo -e '\t%(refname:short) <--> %(upstream:short)'" refs/heads | sh
          echo "-- Remote --" 
          REMOTES=$(git remote -v) 
          if [ "$REMOTES" != '' ]
          then
              echo $REMOTES
          fi  
      fi
      

      它只显示配置了轨道的本地。

      在你的路径上写一个名为 git-track 的脚本,你会得到一个 git track 命令

      https://github.com/albfan/git-showupstream 上更详细的版本

      【讨论】:

        【解决方案11】:

        git config --get-regexp "branch\.$current_branch\.remote"

        将为您提供正在跟踪的遥控器的名称

        git config --get-regexp "branch\.$current_branch\.merge"

        将为您提供正在跟踪的远程分支的名称。

        您需要将 $current_branch 替换为当前分支的名称。您可以使用 git rev-parse --abbrev-ref HEAD 动态获取它

        下面的小脚本结合了这些东西。将其粘贴到名为git-tracking 的文件中,使其可执行,并确保它在您的路径中。

        那你可以说

        $ git  tracking
        <current_branch_name>-><remote_repo_name>/<remote_branch_name>
        

        请注意,远程分支名称可以与您的本地分支名称不同(尽管通常不是)。例如:

        $git tracking 
        xxx_xls_xslx_thing -> origin/totally_bogus
        

        正如您在代码中看到的,关键是从 git 配置中提取数据。我只是使用 sed 清除无关数据。

        #!/bin/sh
        
        current_branch=$(git rev-parse --abbrev-ref HEAD)
        remote=$(git config --get-regexp "branch\.$current_branch\.remote" | sed -e "s/^.* //")
        remote_branch=$(git config --get-regexp "branch\.$current_branch\.merge" | \
          sed -e "s/^.* //" -e "s/refs\/.*\///")
        
        echo "$current_branch -> $remote/$remote_branch"
        

        【讨论】:

          猜你喜欢
          • 2010-09-15
          • 2012-10-23
          • 2014-11-04
          • 1970-01-01
          • 2012-09-18
          • 2012-10-14
          • 2014-08-22
          • 2021-03-21
          相关资源
          最近更新 更多