关于git:如何检查给定远程存储库中是否存在远程分支?


How to check if remote branch exists on a given remote repository?

如果某个特定的分支存在于给定的远程存储库中,我需要为它进行子树合并。问题是远程存储库没有在本地签出,所以我不能使用git branch -r。我所拥有的只是一个远程地址,类似于这个https://github.com/project-name/project-name.git。有没有一种方法只按远程地址列出远程分支?我找不到有用的东西:(


1
$ git ls-remote --heads [email protected]:user/repo.git branch-name

如果发现branch-name,您将得到以下输出:

1
b523c9000c4df1afbd8371324083fef218669108        refs/heads/branch-name

否则将不发送输出。

因此,通过管道连接到wc将给您提供10

1
$ git ls-remote --heads [email protected]:user/repo.git branch-name | wc -l

或者,您可以在git ls-remote上设置--exit-code标志,如果没有找到匹配的refs,该标志将返回退出代码2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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


如果当前文件夹是要运行的git repo,则可以使用另一种方法。

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


您还可以使用:

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

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


您可以在bash终端中执行类似的操作。只需将echos替换为要执行的命令即可。

1
if git ls-remote https://username:[email protected]/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

希望有帮助。


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

大部分时间都在工作。

但如果分支部分匹配如下,则不起作用,

1
2
3
4
5
6
$ git branch -a
creative/dev
qa/dev

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

使用

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

如果你想要一个可靠的方法。

如果您希望在脚本中使用并且不希望将origin假定为默认远程,那么

1
2
3
4
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运行。


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

1
git ls-remote origin <branch>

而不是

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

例子:

1
git ls-remote [email protected]:landmarkgroupme/in-store-application.git  uat_21dec

1
git ls-remote origin uat_21dec

两者的输出相同:

enter image description here

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


这里的所有答案都是特定于Linuxshell的,如果您所处的环境不支持这些操作(例如,Windows的命令提示符),那么它就没有多大帮助。

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

埃多克斯1〔2〕

将返回0,并且

埃多克斯1〔3〕

将返回2。

对于PowerShell,您只需使用内置的shell处理语义:

江户十一〔四〕号

生成$true,而:

埃多克斯1〔6〕

生成$false


你可以试试

1
git diff --quiet @{u} @{0}

这里,@{u}表示远程/上游,@{0}表示当前的本地头(对于较新版本的git,@{0}可以简称为@)。如果远程不存在,它将出错。

使用Git2.16.2(我不确定哪个版本是第一个具有此功能的版本,例如,Git1.7.1没有它),您可以这样做

1
git checkout

如果存在远程分支,则会有一些输出,例如

1
Your branch is up to date with 'origin/master'

否则就没有输出。


您可以使用git remote add something https://github.com/project-name/project-name.git将您拥有的存储库添加为远程存储库,然后执行git remote show something以获取有关远程存储库的所有信息。这需要网络连接,并且对人类有用。

或者,执行git fetch something。这将获取远程名为something的所有分支,并将它们保存在本地存储库中。然后您可以根据需要将它们合并到您的本地分支机构中。我推荐这条路径,因为如果您最终决定要合并,这就是您需要做的。

OT:您使用"本地签出"表示您是从集中版本控制系统的角度来实现这一点的。当你和Git打交道时,这通常是一个死胡同。它使用诸如"结帐"等不同于旧系统的词汇。


将返回名称中包含查询的所有分支(远程或本地)。

埃多克斯1〔23〕


我将上面的一些答案结合在一个脚本中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
BRANCHES=(develop master 7.0 7.0-master)
ORIGIN=bitbucket
REMOTE=github

for BRANCH in"${BRANCHES[@]}"; do
  BRANCH=$(git ls-remote --heads"${ORIGIN}""${BRANCH}" \
      | cut --delimiter=$'\t' --fields=2 \
      | sed 's,refs/heads/,,' \
      | grep --line-regexp"${BRANCH}")
  if [ -n"${BRANCH}" ]
  then
    git branch --force"${BRANCH}""${ORIGIN}"/"${BRANCH}"
    git checkout"${BRANCH}"
    git push"${REMOTE}""${BRANCH}"
  fi
done

git push github --tags

这个脚本将从远程位桶中获取4个分支,并将它们推送到远程GitHub,然后将所有标记推送到GitHub。我在Jenkins的工作中使用这个,这就是为什么你没有看到任何在Jenkins工作库配置中已经完成的git fetchgit pull的原因。

我通常喜欢脚本中的长格式选项。我可以用git checkout -Bgit branchgit checkout结合起来。


我刚试过这个:

1
git ls-remote --heads 2>/dev/null|awk -F 'refs/heads/' '{print $2}'|grep -x"your-branch"|wc -l

如果找到分支"your branch",则返回1,否则返回0。


如果您的分支名称非常具体,那么您可能不需要使用grep进行简单的分支名称匹配:

1
2
3
4
git ls-remote --heads $(git remote | head -1)"*${BRANCH_NAME}*" | \
    cut -d$'\t' -f2 | \
    sed 's,refs/heads/,,' | \
    wc -l

哪个工作

1
2
3
4
BRANCH=master
BRANCH=mas
BRANCH=NonExistingBranch (returns 0)
BRANCH=ISSUE-123

我们使用唯一的问题ID作为分支名称,它工作正常。