update-hook: parse the tag header in preparation to use the tag type
PATCH 3/4 update-hook: parse the tag header in preparation to use the tag type
The tag header is parsed with a while loop and read command. I'm not entirely sure how portable it is, as it had to use the following unusual heredoc format:
while read field value
do
# ..
done <<< "$(some command)"This was necessary because piping the output to a while doesn't work because the pipe is run in a separate process and hence setting variables inside it has no effect in the main script process. This "<<<" heredoc notation works around that problem, but I have no idea how widely supported it is. The alternative (should it be necessary) is to wastefully make multiple "git-cat-file | sed" calls - yuck.
This patch also updates the user/time extraction from the "tagger" field to use the variable $tagger, rather than the "git-cat-file | sed" call used previously.
--- templates/hooks--update | 24 +++++++++++++++++++++--- 1 files changed, 21 insertions(+), 3 deletions(-)
templates/hooks--update +21 -3
@@ -215,15 +215,33 @@ case "$refname_type" in echo " from $oldrev" fi + # Read the tag header + while read field value + do + case "$field" in + object) + tagobject="$value" + ;; + type) + tagtype="$value" + ;; + tag) + # Confirm that this tag has the right name? Nah + ;; + tagger) + tagger="$value" + ;; + esac + done <<< "$(git cat-file tag $newrev | head -q -n 4)" + # If this tag succeeds another, then show which tag it replaces prevtag=$(git describe --abbrev=0 $newrev^ 2>/dev/null) if [ -n "$prevtag" ]; then echo " replaces $prevtag" fi - # Read the tag details - eval $(git cat-file tag $newrev | \ - sed -n '4s/tagger \([^>]*>\)[^0-9]*\([0-9]*\).*/tagger="\1" ts="\2"/p') + # Extract user and time from tagger variable + eval $(sed -n 's/\([^>]*>\)[^0-9]*\([0-9]*\).*/tagger="\1" ts="\2"/p' <<< "$tagger") tagged=$(date --date="1970-01-01 00:00:00 +0000 $ts seconds" +"$DATEFORMAT") echo " tagged by $tagger"
Signature · 1 line
1.5.0.3.402.g0c48
Quoted 8 lines · Andy Parkins
The tag header is parsed with a while loop and read command. I'm not entirely sure how portable it is, as it had to use the following unusual heredoc format:
while read field value do # .. done <<< "$(some command)"
To bad you can't use for-each-ref. ;-)
The problem of course is the update hook is running before a ref is created to point at the tag. If you used post-receive hook on the other hand... Oh, right, that has its own problems too!
Signature · 1 line
Shawn.
Quoted 3 lines · Shawn O. Pearce
The problem of course is the update hook is running before a ref is created to point at the tag. If you used post-receive hook on the other hand... Oh, right, that has its own problems too!
I've obviously not described the problem very well; as I don't understand how your comment relates to this patch.
All I'm doing is pulling the individual fields out of
$ git cat-file -p v1.5.0 object 437b1b20df4b356c9342dac8d38849f24ef44f27 type commit tag v1.5.0 tagger Junio C Hamano <[email protected]> Wed Feb 14 00:00:00 2007 +0000
And putting them in their own variables. I'm not sure how for-each-ref or in fact, any ref-based tool would help me do this. At this point it's nothing to do with git, it's a standard shell script problem.
git cat-file -p $newrev | while read field value
do
variable = "found"
done
echo $variable
Doesn't work, because the right half of the pipe is run in its own process and so setting "variable" has no effect once the while loop is over.
I found that "<<<" heredoc thing in the bash manual, which is almost like having a reverse pipe and allows the while loop to run in the main process.
Andy
Signature · 2 lines
Dr Andy Parkins, M Eng (hons), MIET [email protected]
Quoted 9 lines · Andy Parkins
Quoted 3 lines · Shawn O. Pearce
The problem of course is the update hook is running before a ref is created to point at the tag. If you used post-receive hook on the other hand... Oh, right, that has its own problems too!
I've obviously not described the problem very well; as I don't understand how your comment relates to this patch.
eval git for-each-ref --format='taggername=%(taggername) taggerdate=%(taggerdate)' thetag
Then you have $taggername and $taggerdate available. ;-)
The problem is, there is no ref to for-each over. :-(
Signature · 1 line
Shawn.