# Svn pre-commit hook

**URL:** <https://rubytalk.org/t/svn-pre-commit-hook/25646>\
**Category:** ruby-talk\
**Created:** [10 March 2006 21:28 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646 "2006-03-10T21:28:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![BIl\_Kleb1](https://avatars.discourse-cdn.com/v4/letter/b/a587f6/32.png) [@BIl\_Kleb1](https://rubytalk.org/u/BIl_Kleb1)\
**Post date:** [10 March 2006 21:28 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646/1 "2006-03-10T21:28:43Z")

</div>

OK, I give up.

Can someone (Kou?) please sketch out how to intercept  
a Subversion transaction with a pre-commit hook and  
throw each file matching, say, /\.rb$/ to some StyleChecker?

Based on Kou's svnlook,

&nbsp;&nbsp;[https://svn.collab.net/repos/svn/trunk/tools/examples/svnlook.rb](https://svn.collab.net/repos/svn/trunk/tools/examples/svnlook.rb)

and the bindings,

&nbsp;&nbsp;[http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/svn/](http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/svn/)

it seems that Svn:Fs might be the answer, but I'm having  
trouble figuring out SVN transactions -- the manual says  
very little about these creatures.

Thanks,

> **···**
>
> --  
> Bil  
> [http://fun3d.larc.nasa.gov](http://fun3d.larc.nasa.gov)

---

<div class="post-metadata">

**Author:** ![Collins\_Justin](https://avatars.discourse-cdn.com/v4/letter/c/e19adc/32.png) [@Collins\_Justin](https://rubytalk.org/u/Collins_Justin)\
**Post date:** [10 March 2006 21:44 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646/2 "2006-03-10T21:44:00Z")

</div>

Bil Kleb wrote:

> OK, I give up.
> 
> Can someone (Kou?) please sketch out how to intercept  
> a Subversion transaction with a pre-commit hook and  
> throw each file matching, say, /\.rb$/ to some StyleChecker?
> 
> Based on Kou's svnlook,
> 
> [https://svn.collab.net/repos/svn/trunk/tools/examples/svnlook.rb](https://svn.collab.net/repos/svn/trunk/tools/examples/svnlook.rb)
> 
> and the bindings,
> 
> [http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/svn/](http://svn.collab.net/repos/svn/trunk/subversion/bindings/swig/ruby/svn/)
> 
> it seems that Svn:Fs might be the answer, but I'm having  
> trouble figuring out SVN transactions -- the manual says  
> very little about these creatures.
> 
> Thanks,  
> --  
> Bil  
> [http://fun3d.larc.nasa.gov](http://fun3d.larc.nasa.gov)

I don't know about pre-commit hooks, but here's a post-commit hook I wrote the other day. Not fancy or anything, but will maybe give you an idea?  
I just used the normal 'svnlook'.

> #!/usr/bin/env ruby  
> require 'net/smtp'
> 
> if ARGV.length != 2  
> &nbsp;&nbsp;puts "Usage: post-commit [repos] [revision]"  
> end
> 
> def parse\_changed(change\_list)  
> &nbsp;&nbsp;added = Array.new  
> &nbsp;&nbsp;modified = Array.new  
> &nbsp;&nbsp;deleted = Array.new  
> &nbsp;&nbsp;other = Array.new  
> &nbsp;&nbsp;change\_list = change\_list.split("\n")
> 
> &nbsp;&nbsp;change\_list.each { |changed|
> 
> &nbsp;&nbsp;&nbsp;&nbsp;#changed file/dir is preceded by U/D/A  
> &nbsp;&nbsp;&nbsp;&nbsp;mod = changed[0, 1]  
> &nbsp;&nbsp;&nbsp;&nbsp;  
> &nbsp;&nbsp;&nbsp;&nbsp;case mod  
> &nbsp;&nbsp;&nbsp;&nbsp;when 'U'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;modified \<\< changed[1..-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;when 'A'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;added \<\< changed[1..-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;when 'D'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deleted \<\< changed[1..-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;other \<\< changed  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;}
> 
> &nbsp;&nbsp;change\_string = String.new
> 
> &nbsp;&nbsp;if not added.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;change\_string \<\< "Added:\n" \<\< added.join("\n") \<\< "\n"  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;if not modified.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;change\_string \<\< "Modified:\n" \<\< modified.join("\n") \<\< "\n"  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;if not deleted.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;change\_string \<\< "Deleted:\n" \<\< deleted.join("\n") \<\< "\n"  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;if not other.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;change\_string \<\< "Other:\n" \<\< other.join("\n") \<\< "\n"  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;return change\_string  
> end  
> &nbsp;&nbsp;  
> recipients = ['fake@fake.com']
> 
> repository = ARGV[0]  
> revision = ARGV[1]
> 
> author = `svnlook author #{repository} --revision #{revision}`.chomp.capitalize  
> date = `svnlook date #{repository} --revision #{revision}`.chomp  
> changed = parse\_changed(`svnlook changed #{repository} --revision #{revision}`.chomp)  
> diff = `svnlook diff #{repository} --revision #{revision} --no-diff-deleted`  
> log = `svnlook log #{repository} --revision #{revision}`
> 
> message = \<\<END\_OF\_MESSAGE  
> To: #{recipients.join(',')}  
> From: SVN \<svn@host.net\>  
> Subject: SVN Commit: Revision #{revision} by #{author}
> 
> Author: #{author}  
> Date: #{date}  
> Revision: #{revision}
> 
> #{changed}
> 
> Log Message:  
> #{log}
> 
> #{diff}
> 
> END\_OF\_MESSAGE
> 
> if $DEBUG  
> &nbsp;&nbsp;puts message  
> &nbsp;&nbsp;exit  
> end
> 
> Net::SMTP.start('smtp.host.net', 25, 'host.net', 'fake@fake.net', 'password') { |smtp|
> 
> &nbsp;&nbsp;&nbsp;&nbsp;smtp.send\_message(message, 'fake@fake.net', recipients)  
> &nbsp;&nbsp;&nbsp;&nbsp;  
> }  
> &nbsp;&nbsp;  
> -Justin

---

<div class="post-metadata">

**Author:** ![Kouhei\_Sutou1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/kouhei_sutou1/32/2034_2.png) [@Kouhei\_Sutou1](https://rubytalk.org/u/Kouhei_Sutou1)\
**Post date:** [13 March 2006 14:58 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646/3 "2006-03-13T14:58:23Z")

</div>

Hi,

In \<dusqov$mbv$1@vilya.larc.nasa.gov\>  
&nbsp;&nbsp;"svn pre-commit hook" on Sat, 11 Mar 2006 06:28:43 +0900,

> Can someone (Kou?) please sketch out how to intercept  
> a Subversion transaction with a pre-commit hook and  
> throw each file matching, say, /\.rb$/ to some StyleChecker?

What about attached script?

You can use the attached script with the following  
pre-commit script:

&nbsp;&nbsp;#!/bin/sh

&nbsp;&nbsp;REPOS="$1"  
&nbsp;&nbsp;TXN="$2"

&nbsp;&nbsp;/.../ruby \  
&nbsp;&nbsp;&nbsp;&nbsp;/.../pre-check-file.rb "$REPOS" "$TXN" \  
&nbsp;&nbsp;&nbsp;&nbsp;-p PATTERN1 -c CHECK\_COMMAND1 \  
&nbsp;&nbsp;&nbsp;&nbsp;-p PATTERN2 -c CHECK\_COMMAND2 \  
&nbsp;&nbsp;&nbsp;&nbsp;... \  
&nbsp;&nbsp;&nbsp;&nbsp;\>\> exit 1

&nbsp;&nbsp;exit 0

For example (reject space indented Ruby scripts and C programs):

&nbsp;&nbsp;#!/bin/sh

&nbsp;&nbsp;REPOS="$1"  
&nbsp;&nbsp;TXN="$2"

&nbsp;&nbsp;/usr/bin/ruby \  
&nbsp;&nbsp;&nbsp;&nbsp;~/work/ruby/pre-check-file.rb "$REPOS" "$TXN" \  
&nbsp;&nbsp;&nbsp;&nbsp;-p \.rb$ -c 'grep -v ^ ' \  
&nbsp;&nbsp;&nbsp;&nbsp;-p \.c$ -c 'grep -v ^ ' \  
&nbsp;&nbsp;&nbsp;&nbsp;\>\> exit 1

&nbsp;&nbsp;exit 0

Thanks,

[pre-check-file.rb](https://rubytalk.org/uploads/short-url/gJYaSI4zoFnDnBE90fP5WL0VClc.rb) (3.79 KB)

> **···**
>
> Bil Kleb \<Bil.Kleb@NASA.gov\> wrote:  
> --  
> kou

---

<div class="post-metadata">

**Author:** ![BIl\_Kleb1](https://avatars.discourse-cdn.com/v4/letter/b/a587f6/32.png) [@BIl\_Kleb1](https://rubytalk.org/u/BIl_Kleb1)\
**Post date:** [10 March 2006 22:03 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646/4 "2006-03-10T22:03:42Z")

</div>

Justin Collins wrote:

> I don't know about pre-commit hooks, but here's a post-commit hook I wrote the other day. Not fancy or anything, but will maybe give you an idea?

Thanks.

> I just used the normal 'svnlook'.

If you have the SVN Ruby bindings compiled, you could use Kouhei's  
commit-email.rb for post-hook mailings (and RSS feed):

&nbsp;&nbsp;[https://svn.collab.net/repos/svn/trunk/tools/hook-scripts/commit-email.rb](https://svn.collab.net/repos/svn/trunk/tools/hook-scripts/commit-email.rb)

If you want HTML output also, see

&nbsp;&nbsp;[https://svn.collab.net/repos/svn/trunk/tools/examples/svnlog2html.rb](https://svn.collab.net/repos/svn/trunk/tools/examples/svnlog2html.rb)

Regards,

> **···**
>
> --  
> Bil  
> [http://fun3d.larc.nasa.gov](http://fun3d.larc.nasa.gov)

---

<div class="post-metadata">

**Author:** ![BIl\_Kleb1](https://avatars.discourse-cdn.com/v4/letter/b/a587f6/32.png) [@BIl\_Kleb1](https://rubytalk.org/u/BIl_Kleb1)\
**Post date:** [13 March 2006 15:13 UTC](https://rubytalk.org/t/svn-pre-commit-hook/25646/5 "2006-03-13T15:13:45Z")

</div>

Kouhei Sutou wrote:

> Hi,

Hello.

> What about attached script?

Excellent, Thanks!

This is the nugget I most craved:

> &nbsp;&nbsp;def changed\_paths(base\_rev=nil)  
> &nbsp;&nbsp;&nbsp;&nbsp;base\_rev ||= @txn.base\_revision  
> &nbsp;&nbsp;&nbsp;&nbsp;base\_root = @fs.root(base\_rev)  
> &nbsp;&nbsp;&nbsp;&nbsp;editor = Svn::Delta::ChangedEditor.new(@root, base\_root)  
> &nbsp;&nbsp;&nbsp;&nbsp;base\_root.dir\_delta('', '', @root, '', editor)  
> &nbsp;&nbsp;&nbsp;&nbsp;(editor.added\_files + editor.updated\_files).uniq.sort  
> &nbsp;&nbsp;end

Thanks again,

> **···**
>
> --  
> Bil  
> [http://fun3d.larc.nasa.gov](http://fun3d.larc.nasa.gov)
