问题
I am currently trying to create a pre-commit hook that prevent user to tag a version of code with external that are not tags.
I am just trying to figure out a way to get the external that are specify in a transaction but cant figure out how. The command svnlook dont seem to be able to return anything that remotely look like externals modification. And with the svn command it seem to be the transaction that I am unable to specify. I have no idea what command to use in my pre-commit hook. I am currently in windows but making a python script to be able to test this on our linux server.
What I tested so far is the following :
svnlook propget C:\TestReposLocal svn:externals <== Give me error something is missing
svn propget svn:externals C:\Test <== Give me externals but I cant figure out how to get this from a transaction to place in a pre-commit hook.
In my repository (C:\TestReposLocal) I have one external that is the trunk of another repository. This repository is displayed with the svn propget command but I need to know with the current transaction in a pre-commit if this external is something else than a Tag.
Any help would be gladly receive.
Tnx
回答1:
Well, I can't see really your trouble-point here
- Any (almost any) operation in pre-commit hook with transaction (and local repo) can be performed with
svnlook
- svnlook have subcommand propget, with can operate on transaction level and extract any property from any path inside repo (transaction in this case), and you must already know, there you can meet externals inside repo-tree
- you can identify correct|needed format of externals from any previous revision inside repo
Edit
OK, I see: additional details is needed here. For tests and experimenting I used open repository Proving Ground for externals on Assembla, which have PEG-ed revision in tags and not PEG-ed in trunk. In order to use svnlook locally I just svnrdump'ed it into local repository.
- Nearest equivalent to getting property from transaction is getting it from committed revision.
Tag 1.0.1 was created with r7
>svnlook pg rep svn:externals tags/1.0.1/ -r 7
-r 2 https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib@2 lib
where:
rep
is relative path to repository on local filesystemtags/1.0.1/
is path inside repository, for which I previously know, that it should have definition-r 7
is revision, which I want to test
Tag was created from trunk, in which external is not binded to specific revision
>svnlook pg rep svn:externals trunk/ -r 6
https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib lib
You'll have to see difference in specification now
WARNING: format of externals-definition will be different in case of using ancient (pre 1.4) SVN-clients and can be slightly different (can't recall exact details) in case of using CLI-version of SVN or SVN-integration from IDE (definitions above I created with TortoiseSVN), but it will be your part of job
- I order to apply business logic of hook only when it needed (for commits in /tags only) and finish commits faster, you have also check in hook (at early stages) additional condition - is this commit tag-related or not. It's again svnlook and
dirs-changed
subcommand
dirs-changed
for commit into tags
>svnlook dirs-changed rep -r 7
tags/
tags/1.0.1/
dirs-changed
for commit into other location
>svnlook dirs-changed rep -r 6
trunk/
you can |grep tags
in good OS, do some tricks in Windows, operate according to results
PS: Don't forget replace -r
with -t
on production and store transaction-id+repo-path, which you'll get as parameters for hook
回答2:
This just work for me
REPOS="$1"
TXN="$2"
SVNLOOK=svnlook
Grep_In_List()
{
EX_STATUS=1
while read line
do
echo "$line" | grep "$1" > /dev/null
if [[ $? == 0 ]]
then
echo "$line"
EX_STATUS=0
fi
done
exit $EX_STATUS
}
CHANGED_PATHS=$($SVNLOOK dirs-changed -t "$TXN" "$REPOS" | Grep_In_List "^tags")
if [[ $? != 0 ]]
then
# no tags
exit 0
fi
CHANGED_SUB_PATHS=$(echo $CHANGED_PATHS | xargs -I {} $SVNLOOK tree "$REPOS" "{}" --full-paths -t "$TXN" | sort | uniq | xargs -I {} echo "{}\n")
CHANGED_EXTERNALS=$(echo $CHANGED_SUB_PATHS | xargs -I {} $SVNLOOK pg "$REPOS" svn:externals "{}" -t "$TXN" 2>/dev/null | xargs -I {} echo "{}")
while read external
do
echo "$external" | grep ' -r' > /dev/null
if [[ $? != 0 ]]
then
echo "$external does not have an explicit revision number" 1>&2
exit 1
fi
done <<<"$CHANGED_EXTERNALS"
# all tags correct
exit 0
来源:https://stackoverflow.com/questions/23013918/trying-to-create-a-pre-commit-hook-that-verify-externals