bash - Check if git branch exists in while loop -


hi there trying prompt user branch push to. im trying handle if user enter wrong name. dont have experience bash enjoying it.

while [ "$(git branch --list ${branch_name})" ]     read -r -p "${blue}what branch want push to: ${reset}" branch_name  done 

i have tried few things using different type of quotes, quotes, ect .. no joy.

what correct way

addressing, first, git side of things, you're doing may inadvisable in first place.

is wise?

your question asks: what branch want push to? (emphasis mine), git push takes refspec, represents two potentially different branch names: local name, in own repository, can match against existing branches in local repository, , foreign name, in other git repository. foreign branch name not need exist in first place. if does exist, not have match local branch name.

for instance, can:

git push origin head:newbranch 

to push current commit newly-created branch on origin.

shell code test whether name valid branch name

all said, if wish check whether shell variable holds valid branch name (as opposed other string can resolved commit id, such head or ac0ffee or v2.1.3), way find out is, generally, use git rev-parse fully qualify name. there several subtle traps here though:

$ 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 

hence might try:

is_branch() {     local name="$1" fullname      if fullname=$(git rev-parse --symbolic-full-name \             --verify --quiet "$name");         case "$fullname" in         refs/heads/*) return 0;; # valid branch name         esac     fi     return 1 # not valid branch name } 

however:

$ git rev-parse --symbolic-full-name --verify --quiet head refs/heads/master 

it turns out follows symbolic names (such head when not "detached") , expands them corresponding target. any symbolic name, although head normal local symbolic name, if wish disallow head, have 2 obvious options:

  • see if name literal string head (catches 1 common case), or
  • use git symbolic-ref see if name symbolic reference (catches cases).

another, less obvious option use git rev-parse --abbrev-rev, produces short form of target name of symbolic reference:

$ git rev-parse --abbrev-ref master master $ git rev-parse --abbrev-ref head master 

we compare output against input: if same, name not symbolic reference. flaw here if name tag name, abbreviated reference name still itself:

$ git rev-parse --abbrev-ref v2.1.1 v2.1.1 

so still need full-name check anyway. recommend git symbolic-ref here, e.g.:

is_branch() {     local name="$1" fullname      if fullname=$(git rev-parse --symbolic-full-name \             --verify --quiet "$name");         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 valid branch name } 

but, only if have reason explicitly reject indirect names head. (note git push origin head:head bad idea, git push origin head not bad, since git locally resolve indirection and, in effect, git push origin refs/heads/master:refs/heads/master if head symbolic name master. if head detached won't resolve branch name in first place, particular case not problem here.)

putting together

now have is_branch, can use that:

while ! is_branch "$branch_name";     ... done 

note may idea list branch name options (i.e., run git branch --list) inside loop, got free before.


Comments