When I run the command
git cherry origin/Server_Dev
in my git repository, I get a list of commits of the form
+ 95b117c39869a810595f1e169c64e728d2d7443d
+ e126f1b996ecf1d2a8cf744c74daa92cce338123
+ 869169a6cb0bbe8f1922838798580a1e74ec3884
+ 667819b617c88bd886dc2001f612b5c7a4d396c3
+ fd41328a84b0a127affa6fe4328c93e933de378c
+ cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
This is a good thing.
I now want to execute this command from within a bash script and capture the output into an array using the following code:
commit_hashes=(`git cherry origin/Dev`)
echo ${commit_hashes[@]}
which yields the following output:
+ 95b117c39869a810595f1e169c64e728d2d7443d + e126f1b996ecf1d2a8cf744c74daa92cce338123 + 869169a6cb0bbe8f1922838798580a1e74ec3884 + 667819b617c88bd886dc2001f612b5c7a4d396c3 + fd41328a84b0a127affa6fe432
8c93e933de378c + cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
This is not a good thing
My list of commits is being returned as a string which I must first break up before I can use it. After some searching I found out that if I add IFS=""
to my script before the capturing of the data, my problems would be solved.
So I edited my code to read
IFS=""
commit_hashes=(`git cherry origin/Dev`)
echo ${commit_hashes[@]}
which output
+ 95b117c39869a810595f1e169c64e728d2d7443d
+ e126f1b996ecf1d2a8cf744c74daa92cce338123
+ 869169a6cb0bbe8f1922838798580a1e74ec3884
+ 667819b617c88bd886dc2001f612b5c7a4d396c3
+ fd41328a84b0a127affa6fe4328c93e933de378c
+ cfe1807e5d4acc6b5e75f4463dadb3b1c957376f
This completely ended my sense of reality.
I like to know why things are doing what they're doing, so after some more searching I found out that this is called the Internal Field Separator
and it is used on Unix systems by command interpretors to figure where to break patterns up into tokens.
This I understand.
What I don't understand is
Some help in getting my head around these three points would be appreciated.
See man bash/Arrays. Everything is fine with your array. When you do
echo ${commit_hashes[@]}
echo shows all array elements on one line, as it is told to. When you say
for i in `seq 10`; do
echo ${commit_hashes[$i]}
done
you will see that just one entry per line is shown.
When you set IFS=
to an empty string however, the result of git cherry
isn't broken up into multiple values. The whole string including the newlines is assigned to the first array element. If you
echo ${commit_hashes[0]}
in your second case, you will see, that echo shows all output lines.