Reputation: 1439
I'm trying to run a simple loop over some local git branches, but whenever I run the loop and echo the lines, I'm seeing it echo all of the files/directories in my current working directory. I don't have much bash experience so I'm confused why the outputs would be different.
git branch --merged
shows me what I expect, only branches.
for l in $( git branch --merged ); do echo $l; done
This is first showing all of the files/directories and then the branches, which I do not want to iterate over.
Upvotes: 0
Views: 67
Reputation: 361869
*
will get expanded as a glob. To avoid this you need to quote the expansion of $l
.
# Partial fix
for l in $(git branch --merged); do echo "$l"; done
Wait, that doesn't work. You also need to avoid $(...)
being subject to glob expansion, which is trickier. To do that you could (temporarily) disable globbing:
# Works, but clumsy
set -o noglob
for l in $(git branch --merged); do echo "$l"; done
Not ideal: it prints *
and master
on separate lines. It also changes a global option that affects other commands. Better to leave shell options alone and use a while read
loop instead.
# Best
while IFS= read -r l; do
echo "$l"
done < <(git branch --merged)
There are two tricky bits here. One is using while read; do ...; done < file
to read lines from a file. The syntax is weird but it applies the < file
redirection to the entire loop. The other bit is using <(...)
process substitution to use the output of git branch --merged
where a filename is normally expected.
Upvotes: 3
Reputation: 979
The current branch is marked with a *
, this is being interpreted as a pattern that matches all files (expect those starting with .
). Two options I see right away are:
Change the Internal Field Separator to newline only.
IFS='
'
for l in $(git branch --merged); do echo $l; done
Remove the *
from the result.
for l in $(git branch --merged | tr -d '*'); do echo $l; done
Upvotes: 0