有没有更好的方法来查找本地git分支是否存在?

265

我使用以下命令来查找是否存在一个名为 branch-name本地 git 分支。这样做正确吗?有更好的方法吗?

请注意,我是在脚本内执行此操作。因此,如果可能的话,我想使用plumbing命令

git show-ref --verify --quiet refs/heads/<branch-name>
# $? == 0 means local branch with <branch-name> exists. 

8
在我无知的情况下,我会使用 git branch | grep -w <branch-name>。虽然这是一个表面命令,但我认为未来不太可能对这种用法进行重大更改,因此这段代码仍然可用。 - UncleZeiv
@UncleZeiv:你可能是对的,这个命令不会有太大变化而变得无法使用。我只是有点强迫症,比如瓷器和管道之类的东西。 - Manoj Govindan
12
git rev-parse --verify <branch_name> 命令可以验证分支名称,也可以验证标签和提交哈希等其他引用。因此,如果你只对分支感兴趣,它可能不太适合你,因为它会返回误报。需要注意的是,翻译过程中不能改变原文意思。 - Paul S.
非常微小的事情,但在更新部分中,应该是git rev-parse --verify <branch-name>(即branch-name而不是branch_name)? - Gautam
2
只有使用git show-ref命令才能确定本地分支是否存在。在更新(使用git rev-parse语法)中,如果远程分支匹配,则返回代码也为0。 - Fabien Bouleau
显示剩余2条评论
18个回答

152

当我在搜索引擎上搜索'git检查分支是否存在'时,这个页面是我看到的第一个。

我得到了我想要的信息,但我想提供一个更新的答案,因为原始帖子是从2011年发布的。

git rev-parse --verify <branch_name>

这基本上与被接受的答案相同,但您不需要键入“refs/heads/”

因此,在shell脚本中,这将是:

if [ `git rev-parse --verify main 2>/dev/null` ]
then
   ...
fi

35
请注意:git rev-parse --verify 命令只会告诉你一个对象是否存在于代码库中(例如,对于任何能够在代码库中找到的对象,它都会返回0)。但是它并不会告诉你这个对象是否是一个分支。 - tavnab
18
这不是正确的问题答案,该问题询问如何知道分支是否存在。它会误报标签。你可以轻松测试一下。你需要使用"refs/heads/"来区分在"refs/tags"中的标签,甚至"refs/remotes"中的远程标签。 - msouth
25
"git rev-parse --verify gh-pages" 返回:致命错误:需要单个修订版本。 - SuperUberDuper
5
这也给我返回了 fatal: Needed a single revision - HDJEMAI
2
不需要使用 [ ... ]。只需使用 if git rev-parse --verify main >/dev/null 2>&1 ; then ...。它使用命令返回的成功/失败状态。(如注释所述,它对分支和标签都返回 true。) - Keith Thompson
显示剩余3条评论

77
据我所知,在脚本中这是最好的方法。我不确定是否还有更多要补充的,但也许只需要一个答案即可,它会说“那个命令能完成你想要的一切” :)
唯一需要注意的是分支名称可能包含令人惊讶的字符,因此您可能需要引用<branch-name>

1
关于引用<branch-name>的好处很明显。顺便说一下,我正在使用这个在一个fabric脚本中。我会记得引用这个变量的。 - Manoj Govindan
1
正确答案是这样的: git show-ref --verify --quiet refs/heads/<branch-name> 将正确显示 HEAD 不是一个分支。git rev-parse --verify 会告诉你 HEAD 是一个现有的分支。这是错误的,因为 HEAD 不是一个分支。 - Paulo Neves

68

我建议使用git show-ref --quiet refs/heads/$name

  • --quiet表示没有输出,这很好,因为你可以清楚地检查退出状态。

  • refs/heads/$name限制为本地分支并匹配完整名称(否则dev将匹配develop

在脚本中的用法:

if git show-ref --quiet refs/heads/develop; then
    echo develop branch exists
fi

1
是的,这是唯一一个默默执行的命令。Git 命令的命名有些奇怪。 - smac89
2
有点奇怪,我不得不滚动三个答案才能找到最好的解决方案。我想这个答案最终会排在首位。 - ijoseph
1
如果您想在脚本中使用它,这就是要使用的答案。 - user151841

47

就快完成了。

只需省略--verify--quiet,如果分支存在,则会返回哈希值,否则返回空值。

将其分配给一个变量并检查是否为空字符串。

exists=`git show-ref refs/heads/<branch-name>`
if [ -n "$exists" ]; then
    echo 'branch exists!'
fi

19
返回值已经足够了——你不需要为了将值赋给一个变量而进行可能会出错的努力。 - msouth
因为你可以检查返回值,所以被踩了。 - Jason Harrison

30

用于脚本的使用:

git show-ref -q --heads <branch-name>

只有当本地分支存在时,<branch-name> 存在,否则退出并返回 0

例如:

if git show-ref -q --heads <branch-name>; then
   echo 'Branch exists'
fi

16
我认为您可以在此处使用git show-branch
$ git show-branch --list
  [master] test
* [testbranch] test
$ git show-branch testbranch
[testbranch] test
$ echo $?
0
$ git show-branch nonexistantbranch
fatal: bad sha1 reference nonexistantbranch
$ echo $?
128
因此,$? == 0表示该分支存在,您无需深入了解refs/heads/的内部工作。只要不向show-branch传递-r,它就只会在本地分支上运行。

6
据我所知,git show-branch是一个_瓷器_命令。正如我在问题中所说的,如果有等效的管道命令,我宁愿不在脚本中使用瓷器命令。请参见http://www.kernel.org/pub/software/scm/git/docs/。 - Manoj Govindan
4
@Manoj:我知道瓷器和管道的区别,但我从未读过管道被认为比瓷器更稳定。谢谢你在文档中指出这一点。 - Mark Drago
1
为了避免错误地查找标签,并更具体地说明分支是本地还是远程,您可以指定 git show-branch refs/heads/[branch]git show-branch refs/remotes/origin/[branch] - twasbrillig

11

git branch -l <branch-name>

如果分支存在,则返回分支名,如果不存在则返回空


2
这是更好的解决方案。例如:git_checkout_main() { main_branch=$(git branch -l main) if [ -z "${main_branch}" ]; then git checkout master else git checkout main fi } - Viet

4
在Windows批处理脚本中,情况有些不同。
git rev-parse --verify <branch>

if %ERRORLEVEL% == 0  (
    echo "Yes"
) else (
    echo "No"
)

对于相同名称的标签,也会返回Yes。 - damkrat

3
是的,有一个。
git rev-parse [<options>] <args>…​

请参见https://git-scm.com/docs/git-rev-parse,您可以在其中找到参数集和函数。

git rev-parse --verify <branch-name>

2

我们称其为git is_localbranch(您需要在.gitconfig中添加别名)。

用法:

$ git is_localbranch BRANCH

来源:

git branch | grep -w $1 > /dev/null
if [ $? = 0 ]
then
  echo "branch exists"
fi

如果在PATH中的任何目录中可用且名为git-is_localbranch,则无需在.gitconfig中设置别名:git <command>将寻找一个名为git-<command>的可执行文件,例如git foo将寻找一个名为git-foo的可执行文件。 - Dereckson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接