Unquoted variables and command substitutions like $i or $(git …) apply the split+glob operatorsplit+glob operator to the string result. That is:
- Build a string containing the value of the variable or the output of the command (minus final newlines in the latter case).
- Split the string into separate fields according to the value of
IFS. - Interpret each field as a wildcard pattern and replace it by the list of matching file names; if a pattern doesn't match any file, leave it intact.
The output of git branch | grep -v master (step 1) contains * master which is split (step 2) into two fields * and master; * is replaced (step 3) by the list of file names in the current directory.
You can run set -f to temporarily disable globbing. Another approach is to avoid command substitution and instead parse the input with readparse the input with read. Neither do the right thing though — you'll have spurious branch names, because the git output contains more than what you need (the * flag to indicate the current branch, but also things like remotes/somewhere/foo -> bar for remote-tracking branches). I think the following is safe if inelegant:
for i in $(git branch | sed -e 's/^..//' -e 's/ .*//'); do
echo $i
done
I think the robust way is to use git-for-each-ref.
for i in $(git for-each-ref --format='%(refname:short)' refs/heads refs/remotes); do
echo $i
done