1

I have the following bash function :

tg() {
  git add -A && git commit -m $1 && git push
}

But it seems not to work :

$ tg "create index for users"
error: pathspec 'index' did not match any file(s) known to git.
error: pathspec 'for' did not match any file(s) known to git.
error: pathspec 'users' did not match any file(s) known to git.

Obviously, the problem is that the quote was expanded and my middle command was read as git commit -m create index for users rather than git commit -m "create index for users"

What did I do wrong ? How can I fix this ?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

1 Answers1

4

Double quote the expansion $1:

tg() {
  git add -A &&
  git commit -m "$1" &&
  git push
}

By not quoting $1, the shell will split its value on whitespaces (the contents of $IFS) and the resulting words will additionally undergo filename globbing.

Related:

Kusalananda
  • 333,661
  • Thx for your help. I'm confused here : isn't "$1" supposed to be a "heredoc" string and variables inside it are supposed to be expanded ? For example, in the shell echo "$MYVAR" is equivalent to echo $MYVAR ? – Ewan Delanoy Jan 02 '19 at 10:03
  • 2
    @EwanDelanoy You are not using any here-document in your code. A here-document is written utility <<TAG and terminated by TAG (TAG can be any string). It's a form of redirection. echo $var and echo "$var" are not equivalent for the same reasons as I mentioned in my answer. Test with var=*. When it comes to variable expansions and quoting, $var and $1 behaves the same. – Kusalananda Jan 02 '19 at 10:06
  • Got it, thx. I'll try your solution a few times and accept it if it works. – Ewan Delanoy Jan 02 '19 at 10:08
  • 1
    @EwanDelanoy If there's only one "word" and no whitespaces, then echo "$MYVAR" and echo $MYVAR will have same output. But if you have hello world then "$MYVAR" is treated as single word, $MYVAR is split into two words. In this case, this is trivial. If you do ls $MYVAR it can give you file not found if you're looking for hello world file, because ls will look for two files, hello and world, but ls "$MYVAR" will show you the file hello world. – Sergiy Kolodyazhnyy Jan 02 '19 at 10:09
  • 1
    @SergiyKolodyazhnyy That first sentence is true only given that the word contains no filename globbing characters, and that IFS has the default value. – Kusalananda Jan 02 '19 at 10:13
  • @Kusalananda Yep, that too. – Sergiy Kolodyazhnyy Jan 02 '19 at 10:15