检查while循环中是否存在git分支
您好,我正在尝试提示用户输入要推送到的分支。如果用户输入了错误的名称,我会尽力处理。我对bash没有太多经验,但我真的很喜欢它检查while循环中是否存在git分支,git,bash,Git,Bash,您好,我正在尝试提示用户输入要推送到的分支。如果用户输入了错误的名称,我会尽力处理。我对bash没有太多经验,但我真的很喜欢它 while [ "$(git branch --list ${branch_name})" ] do read -r -p "${BLUE}What branch do you want to push to: ${RESET}" branch_name done 我试过一些方法,比如使用不同类型的引号,只是引号,等等。。毫无乐趣 正确的方法是什么?您的代码
while [ "$(git branch --list ${branch_name})" ]
do
read -r -p "${BLUE}What branch do you want to push to: ${RESET}" branch_name
done
我试过一些方法,比如使用不同类型的引号,只是引号,等等。。毫无乐趣
正确的方法是什么?您的代码不起作用,因为您要求的是 只要[list of Branchs],请用户输入分支名称 你必须写作 只要[user input]不在[list of Branchs]中,请用户输入分支名称 试一试
分支机构名称=
虽然grep-qwF“$branch_name”寻址,首先,只处理Git方面的事情,首先,您所做的可能是不可取的
这明智吗?
您的问题是:您希望推到哪个分支机构?(emphasis mine),但是git push
采用了一个refspec,它表示两个可能不同的分支名称:一个本地名称,在您自己的存储库中,您可以与本地存储库中的现有分支进行匹配;另一个外来名称,在其他一些git存储库中。外部分支名称甚至不需要首先存在。如果它确实存在,则不必与本地分支名称匹配
例如,我可以:
git push origin HEAD:newbranch
将当前提交推送到origin
上新创建的分支
用于测试名称是否为有效分支名称的Shell代码
综上所述,如果您希望检查shell变量是否持有有效的分支名称(而不是可以解析为提交ID的其他字符串,例如HEAD
或ac0ffee
或v2.1.3
),通常,找到的方法是使用git rev parse
来完全限定名称。不过,这里有几个微妙的陷阱:
$ git rev-parse --symbolic-full-name --verify --quiet master
refs/heads/master
$ git rev-parse --symbolic-full-name --verify --quiet asdf
$ echo $?
1
$ git rev-parse --symbolic-full-name --verify --quiet v2.1.1
refs/tags/v2.1.1
因此,我们可以尝试:
is_branch() {
local name="$1" fullname
if fullname=$(git rev-parse --symbolic-full-name \
--verify --quiet "$name"); then
case "$fullname" in
refs/heads/*) return 0;; # valid branch name
esac
fi
return 1 # not a valid branch name
}
然而:
$ git rev-parse --symbolic-full-name --verify --quiet HEAD
refs/heads/master
事实证明,这会跟随符号名(例如,当它未“分离”时,会跟随HEAD
),并将它们扩展到相应的目标。它对任何符号名都执行此操作,尽管头
是唯一正常的本地符号名,因此如果您希望禁止头
,您有两个明显的选项:
- 查看名称是否为文本字符串
头
(捕获一个常见的大小写),或者
- 使用
git symbolic ref
查看名称是否为符号引用(捕获所有案例)
另一个不太明显的选项是使用git rev parse--abbrev rev
,它生成符号引用的目标名称的缩写形式:
$ git rev-parse --abbrev-ref master
master
$ git rev-parse --abbrev-ref HEAD
master
然后,我们可以将输出与输入进行比较:如果它们相同,则名称不是符号引用。此处的缺陷在于,如果名称是标记名,则其缩写引用名仍然是其自身:
$ git rev-parse --abbrev-ref v2.1.1
v2.1.1
所以我们还是需要查一下全名。因此,我建议在这里使用git symbolic ref
,例如:
is_branch() {
local name="$1" fullname
if fullname=$(git rev-parse --symbolic-full-name \
--verify --quiet "$name"); then
case "$fullname" in
refs/heads/*) # valid branch name; check if symbolic
git symbolic-ref --quiet "$name" >/dev/null && return 0
;;
esac
fi
return 1 # not a valid branch name
}
但是,只有当您有理由明确拒绝像HEAD
这样的间接名称时,才可以这样做。(请注意,git-push-origin-HEAD:HEAD
通常是个坏主意,但是git-push-origin-HEAD
并不是那么坏,因为您的git将局部解析间接寻址,实际上,git-push-origin-refs/heads/master:refs/heads/master
如果HEAD
是master
的符号名。如果HEAD
i它首先不会解析为任何分支名称,因此这种特殊情况在这里不是问题。)
把它放在一起
现在我们有了一个is_分支
,我们可以使用它:
while ! is_branch "$branch_name"; do
...
done
请注意,在循环中列出分支名称选项(即运行git branch--list
)可能是个好主意,这是您以前免费获得的东西。Legend,谢谢你的回复,我相信很多人都会从这篇文章中受益。如果分支只在git ls remote
@CodyChan中列出,那就行不通了:如果git ls remote
列出了分支名称,你没有分支名称,他们(远程)有分支名称。他们的分行名称不是你的分行名称!如果要获取该分支名称,必须选择一个提交(在存储库中),确保该提交存在于存储库中,然后创建该分支名称(在存储库中)。这是一个git fetch的作业,外加一个git命令。
while ! is_branch "$branch_name"; do
...
done