问题
I use git-svn to interact with an existing SVN repository that contains some C++ projects. subwcrev.exe is used as a pre-build event to update some strings in a C++ header (svnversion.h). These strings get hardcompiled to form some version information for the resulting binary.
Since subwcrev requires .svn metadata to work, the pre-build event is going to fail when used on the git-svn working copy. So I came up with the following bash script which I use as post-commit and post-checkout hooks for my git repository. The script tries to do the same thing as subwcrev based on the output of git svn info (cached in a local file).
#!/bin/sh
if [ ! -f svninfo ] ; then
git svn info > svninfo
fi
revision=`sed -e "/Revision/!d" -e "s/Revision: \(.*\)/\1/" svninfo`
lastchange=`sed -e "/Last Changed Rev/!d" -e "s/Last Changed Rev: \(.*\)/\1/" svninfo`
# Get the last changed date, extract timestamp, replaces dashes with slashes
changedate=`sed -e "/Last Changed Date/!d" -e "s/Last Changed Date: \(.\{19\}\).*/\1/" -e "s!-!\\\\\\/!g" svninfo`
now=`date "+%Y\/%m\/%d %H:%M:%S"`
gitcommit=`git show --abbrev-commit | sed -n -e "s/commit //p"`
for entry in $( find -name svnversion_template.h ); do
newname=`echo $entry|sed -e "s/_template//"`
sed -e "s/\\\$WCRANGE\\\$/${revision}/" \
-e "s/\\\$WCREV\\\$/${lastchange}-${gitcommit}/" \
-e "s/\\\$WCDATE\\\$/${changedate}/" \
-e "s/\\\$WCNOW\\\$/${now}/" \
-e "s/\\\$WCURL\\\$/local git repo/" \
-e "s/\\\$WCMODS.*\\\$/(true)/" \
-e "s/\\\$WCMIXED.*\\\$/(false)/" \
$entry > `echo $entry|sed -e "s/_template//"`
done
What I cannot really emulate so far is the automatic detection of a local uncommitted changes (based on the last checked out SVN revision) that makes subwcrev so useful.
I am replacing $WCREV$
with the revision number of the SVN repository (as subwcrev would do) but this time I add my abbreviated git commit hash to identify the code I compiled. My question now is: Is there a way to distinguish in a shell script whether my current HEAD differs from the last fetched SVN revision so that I could omit adding the -${gitcommit}
part and set $WCMODS$
to false?
If there were some thing like a post-"git svn dcommit"
hook, my problem would be solved, too, since then that special hook would create the svnversion.h differently. Can such hook be added somehow?
回答1:
I don't really get your points, but start to improve your script first.
revision=$(grep -Po "(?<=Revision: ).*" svninfo)
lastchange=$(grep -Po "(?<=Last Changed Rev: ).*" svninfo)
# Get the last changed date, extract timestamp, replaces dashes with slashes
changedate=$(grep -Po "(?<=Last Changed Date: ).{19}" svninfo)
changedate=${changedate//-//}
now=$(date "+%Y\/%m\/%d %H:%M:%S")
Then, in for loop, could you please explain detail, what result you need? Can you show one sample of svnversion_template.h ?
回答2:
So it looks like you might have to parse the contents of the git svn info
query yourself to get what is normally stored in WCREV. The example results look like this for me:
git svn info
Path: .
URL: http://myurl.com/trunk/myrepo
Repository Root: http://myurl.com
Repository UUID: 15fed3e9-81ce-ef4a-a7da-fc36e3df1edc
Revision: 14106
Node Kind: directory
Schedule: normal
Last Changed Author: myusername
Last Changed Rev: 14106
Last Changed Date: 2015-05-29 10:23:10 -0400 (Fri, 29 May 2015)
Now for the second part of your question, whether or not you can tell if your git HEAD matches the latest svn checkout, you'll need to use the command git diff git-svn
command. "git-svn" here is the name of the branch that the git-svn program is maintaining, and if everything is up to date, the results will be empty.
来源:https://stackoverflow.com/questions/1954062/emulate-subwcrev-when-using-git-svn