When you place [double quotes][1] around an [expansion][2], such as the [parameter expansion][3] `$*`, the expanded text is not subject to [word splitting][4]. (That's one of the reasons to use double quotes around `$` expansions; the other is to prevent [globbing][5].) Furthermore, inside double quotes, [single quotes][6] are not treated specially, so they do not perform quoting and they are not [removed][7].
So, as [Michael Homer says][8], you can just **omit the spurious `'` `'` marks** and your function should work. I suggest writing it like this:
<!-- language: lang-bash -->
gac() {
git add .
git commit -m "$*"
}
You can use the `function` keyword to define functions in Bash but the syntax shown above works just as well and is portable across Bourne-style shells.
---
To address the conceptual issue here more directly, this line in your original code shows that you wanted to expand a parameter whose value contained spaces, in such a way that you could pass it as a single argument to `git`:
<!-- language: lang-bash -->
concatenated="'$*'"
When you write a single argument yourself that contains spaces, you quote the spaces, usually with quotes around the whole string. The presence of `'` `'` *inside* the `"` `"` in that line tells me that you were trying to include the quotes that you would normally type.
The reason that approach does not work is that **it is the shell, and not the `git` command, to which quoting is significant**. Suppose you have the command:
some-command 'foo bar' baz
That command does not actually pass any quotation marks to the `some-command` command. Instead, it runs `some-command` with `foo bar` as [argument][9] 1 and `baz` as argument 2. (There is also an argument 0, which tells a program how it was run; the shell passes `some-command` for that.)
Using quotes enables you to *tell the shell* where arguments begin and end. Spaces normally tell the shell to perform word splitting, but you want to suppress the spaces' special meaning to the shell, which is what quoting does. When quotes are quoted, like the inner `'` `'` inside `"` `"`, that removes *their* special meaning too. Then they don't perform quoting, but are instead passed literally to your command, as `git` showed in its log:
a382806 'one two three'
[1]: https://www.gnu.org/software/bash/manual/bash.html#Double-Quotes
[2]: https://www.gnu.org/software/bash/manual/bash.html#Shell-Expansions
[3]: https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
[4]: https://www.gnu.org/software/bash/manual/bash.html#Word-Splitting
[5]: https://www.gnu.org/software/bash/manual/bash.html#Filename-Expansion
[6]: https://www.gnu.org/software/bash/manual/bash.html#Single-Quotes
[7]: https://www.gnu.org/software/bash/manual/bash.html#Quote-Removal
[8]: https://unix.stackexchange.com/questions/399774/passing-string-containing-spaces-as-command-line-argument-from-within-script#comment713953_399774
[9]: https://en.wikipedia.org/wiki/Command-line_interface#Arguments