检查while循环中是否存在git branch

时间:2017-04-05 20:49:48

标签: 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

我尝试了一些使用不同类型的引号,只是引用等等,没有任何快乐。

什么是正确的方法

2 个答案:

答案 0 :(得分:0)

您的代码不起作用,因为您要求的内容如

  

只要[分支列表],请向用户询问分支名称。

你必须写

  

只要[用户输入]不在[分支机构列表]中,请询问用户是否有分支名称。

尝试

branch_name=
while ! grep -qwF "$branch_name" <(git branch --list)
do
    read -r -p "${BLUE}What branch do you want to push to: ${RESET}" branch_name 
done

grep部分在分支列表中搜索输入的分支名称,如果找到分支名称,则返回0(= true = success)。由于只要分支 not 存在,我们就想要分支名称,我们使用!否定退出代码。或者,您可以写until grep而不是while ! grep

答案 1 :(得分:0)

首先,只是Git方面的问题,你所做的事情一开始可能是不可取的。

这是明智的吗?

您的问题是:您希望推送到哪个分支?(强调我的),但git push需要 refspec ,表示两个可能不同的分支名称: local 名称,位于您自己的存储库中,您可以与本地存储库中的现有分支进行匹配,以及外部名称,在某些其他 Git存储库中。外部分支名称甚至不需要存在。如果 存在,则不必匹配本地分支名称。

例如,我可以:

git push origin HEAD:newbranch

将我当前的提交推送到origin上新创建的分支。

用于测试名称是否为有效分支名称的Shell代码

所有这一切,如果你想检查shell变量是否包含有效的分支名称(而不是可以解析为提交ID的其他字符串,例如{{1}或HEADac0ffee),一般来说,找出方法是使用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是唯一正常的本地符号名称,因此如果您希望禁用HEAD,则有两个明显的选项:

  • 查看名称是否为文字字符串HEAD(捕获一个常见情况),或
  • 使用HEAD查看该名称是否为符号引用(捕获所有案例)。

另一个不太明显的选择是使用git symbolic-ref,它会生成符号引用的 target 名称的简短形式:

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将本地解决间接问题,实际上git push origin HEAD如果git push origin refs/heads/master:refs/heads/masterHEAD的符号名称。如果master 已分离,则首先不会解析为任何分支名称,因此特定情况这不是问题。)

把它放在一起

现在我们有HEAD,我们可以使用:

is_branch

请注意,在循环中列出分支名称选项(即运行while ! is_branch "$branch_name"; do ... done )可能是一个好主意,这是您之前有效获得的。