【问题标题】:How read the current upstream for a git branch如何读取 git 分支的当前上游
【发布时间】:2018-03-12 21:27:26
【问题描述】:

我正在搜索 git 命令以了解与现有分支关联的上游(如果有)。
(某种与“写”命令相关的“读”命令git branch --set-upstream-to=...
原因是我使用了一个连接了多个远程仓库的分支,我想在更改之前检查分支是否已经与正确的上游连接。

【问题讨论】:

    标签: git git-branch upstream-branch


    【解决方案1】:

    事实上,我发现了使用git status 命令的第一个技巧:
    我的分支是当前分支并且有一个上游,我得到一个类似Your branch is up-to-date with 'the_repo/the branch' 的行,但我有一个更直接的方法来知道这一点。

    【讨论】:

      【解决方案2】:

      以下是我如何找到与 git status 相同的答案,但以脚本友好的方式:

       $ branch="$(git branch | grep '\*' | cut -d' ' -f2-)"
       $ remote="$(git config "branch.${branch}.remote")"
       $ remote_branch="$(git config "branch.${branch}.merge" | cut -d/ -f3-)"
       $ echo "${branch} is tracking ${remote}/${remote_branch}"
       print_locking_less is tracking origin/master
      

      远程跟踪分支的信息存放在.git/config,如下所示:

      [branch "print_locking_less"]
              remote = origin
              merge = refs/heads/master
      

      【讨论】:

      • 这很好,但也很棘手。我非常喜欢torek的解决方案!但是感谢有关文件.git/config 的信息,这也很有趣。
      【解决方案3】:

      TL;DR:使用git rev-parse

      $ git rev-parse --abbrev-ref master@{u}
      weird/master
      

      如果没有设置上游,你会得到:

      fatal: no upstream configured for branch 'master'
      

      (和非零退出代码)。将 stderr 重定向到 /dev/null 以丢弃不想要的错误消息:

      if master_upstream=$(git rev-parse --abbrev-ref master@{u} 2>/dev/null); then
          master_has_upstream=true
      else
          master_has_upstream=false
      fi
      

      例如。

      说明

      Anthony Sottile's answer 通常会为您提供正确的名称,但并非总是如此。特别要注意当originremote.origin.fetch 设置不正常时会发生什么:

      $ git init
      Initialized empty Git repository in .../tmp/tt/.git/
      $ git remote add origin git://github.com/git/git
      $ git config remote.origin.fetch '+refs/heads/*:refs/remotes/weird/*'
      $ git fetch
      remote: Counting objects: 231294, done.
      remote: Compressing objects: 100% (663/663), done.
      remote: Total 231294 (delta 0), reused 662 (delta 0), pack-reused 230631
      Receiving objects: 100% (231294/231294), 93.03 MiB | 3.54 MiB/s, done.
      Resolving deltas: 100% (170261/170261), done.
      From git://github.com/git/git
       * [new branch]          maint      -> weird/maint
       * [new branch]          master     -> weird/master
       * [new branch]          next       -> weird/next
       * [new branch]          pu         -> weird/pu
       * [new branch]          todo       -> weird/todo
       * [new tag]             v2.14.2    -> v2.14.2
      [lots more tags snipped]
      

      请注意,虽然 remote 被命名为 origin,但远程跟踪 branches 被命名为 weird/masterweird/next 等等。它确实有效:

      $ git checkout master
      Branch master set up to track remote branch master from origin.
      Already on 'master'
      $ git status
      On branch master
      Your branch is up-to-date with 'weird/master'.
      
      nothing to commit, working tree clean
      

      但是如果远程跟踪分支名称是origin/master.git/config 中的内容仍然看起来像您所期望的:

      [branch "master"]
          remote = origin
          merge = refs/heads/master
      

      使用:

       branch="$(git branch | grep '\*' | cut -d' ' -f2-)"
      

      效果很好(尽管应该经常使用git symbolic-ref --short HEAD 来获取当前分支名称:见下文)。

      remote="$(git config "branch.${branch}.remote")"
      

      这部分工作得很好——它得到了遥控器的名字。

      remote_branch="$(git config "branch.${branch}.merge" | cut -d/ -f3-)"
      

      这就是我们出错的地方。我们需要的是使用git rev-parse加上“指定分支的上游”的gitrevisions语法,即将@{u}@{upstream}附加到分支名称。通常git rev-parse 将其转换为哈希 ID,但使用--abbrev-ref,它会打印名称的短版本,或者使用--symbolic-full-name,它会打印长版本:

      $ git rev-parse --symbolic-full-name master@{u}
      refs/remotes/weird/master
      

      (我不知道为什么在一种情况下拼写为--abbrev-ref,在另一种情况下拼写为--symbolic-full-name。)

      注意在HEAD上使用git rev-parse时,如果HEAD被分离,答案就是符号HEAD。也就是说,在任何 Git 存储库中,git rev-parse HEAD 始终成功,即使在打印符号名称时也是如此。这对于git symbolic-ref 来说是正确的:

      $ git checkout --detach
      HEAD is now at ea220ee40... The eleventh batch for 2.15
      $ git rev-parse --abbrev-ref HEAD
      HEAD
      $ git rev-parse --symbolic-full-name HEAD
      HEAD
      $ git symbolic-ref HEAD
      fatal: ref HEAD is not a symbolic ref
      

      因此,要解析HEAD(查找当前分支),请根据“无当前分支”情况下的行为选择要使用的命令。

      【讨论】:

      • 非常感谢,它非常清晰和详细。就我而言,默认远程存储库始终称为origin,因此我将使用您的语法git rev-parse --abbrev-ref 'mybranch'@{upstream}
      【解决方案4】:

      只需使用git branch -vv:

      foo    03b325f Commit on untracked branch
      master b7da42b [origin/master] Initial commit
      

      上游(如果有)很好地显示在方括号中。

      摘自manual,并添加了重点:

      -v
      -vv
      --详细
      在列表模式下,显示每个头的 sha1 和提交主题行,以及与上游分支的关系(如果有)。 如果给出两次,则打印链接工作树的路径(如果有)和 上游分支的名称(另见 git remote show )。注意当前工作树的 HEAD 不会有它的 打印的路径(它将始终是您的当前目录)。

      请注意,-vv--verbose 更详细,-v-v 相同。

      【讨论】:

        猜你喜欢
        • 2012-04-06
        • 2023-03-09
        • 2012-07-11
        • 2013-02-13
        • 1970-01-01
        • 2013-02-10
        • 2023-03-05
        • 2017-12-23
        • 2011-01-15
        相关资源
        最近更新 更多