0

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

wincrasher
  • 121
  • 1
  • 10
  • 1
    The real solution to your problem starts with getting rid of svn:exterals for the reasons you're encountering (and more) – thekbb Apr 11 '14 at 14:25
  • That would be difficult. We are a compagny and we each sector have a repository to put our stuff in them. We each have a version of our repository and are modified frequently. And our SDK is a melting pot of every part the compagny is working on. When we release a tag we tag every external and release a version containing only tags. Which is why I need to have a pre-commit that validate that external are tags. – wincrasher Apr 11 '14 at 14:47
  • 2
    @thekbb - don't "fix" the things, which **are not broken**!!! And don't dictate policy for company, which you don't own – Lazy Badger Apr 12 '14 at 10:05
  • 1
    I'm not dictating policy - just making the observation that svn:externals are very very rarely used in a way that makes things easier. Without knowing more it's hard to recommend an alternative... However the OP did mention an SDK, it seems odd that the source of an SDK would be needed. – thekbb Apr 14 '14 at 15:04

2 Answers2

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:

  1. rep is relative path to repository on local filesystem
  2. tags/1.0.1/ is path inside repository, for which I previously know, that it should have definition
  3. -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

Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
  • My problem is that I cant seem to figure out how to write the command line properly for a transaction. In my above example I wrote : `svnlook propget C:\TestReposLocal svn:externals` I was missing /trunk at the end. This is to be able to validate a already existing path in the repository. What I am trying to do is to be able to see which externals are being commit in a transaction I guess the line should look like `svnlook propget C:\TestReposLocal svn:externals -t 12-2c` or whatever the transaction number is. But this does not work. It always say property name missing. – wincrasher Apr 14 '14 at 12:38
0

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
Andrey
  • 11
  • 1
  • 3