【发布时间】:2012-01-03 15:58:48
【问题描述】:
如果特定分支存在于给定的远程存储库中,我需要对特定分支进行子树合并。问题是远程仓库没有在本地签出,所以不能使用git branch -r。我只有一个远程地址,比如https://github.com/project-name/project-name.git。有没有办法仅通过远程地址列出远程分支?我找不到任何有用的东西:(
【问题讨论】:
标签: git
如果特定分支存在于给定的远程存储库中,我需要对特定分支进行子树合并。问题是远程仓库没有在本地签出,所以不能使用git branch -r。我只有一个远程地址,比如https://github.com/project-name/project-name.git。有没有办法仅通过远程地址列出远程分支?我找不到任何有用的东西:(
【问题讨论】:
标签: git
这对我来说是最简单的方法。 (※鱼壳)
if test (git ls-remote | grep your-branch-name)
echo exist
else
echo not_exist
end
【讨论】:
怎么样
if [ -e .git/refs/remotes/origin/mybranch ]; then
echo remote branch still exists - locally at least
else
echo remote branch is gone
fi
git ls-remote 将与远程服务器交互,这
可能是也可能不是你想要的。
【讨论】:
$ git ls-remote --heads git@github.com:user/repo.git branch-name
如果找到branch-name,您将获得以下输出:
b523c9000c4df1afbd8371324083fef218669108 refs/heads/branch-name
否则将不发送任何输出。
因此,通过管道将其发送到 wc 会得到 1 或 0:
$ git ls-remote --heads git@github.com:user/repo.git branch-name | wc -l
或者,您可以在git ls-remote 上设置--exit-code 标志,如果找不到匹配的引用,它将返回退出代码2。可以直接在 shell 测试中检查结果,也可以通过检查状态变量$?。
$ git ls-remote --exit-code --heads git@github.com:user/repo.git branch-name
【讨论】:
git ls-remote --heads ${REPO} ${BRANCH} | grep ${BRANCH} >/dev/null,然后是if [ "$?" == "1" ] ; then echo "Branch doesn't exist"; exit; fi
/refs/heads/branch-name。否则,即使没有branch-name,也会返回分支foo/branch-name。
git ls-remote --heads origin branch-name
--exit-code 必须在 --heads 之前。
这里的所有答案都是特定于 Linux shell 的,如果您处于不支持此类操作的环境(例如 Windows 的命令提示符)中,这将无济于事。
幸运的是,git ls-remote 接受 --exit-code 参数,该参数分别根据分支是否存在返回 0 或 2。所以:
git ls-remote --exit-code --heads origin <branch-that-exists-in-origin>
将返回 0,并且
git ls-remote --exit-code --heads origin <branch-that-only-exists-locally>
将返回 2。
对于 PowerShell,您可以简单地使用内置的真实性处理语义:
if (git ls-remote --heads origin <branch-that-exists-in-origin>) { $true } else
{ $false }
产生$true,而:
if (git ls-remote --heads origin <branch-that-only-exists-locally>) { $true } else
{ $false }
产生$false。
【讨论】:
将返回名称中包含查询的所有分支(远程或本地)。
git branch --all | grep <query>
【讨论】:
我将上面的一些答案合并到一个脚本中:
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
此脚本将从远程bitbucket 中获取4 个分支,并将它们推送到远程github,然后将所有标签推送到github。
我在 Jenkins 作业中使用它,这就是为什么您看不到任何 git fetch 或 git pull,这已在 Jenkins 作业存储库配置中完成。
我通常更喜欢脚本中的长格式选项。我可以使用git checkout -B 组合git branch 和git checkout。
【讨论】:
那么就不需要每次都手动传递仓库名称了。
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
两者都会给出相同的输出:
更多关于起源: Git 有“远程”的概念,它只是指向存储库其他副本的 URL。当您克隆另一个存储库时,Git 会自动创建一个名为“origin”的远程并指向它。您可以通过键入 git remote show origin 来查看有关远程的更多信息。
【讨论】:
你可以试试
git diff --quiet @{u} @{0}
这里@{u}指远程/上游,@{0}指当前本地HEAD(使用较新版本的git,@{0}可以缩写为@)。如果远程不存在,则会出错。
用git 2.16.2(我不确定哪个版本最先有这个功能,比如git 1.7.1没有),你可以这样做
git checkout
如果存在远程分支,会有一些输出,比如
Your branch is up to date with 'origin/master'
否则没有输出。
【讨论】:
我刚试过这个:
git ls-remote --heads 2>/dev/null|awk -F 'refs/heads/' '{print $2}'|grep -x "your-branch"|wc -l
如果找到分支“your-branch”,则返回 1,否则返回 0。
【讨论】:
如果您的分支名称非常具体,您可能不需要使用 grep 进行简单的分支名称匹配:
git ls-remote --heads $(git remote | head -1) "*${BRANCH_NAME}*" | \
cut -d$'\t' -f2 | \
sed 's,refs/heads/,,' | \
wc -l
适用于
BRANCH=master
BRANCH=mas
BRANCH=NonExistingBranch (returns 0)
BRANCH=ISSUE-123
我们使用唯一的问题 ID 作为分支名称,它工作正常。
【讨论】:
$ 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 可能有一段时间。
【讨论】:
grep -x "$branch" 与 grep ^"$branch"$ 相同)。虽然在脚本中我更喜欢长格式开关:--line-regexp。另外,不需要wc -l。将空输出放在 Bash if [ -z ] 中有效地评估为 true,因此这意味着分支不存在。这样可以节省几毫秒。
你也可以这样用:
git show-branch remotes/origin/<<remote-branch-name>>
返回最新的提交和 $?是 0 否则返回 "fatal: bad sha1 reference remotes/origin/" 和 $?是 128
【讨论】:
如果它是一个 git repo 来运行,你可以在当前文件夹中使用的另一种方式
git branch -a | egrep 'remotes/origin/${YOUR_BRANCH_NAME}$'
【讨论】:
git branch -a | egrep "remotes/origin/${YOUR_BRANCH_NAME}$"
git branch -a | grep "\b${BRANCH}$"
git fetch 如果使用 git branch -a 是必需的,因此首先获取所有远程引用。否则使用其他人指出的git ls-remote。
git branch -a --list '<pattern>'也是一个选项。如果您需要脚本的返回码,请通过管道传递给 grep。
您可以在 Bash 终端中执行类似的操作。只需将 echos 替换为您要执行的命令即可。
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
希望对你有帮助。
【讨论】:
您可以使用git remote add something https://github.com/project-name/project-name.git 将您拥有的存储库添加为远程,然后执行git remote show something 以获取有关远程的所有信息。这需要网络连接并且对人类使用很有用。
或者,执行git fetch something。这将获取远程名为something 的所有分支并将它们保存在本地存储库中。然后,您可以根据需要将它们合并到您的本地分支中。我推荐这条路径,因为如果你最终决定必须合并,这就是你需要做的。
OT:您使用“本地签出”表示您是从集中式版本控制系统的角度来处理此问题的。当你处理 git 时,这通常是一个死胡同。它使用“结帐”等词与旧系统的使用方式不同。
【讨论】:
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 ls-remote --exit-code . origin/branch-name &> /dev/null 然后使用$? 作为测试操作数
if git ls-remote ...; then ...; fi 一样,直接在条件中使用命令,比检查$?(可以通过记录语句、陷阱等更改)更不容易出错。
--heads?
--heads 仅列出分支。使用--tags 仅列出标签。