Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
872 views
in Technique[技术] by (71.8m points)

bash - Git config alias escaping

I'm trying to write a git alias that removes from the commit messages the string "[ci skip]" (placed at the end of the message), but I'm having problem with escaping. The alias takes all the commit from the one passed as argument to HEAD.

If I run the following command:

git filter-branch -f --msg-filter "sed -e "s/[ci skip]$//g"" master..HEAD

it works as expected. Anyway if I create the following alias:

unwip = !sh -c 'git filter-branch -f --msg-filter "sed -e "s/[ci skip]$//g"" $0..HEAD'

and I run git unwip master it complains about bad config, but I expect it to behave as the previous commads. How can I fix this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Generic solution

Getting a git alias to pass the parser correctly can be a mind-boggling set of " noise, so I created two aliases:

# Quote / unquote a sh command, converting it to / from a git alias string
quote-string = "!read -r l; printf "!; printf %s "$l" | sed 's/\(["]\)/\\\1/g'; printf " #"\n" #"
quote-string-undo = "!read -r l; printf %s "$l" | sed 's/\\\(["]\)/\1/g'; printf "\n" #"

This allows you to convert anything you could type into sh+, eg:

$ echo '"'

"

Into a quoted string fit for an alias:

$ git quote-string
echo '"'

"!echo '"' #"

To quote a multi-line string, I wrote a longer script, which I suggest you run as:

git quote-string |sponge

Answering OP's specific issue

Using git quote-string on the OP's command, I get:

"!git filter-branch -f --msg-filter "sed -e "s/\[ci skip\]$//g"" master..HEAD #"

So, to use the OP's preferred alias name, under [alias] in ~/.gitconfig, add:

unwip = "!git filter-branch -f --msg-filter "sed -e "s/\[ci skip\]$//g"" master..HEAD #"

Debugging

Sometimes it's nice to see what is going on under the hood. Try this alias:

debug  = "!set -x; GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git"

Just insert debug between git and whatever would usually follow, eg for the OP's question:

git debug unwip


+ git uses /bin/sh to execute aliases beginning with !*. To work around this, create a command line like: bash -c 'echo "' and then pass this to git quote-string.

* See the "Debugging" heading for proof


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...