git-sh-setup: refactor ident-parsing functions

The only ident-parsing function we currently provide is get_author_ident_from_commit. This is not very flexible for two reasons: 1. It takes a commit as an argument, and can't read from commit headers saved on disk. 2. It will only parse authors, not committers. This patch provides a more flexible interface which will parse multiple idents from a commit provide on stdin. We can easily use it as a building block for the current function to retain compatibility. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Oct 18, 2012 at 03:25 UTC ce80ca566af713c85ce3a1c20b466486058a971a
1 file changed +43 -19
git-sh-setup.sh
+43 -19
@@ -191,28 +191,52 @@ require_clean_work_tree () {
191 fi
192 }
193
194 +# Generate a sed script to parse identities from a commit.
195 +#
196 +# Reads the commit from stdin, which should be in raw format (e.g., from
197 +# cat-file or "--pretty=raw").
198 +#
199 +# The first argument specifies the ident line to parse (e.g., "author"), and
200 +# the second specifies the environment variable to put it in (e.g., "AUTHOR"
201 +# for "GIT_AUTHOR_*"). Multiple pairs can be given to parse author and
202 +# committer.
203 +pick_ident_script () {
204 + while test $# -gt 0
205 + do
206 + lid=$1; shift
207 + uid=$1; shift
208 + printf '%s' "
209 + /^$lid /{
210 + s/'/'\\\\''/g
211 + h
212 + s/^$lid "'\([^<]*\) <[^>]*> .*$/\1/'"
213 + s/.*/GIT_${uid}_NAME='&'/p
214 +
215 + g
216 + s/^$lid "'[^<]* <\([^>]*\)> .*$/\1/'"
217 + s/.*/GIT_${uid}_EMAIL='&'/p
218 +
219 + g
220 + s/^$lid "'[^<]* <[^>]*> \(.*\)$/@\1/'"
221 + s/.*/GIT_${uid}_DATE='&'/p
222 + }
223 + "
224 + done
225 + echo '/^$/q'
226 +}
227 +
228 +# Create a pick-script as above and feed it to sed. Stdout is suitable for
229 +# feeding to eval.
230 +parse_ident_from_commit () {
231 + LANG=C LC_ALL=C sed -ne "$(pick_ident_script "$@")"
232 +}
233 +
234 +# Parse the author from a commit given as an argument. Stdout is suitable for
235 +# feeding to eval to set the usual GIT_* ident variables.
236 get_author_ident_from_commit () {
195 - pick_author_script='
196 - /^author /{
197 - s/'\''/'\''\\'\'\''/g
198 - h
199 - s/^author \([^<]*\) <[^>]*> .*$/\1/
200 - s/.*/GIT_AUTHOR_NAME='\''&'\''/p
201 -
202 - g
203 - s/^author [^<]* <\([^>]*\)> .*$/\1/
204 - s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
205 -
206 - g
207 - s/^author [^<]* <[^>]*> \(.*\)$/@\1/
208 - s/.*/GIT_AUTHOR_DATE='\''&'\''/p
209 -
210 - q
211 - }
212 - '
237 encoding=$(git config i18n.commitencoding || echo UTF-8)
238 git show -s --pretty=raw --encoding="$encoding" "$1" -- |
215 - LANG=C LC_ALL=C sed -ne "$pick_author_script"
239 + parse_ident_from_commit author AUTHOR
240 }
241
242 # Clear repo-local GIT_* environment variables. Useful when switching to