Re: git-send-mail in sh
- From
Junio C Hamano <junkio@cox.net>
- Date
- Nov 27, 2005, 22:01 UTC
- Message-ID
- <7v4q5xbvip.fsf@assigned-by-dhcp.cox.net>
- In-Reply-To
- <4388E33A.8000004@op5.se>
Andreas Ericsson <ae@op5.se> writes:
> Here's what I have on disk right now. The ${var##*^} syntax was decided
> to be portable in some earlier discussion, so I'm sticking with it
> (mostly because I don't know how to do it with expr and Junio pokes me
> when I do it with sed. Enlightenment welcome).The ${parameter##word} syntax is in IEEE 1003.1-2001, and bash, ksh, and dash seem to work with it. That does not necessarily mean it is "portable" but I won't be so worried about shells that do not grok this. Input from people on non-Linux platforms are appreciated.
Show 10 quoted lines
> if [ "$com2" ]; then
> range="$com1..$com2"
> else
> case "$com1" in
>...
> ?*^)
> # single commit
> com1="${com1##*^}"
> range="$com1^1..$com1"
> ;;I wonder if you meant "${com1%^}" here, to remove the trailing '^'.Show 8 quoted lines
> ?*^[0-9]|?*^[0-9][0-9])
> # series of commits, ranging back from <commit-ish>
> range="$com1..${com1%%^*}"
> ;;
> ^[0-9]|^[0-9][0-9])
> # series of commits, ranging back from HEAD
> range="HEAD$com1..HEAD"
> ;;N generation back in extended SHA1 notation uses a tilde '~', e.g. "HEAD~5" is five commits back from the current HEAD, so I'd prefer being consistent with that (HEAD^5 means the fifth parent of an octopus merge commit). Also limiting to between 0 and 99 generations misinterprets "HEAD~123".
Although checking only the letter that follows the tilde is a digit mistakenly accepts something like "master~1-bad-one", that is already malformed and whatever comes downstream would barf, so that may be fine. How about something like:
?*'~'[1-9]*)
range="$com1..${com1%~*}" ;;
'~'[1-9]*)
range="HEAD$com1..HEAD" ;;I do not have aversion against echo piped to sed in general, by the way. I *would* redicule people who write something like this, though:
case "$git" in
*/.git) printname=`echo "$git" | sed -e 's/\/\.git$//'` ;;
*) printname=$git ;;
esacIt should be spelled `expr "$git" : '\(.*\)/\.git$'` (or "${git%/.git}" if we know the shell is POSIX), for this particular one, since we already know it ends with "/.git". But if all you want to do is to drop an *optional* trailing "/.git" (i.e. your input may or may not end with "/.git"), a single:
printname=`echo "$git" | sed -e 's/\/\.git$//'`
without surrounding case may be adequate; it forks sed when it does not have the optional /.git part, though. And if you are dropping optional /.git or .git (think of prettyprinting uemacs/.git and git.git), then echo-to-sed without surrounding "case" is probably easier to read:
printname=`echo "$git" | sed -e 's/\/*\.git$//'`
unless you want to avoid fork, in which case it would be:
case "$git" in
*/.git) printname=${git%/.git} ;;
*.git) printname=${git%.git} ;;
*) printname=$git ;;
esac