Hugo Sum
Hugo Sum

Reputation: 243

git commit error: pathspec 'xxx' did not match any file(s) known to git

I wrote a bash script to update my files through git automatically, but I keep getting error for the git commit line, if my message contains error.

I have already wrapped my message with quote, what's wrong here?

My bash script:

##Handle local git update
remote='
cd express-demo-nonbare;
git pull origin master;
';

echo "Process for updating Git begin";
git add . ;
read -p "Message for this commit: " comment;
comment=\"${comment}\";
echo $comment;
git commit --message=$comment;
git push backup master;

Upvotes: 0

Views: 3795

Answers (2)

torek
torek

Reputation: 487725

You don't want to, as you put it:

wrap... my message with quote

(which is indeed what you are doing). Instead, you want to protect your message from having bash treat it as a list of words. To do that, you need quotes, but in a different position:

remote='
cd express-demo-nonbare;
git pull origin master;
'

echo "Process for updating Git begin"
git add .
read -p "Message for this commit: " comment
echo "$comment"
git commit --message="$comment"
git push backup master

I removed all non-essential semicolons as well (bash treats the end of a line as the end of the command, unless something like an unclosed parenthesis or brace prevents this).

It's not clear to me what your intent is in setting the variable remote to the literal string newlinecdspaceex...;newline, especially since $remote does not occur later in the script. Note, however, that since this string does include white-space, expanding it outside quotes, as in $remote (vs "$remote" which expands it inside quotes) can trigger further shell actions. For instance:

foo='this; that'
wc $foo

will have the wc program attempt to open files named this; and that, having split $foo at the white spaces into separate words that are then passed to wc. This splitting is actually based on $IFS:

IFS=+
foo='this+that'
wc $foo

tries to open files named this and that. Restoring IFS to its normal setting:

wc $foo

tries to open one file named this+that.

(I sometimes use wc as a program to help show what the actual arguments were, since it tries to open each one as a file name, and spits out the actual file name in any subsequent error message or count.)

Similarly, if the expansion of a variable produces shell glob metacharacters, these will be evaluated after the expansion:

foo='*'
wc $foo

will try to open and read every file and directory in the current directory. Again, double quotes will protect against this:

wc "$foo"

will only try to open and read one file, named *.

Upvotes: 1

rtx13
rtx13

Reputation: 2610

Really you just need to quote the comment variable when supplying it to git commit. You can replace:

read -p "Message for this commit: " comment;
comment=\"${comment}\";
echo $comment;
git commit --message=$comment;

with

read -p "Message for this commit: " comment;
echo $comment;
git commit --message="$comment";

The quotes will not be part of the commit message, rather they are consumed by bash in ensuring that the entire content of the comment variable is submitted as part of a single --message=... argument to git, even if it contains whitespace characters.

Upvotes: 2

Related Questions