如何检查给定的远程仓库上是否存在远程分支?

180

如果在给定的远程仓库中存在特定分支,我需要对一个子树合并进行操作。问题是远程仓库没有被本地检出,所以我无法使用git branch -r命令。我只有一个远程地址,类似于https://github.com/project-name/project-name.git。 有没有一种方法可以通过远程地址列出远程分支?很遗憾我找不到任何有用的东西:(

18个回答

193
$ git ls-remote --heads git@github.com:user/repo.git refs/heads/[branch-name]
# or
$ git ls-remote --heads origin refs/heads/[branch-name]

如果找到[branch-name],您将获得以下输出:
b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

否则将不会发送任何输出。
因此,将其导入到wc中将给出10
$ git ls-remote --heads git@github.com:user/repo.git refs/heads/[branch-name] | wc -l

或者你可以在git ls-remote命令上设置--exit-code标志,如果没有找到匹配的引用,它将返回退出码2。结果可以直接在shell测试中检查,或通过检查状态变量$?来进行检查。
$ git ls-remote --exit-code --heads git@github.com:user/repo.git refs/heads/[branch-name]

请注意,您应该在[branch-name]前加上refs/heads/前缀,否则它将进行部分匹配,例如bar将匹配到barfoo/bar两个分支。

15
我使用了命令 git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/null,然后紧接着使用了 if [ "$?" == "1" ] ; then echo "分支不存在"; exit; fi - sibaz
1
我花了几个小时寻找这个简洁而精确的答案,太棒了。 - medik
3
你需要将分支名称指定为 /refs/heads/branch-name。否则,即使没有 branch-name,也会返回分支 foo/branch-name - FuzzY
18
注意:如果您不想指定存储库的URL,可以指定存储库的远程名称,例如:git ls-remote --heads origin branch-name - daveruinseverything
6
顺序很重要:--exit-code 必须在 --heads 之前。 - bishop
2
“/refs/heads/branch-name” 看起来不起作用,但是 “refs/heads/branch-name” 可以。 - Blaisorblade

56
git ls-remote --heads https://github.com/rails/rails.git
5b3f7563ae1b4a7160fda7fe34240d40c5777dcd    refs/heads/1-2-stable
81d828a14c82b882e31612431a56f830bdc1076f    refs/heads/2-0-stable
b5d759fd2848146f7ee7a4c1b1a4be39e2f1a2bc    refs/heads/2-1-stable
c6cb5a5ab00ac9e857e5b2757d2bce6a5ad14b32    refs/heads/2-2-stable
e0774e47302a907319ed974ccf59b8b54d32bbde    refs/heads/2-3-stable
13ad87971cc16ebc5c286b484821e2cb0fc3e3b1    refs/heads/3-0-stable
3df6c73f9edb3a99f0d51d827ef13a439f31743a    refs/heads/3-1-stable
f4db3d72ea564c77d5a689b850751ce510500585    refs/heads/compressor
c5a809e29e9213102351def7e791c3a8a67d7371    refs/heads/deps_refactor
821e15e5f2d9ef2aa43918a16cbd00f40c221e95    refs/heads/encoding
8f57bf207ff4f28fa8da4544ebc573007b65439d    refs/heads/master
c796d695909c8632b4074b7af69a1ef46c68289a    refs/heads/sass-cleanup
afd7140b66e7cb32e1be58d9e44489e6bcbde0dc    refs/heads/serializers

我之前也不知道有ls-remote这个命令。谢谢! - Keen
9
我需要在一个bash脚本中进行测试,所以我只对退出代码感兴趣,因此在本地克隆中执行了以下操作:git ls-remote --exit-code . origin/branch-name &> /dev/null,然后将 $? 作为测试运算对象。 - Darren Bishop
5
@Darren,在条件语句中直接使用命令,例如 if git ls-remote ...; then ...; fi,比检查 $?(该值可能会受到日志语句、陷阱等影响而改变)更少出错。 - Charles Duffy
Why the --heads? - Steve
@JohnLinux --heads 仅列出分支。使用 --tags 仅列出标签。 - rymo

47

这里所有的回答都是针对Linux shell特定的,如果你在不支持这些操作的环境下,比如Windows的命令提示符,那么这并没有太大帮助。

幸运的是,git ls-remote接受一个--exit-code参数,根据分支是否存在返回0或2。因此:

git ls-remote --exit-code --heads origin <在origin中存在的分支>

将返回0,而

git ls-remote --exit-code --heads origin <仅在本地存在的分支>

将返回2。

对于PowerShell,您可以简单地使用内置的真值处理语义:

if (git ls-remote --heads origin <在origin中存在的分支>) { $true } else { $false }

返回$true,而:

if (git ls-remote --heads origin <仅在本地存在的分支>) { $true } else { $false }

返回$false


喜欢使用退出代码。非常感谢你。重要提示:在“git ls-remote”中,对于退出码2,“<branch-that-does-not-exist-in-origin>”是更准确的描述,因为它不表示其在本地存在。使用“git branch --list '<branch-name>' | grep --quiet '<branch-name>'”可以利用退出代码来确定提供的名称是否具有本地分支。在这里,退出代码“0”表示本地存在该分支,“1”表示不存在。编辑:我看到你最初的回答是因为你“在Windows上”。很抱歉,因为这个评论是面向Linux的。 - Darren Felton

36

你也可以使用这个:

git show-branch remotes/origin/<<remote-branch-name>>

返回最新的提交及$?的值为0, 否则返回 "fatal: bad sha1 reference remotes/origin/<>" ,$?的值为128


4
在检查之前,这不会从远程拉取分支,因此您无法获取最新的远程状态。 - siemanko
1
这是最好的!git ls-remote --heads origin <branch> 非常慢(对我来说需要3-4秒)。即使远程分支不存在,git branch -r --list origin/<branch> 也会返回0。这很快,并且如果远程分支不存在则返回128! - TrueY

25

那就不需要每次手动传递存储库名称了。

git ls-remote origin <branch>

而不是

git ls-remote <full repo url> <branch>

例子:

git ls-remote git@bitbucket.org:landmarkgroupme/in-store-application.git  uat_21dec

或者

git ls-remote origin uat_21dec
两者将输出相同:

enter image description here

更多关于来源的信息 : Git有“远程”这一概念,它只是指向您的存储库其他副本的URL。当您克隆另一个存储库时,Git会自动创建一个名为“origin”的远程并指向它。您可以通过输入git remote show origin查看有关远程的更多信息。


21

如果当前文件夹是一个 git 仓库,你可以使用另一种方式来运行:

git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'

4
使用双引号:git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"。意思是搜索与${YOUR_BRANCH_NAME}名称相匹配的远程分支。 - Ivan
4
这不是最优的方法,因为即使只匹配现有分支名称的一部分,而没有完全匹配目标分支,它也会返回true。因此,在脚本中用它来测试分支是否存在然后再checkout是不安全的。不过还是感谢您分享,我觉得很有用。可以通过这种方式进行修复:git branch -a | grep "\b${BRANCH}$" - EntangledLoops
2
如果使用 git branch -a,则需要执行 git fetch 以先获取所有远程引用。否则,请按照其他人指出的使用 git ls-remote - hIpPy
git branch -a --list '<pattern>'同样是一个选项。如果你需要脚本的返回代码,请使用管道符连接到grep命令。 - LOAS

14

你可以在Bash终端中做类似于这样的事情。只需将echo替换为您想要执行的命令。

if git ls-remote https://username:password@github.com/project-name/project-name.git | grep -sw "remote_branch_name" 2>&1>/dev/null; then echo "IT EXISTS..START MERGE" ; else echo "NOT FOUND" ; fi
希望它有所帮助。

4
我喜欢它。其他的回答也有ls-remote,但我喜欢的是“if”。 - Stony

10
$ git ls-remote --heads origin <branch> | wc -l

大多数情况下都能正常工作。

但是,如果分支部分匹配如下所示,则无法正常工作:

$ git branch -a
creative/dev
qa/dev

$ git ls-remote --heads origin dev | wc -l
2

使用

git ls-remote --heads origin <branch> | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^<branch>$ | wc -l

如果你想要一种可靠的方式。

如果你想在脚本中使用,而不希望将origin作为默认远程,则可以:

git ls-remote --heads $(git remote | head -1) "$branch" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    grep ^"$branch"$ | wc -l

应该可以工作。

请注意,git branch -a | grep ... 不可靠,因为上一次 fetch 可能已经过了一段时间。


对我来说,这是被接受的答案,结合了Amitesh(远程简短名称)和James Cache的答案(grep -x“$branch”grep ^“$branch”$相同)。虽然在脚本中,我更喜欢长格式开关:--line-regexp。此外,没有必要执行wc -l。将空输出放入Bash if [ -z] 中有效地评估为真,因此表示该分支不存在。这可以为您节省几毫秒的时间。 - Amedee Van Gasse

5

该命令将返回所有包含查询内容(无论是远程还是本地)的分支名称。

git branch --all | grep <query>


1
这似乎比 git ls-remote 快得多。谢谢。 - hookenz

2
这里有一个简单的bash脚本,可以完成这项任务。
#!/bin/bash

BRANCH="your-branch-name"
# Replace above value with the URL of your git repository
REPO_URL="https://github.com/lsst-dm/qserv-ingest.git"
if git ls-remote --exit-code --heads "$REPO_URL" "$BRANCH"
then
    echo "REMOTE BRANCH EXISTS"
else
    echo "REMOTE BRANCH NOT FOUND"
fi

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