检查while循环中是否存在git分支

检查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 我试过一些方法,比如使用不同类型的引号,只是引号,等等。。毫无乐趣 正确的方法是什么?您的代码

您好,我正在尝试提示用户输入要推送到的分支。如果用户输入了错误的名称,我会尽力处理。我对bash没有太多经验,但我真的很喜欢它

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