git - 如何获得默认分支?

lfe*_*445 28 git

我的团队交替使用dev和master作为几个repos的默认分支,我想编写一个脚本,在输入目录时检查默认分支.

当在某些repos中打开pull请求时,它们默认为'dev'或'master'作为合并目标.

我了解如何设置此信息但不检索它:https: //help.github.com/articles/setting-the-default-branch/

是否有可用于确定远程存储库的默认分支的git命令?

dan*_*kza 26

在Github克隆的repo中使用git 2.9.4(但可能在其他版本中工作)进行测试:

$ git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
master
Run Code Online (Sandbox Code Playgroud)

  • 要从上游同步此符号引用,请使用“git remote set-head origin --auto”。这会更新“git Remote show”中看到的内容以及此处引用的符号引用。 (11认同)
  • 如果我更改服务器端 (github) 上的默认分支,这仍然会在旧的但当前的克隆中获得旧的默认值(但新的克隆很好)。在这里如何强制更新? (3认同)
  • 这适用于原点,但是当我尝试为另一个远程(例如分叉的 github 设置中的上游)获取默认分支时,我得到“不是符号引用”。我对 git 不够了解,无法理解为什么,但显然 ref/remotes/upstream 根本不存在。不过,基于 git remote 的 Radon8472 解决方案对我有用。 (3认同)
  • 此方法可能会失败或返回不正确的结果。ref可能是无法解析为分支的哈希,而不是符号引用。这也可以通过查看HEAD来解决。不过,在6528个存储库中,我检查了172种情况下的两种“ git symbolic-ref”方法返回了错误的结果(例如,“ Alfresco / chef-alfresco”的“ master”而不是“ develop”)。@ Radon8472提出的“ git remote show”方法更可靠,并且在我手动验证的172个不同案例中,似乎返回了正确的结果。 (3认同)
  • 也许我做错了什么,但是当我运行它时,我得到:`fatal:ref refs / remotes / origin / HEAD在Git 2.19.1中不是符号ref`。 (2认同)
  • 你也可以使用 **basename** 而不是 sed `basename $(git symbols-ref refs/remotes/origin/HEAD)` (2认同)

Rad*_*472 20

我找到了一种方法来检测默认分支,如果它不是主分支.

git remote show [your_remote] | grep "HEAD branch" | cut -d ":" -f 2
Run Code Online (Sandbox Code Playgroud)

我用gitlab的多个repo测试了它,它工作得很好.

  • 如果 git 在非英语语言环境下运行,这将不起作用。例如,在德语语言环境中,“HEAD Branch”拼写为“Hauptbranch”。要修复此问题,请使用:`LC_ALL=C git remote show origin | sed -n '/HEAD 分支/s/.*: //p'` (9认同)
  • 我将其更新为这样以删除空格`git remote show origin | grep '头分支' | 切-d''-f5` (4认同)
  • 这对我来说效果很好,只是cut命令在实际的分支名称之前留了一个空格,这在脚本中使用时会引起问题。我最终使用`git remote show上游| grep“ HEAD分支” | sed's /.*://'` (2认同)
  • 到目前为止最好的方法。由于某些原因,我什至没有refs / remotes / origin / HEAD。 (2认同)
  • 请注意,如果您的 HEAD 不明确,这可能不适用于某些(较旧的)版本的 git。参见例如[这篇文章](/sf/ask/198258861/) (2认同)

Joe*_*nux 19

这个问题有点老了,但如果有人最近遇到这个问题......

git remote show <remote_name> | awk '/HEAD branch/ {print $NF}'
Run Code Online (Sandbox Code Playgroud)

这也只会显示分支名称,不包括任何空格或其他废话。

我喜欢使用几个 git 别名来保存它(我有一堆这样的有用别名):

upstream-name = !git remote | egrep -o '(upstream|origin)' | tail -1
head-branch = !git remote show $(git upstream-name) | awk '/HEAD branch/ {print $NF}'
Run Code Online (Sandbox Code Playgroud)

我几乎 100% 的时间都使用“上游”和“原点”作为我的遥控器(当我使用Fork & Pull工作流程时,“上游” ......这通常是)。您的用例可能不需要upstream-name别名,我只是觉得它很有用。


Jef*_*kin 18

git rev-parse --abbrev-ref origin/HEAD将打印origin/<default-branch-name>。的git symbolic-ref回答也在做着同样的事情,但需要一个较长的说法。

如果origin存储库更改其默认分支名称,git remote set-head origin -a则将检索新的默认分支名称。

  • 回答我自己 - 这不是规范的答案,因为它仅适用于通过从远程克隆创建的存储库 - 而不是您创建的存储库,然后通过“git remote add”添加远程并推送到它。 (7认同)
  • 它的运行速度比“git remote show”快得多,因为它使用本地信息而不轮询远程。您可以删除前 7 个字符(即“origin/”)并使用 `git rev-parse --abbrev-ref origin/HEAD | 获取分支名称。切-c8-`。 (5认同)
  • 对我不起作用:当按照答案执行时,我得到的唯一标准输出是“origin/HEAD”,并且还有错误“警告:忽略悬空的symref refs/remotes/origin/HEAD”,“致命:不明确”参数“origin/HEAD”:未知修订版本或路径不在工作树中。`。如果我在命令后附加一个“--”,它会显示“警告:忽略悬空的 symref refs/remotes/origin/HEAD”、“致命:错误的修订版“origin/HEAD”。然而,这个答案所指的“git symbolic-ref”答案对我有用。 (5认同)

Hen*_*nry 17

要求

您需要refs/remotes/origin/HEAD并且仅在克隆时设置。否则你需要自己设置

git remote set-head origin -a

更多信息

命令

无论您如何命名遥控器,以下命令都会列出 HEAD 分支:

git branch --remotes --list '*/HEAD'
Run Code Online (Sandbox Code Playgroud)

您可以从中提取默认分支,如下所示:

git branch -rl '*/HEAD' | rev | cut -d/ -f1 | rev
Run Code Online (Sandbox Code Playgroud)

(使用git branch参数的简短变体)。

如果您的 shell 没有该rev命令,您可以使用awk

git branch -rl '*/HEAD' | awk -F/ '{print $NF}'
Run Code Online (Sandbox Code Playgroud)


Amo*_*ory 15

正如其他回答者所指出的,默认分支的概念是 GitHub 的事情,对于 Git 来说并没有真正的意义(从崇高的意义上来说)(这里有一个相当不错的(如果没有得到充分重视)评论对此进行了一些介绍:https ://stackoverflow.com/a/65710958/2521092)但在实践中,我们都知道这意味着什么。

自从最初提出这个问题以来,Git 2.28 添加了init.defaultBranch,允许与 不同的初始分支master,并且很多项目现在都在使用main. 那挺好的。这里的大多数答案都依赖于检查遥控器,但这依赖于实际上存在一个遥控器,并且这些遥控器存在可靠且一致的命名方案。这些可能(越来越?)合理的假设,但这不是保证,而且我发现这里的任何主要答案都不会很好地失败。

此外,我的主要用例是使用各种 git 别名的默认分支的名称(例如lm = log main..HEAD)。我想使用相同的别名,而无需考虑太多,无论使用外部存储库还是不使用远程的master本地使用。mainGit 及其配置无法真正“存储”信息,因此无法提前设置当前存储库的主分支是什么。因此,任何想要显示主分支和 HEAD 之间提交的别名都不能假设git log master..HEADgit log main..HEAD工作。

因此,我default-branch在 Git 中定义了一个别名,它可以找出默认分支,然后将其提供给其他别名。这是一个痛苦,因为一个简单的东西lm = log main..HEAD必须变成,lm = "!git log $(git default-branch)..HEAD"但我们在这里:

default-branch = "!git branch --sort=-refname | grep -o -m1 '\\b\\(main\\|master\\|dev\\)\\b'"

这只是获取分支名称,然后找到定义列表中的第一个分支。如果有main,则使用它;如果没有并且有一个master,请使用它。我还有dev一些人使用的第三选项。

这有点类似于 @henrik-n 在/sf/answers/4663565441/中所做的事情,但我是在 Git 本身而不是 shell 中完成的,而且我认为它有更多的可选性。


小智 14

这可以通过 gh cli 工具获得(已测试 v2.0.0)

gh repo view --json defaultBranchRef --jq .defaultBranchRef.name
Run Code Online (Sandbox Code Playgroud)


小智 8

所有其他答案都做了太多假设,这是对我有用的唯一方法。无论您当前位于哪个分支,这都有效,不假设origin/HEAD引用存在于本地,并且始终反映当前的默认分支,即使它已被更改。

唯一的缺点是它改变了本地origin/HEAD引用,但这通常不应该成为问题。

允许 git 设置你的origin/HEAD,确定自动使用哪个分支:

$ git remote set-head origin --auto
origin/HEAD set to main
Run Code Online (Sandbox Code Playgroud)

然后,获取包含默认分支名称的字符串:

$ git rev-parse --abbrev-ref origin/HEAD
origin/main
Run Code Online (Sandbox Code Playgroud)

或者,对于单行解决方案:

$ git remote set-head origin --auto >/dev/null 2>&1 && git rev-parse --abbrev-ref origin/HEAD
origin/main
Run Code Online (Sandbox Code Playgroud)


Ant*_*ile 7

到目前为止,似乎没有一个不需要克隆的答案

这需要git 2.8.0或更高版本

$ git ls-remote --symref git@github.com:pre-commit/pre-commit.github.io HEAD
ref: refs/heads/real_master HEAD
e100a6a3c72b4e54f0d176f791dfd2dbd7eb5fa7    HEAD
Run Code Online (Sandbox Code Playgroud)


Hen*_*k N 6

我只是想要一个 shell 脚本来知道分支是“master”还是“main”。

出于这个目的,这似乎足够好了:

[ -f "$(git rev-parse --show-toplevel)/.git/refs/heads/master" ] && echo master || echo main
Run Code Online (Sandbox Code Playgroud)

如果您知道它将始终从存储库的根目录调用,则可以将其简化为

[ -f .git/refs/heads/master ] && echo master || echo main
Run Code Online (Sandbox Code Playgroud)

我在我的 Git 别名中使用它,如下所示:https://github.com/henrik/dotfiles/commit/6815bd95770afab2936fb6202b1ee5e82cb9662b


Von*_*onC 5

是否有 git 命令可用于确定远程存储库的默认分支?

这列出了默认的本地存储库分支:

git rev-parse --abbrev-ref origin/HEAD
Run Code Online (Sandbox Code Playgroud)

GitHub API可以使用其CLI显示默认分支gh

gh api /repos/{owner}/{repo} --jq '.default_branch'
Run Code Online (Sandbox Code Playgroud)


小智 5

git symbolic-ref有一个--short选项。所以我的首选命令是:

$ git symbolic-ref --short HEAD
master
Run Code Online (Sandbox Code Playgroud)

  • 这对于问题所要求的内容不起作用。仅当您碰巧位于默认分支上时,它才会给出正确的答案。如果检查了其他内容,它会给出该内容。 (25认同)
  • 对于远程,它仍然是`git symbolic-ref --short refs / remotes / origin / HEAD | sed's @ ^ origin / @@'` (4认同)
  • 它是一个路径,因此在大多数 POSIX-y shell 中,您也可以仅使用基本名称来获取最后一个组件。:D `basename $(git symbolic-ref --short refs/remotes/origin/HEAD)` (4认同)
  • basename 不适用于所有分支名称,因为它们可以包含斜杠 (4认同)

Car*_*lsh 5

如果像这个问题一样,您正在尝试获取GitHub默认分支,而不是其他 git 服务器:

/repos您可以使用GitHub API获取默认分支。这是default_branch响应的字段:

$ curl -s https://api.github.com/repos/darthwalsh/bootstrappingCIL | \
      jq --raw-output .default_branch
master
Run Code Online (Sandbox Code Playgroud)