-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsvn-log.rb
executable file
·72 lines (56 loc) · 2.35 KB
/
svn-log.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env jruby --1.9 -s
# Filters svn log output for the list of files changed, optionally accepting changes for only some users.
# Usage:
# svn-log.rb -r=revision -users=user1,user2 -msg="some message filter"
require 'nokogiri'
def usage
puts <<END
Filters svn log output for the list of files changed, optionally accepting
changes for only some users and a log message. Changes are filtered by user
first, then filtered by message.
Usage:
svn-log.rb -r=revision -users=user1,user2 -msg="some message filter"
-help (optional) displays this message and exits
-r=revision (optional) revision is the revision from which to start querying
SVN fetches the revisions of the last 7 days by default
-users=user1,user2 (optional) a comma separated list of users to filter for
-msg="a message" (optional) a string used to filter commit messages
END
end
def filter_changes_by_users(changes, users)
return changes unless users && !users.empty?
changes.select { |logentry| users.include?(logentry.xpath("author").text) }
end
def filter_changes_by_log(changes, message="")
changes.select { |logentry| logentry.xpath("msg").text =~ /#{Regexp.escape(message)}/i }
end
def get_changes(xml_document)
xml_document.xpath("//logentry")
end
def get_files_in_revision(revision)
cmd_output = `svn diff --no-diff-deleted --summarize -r #{revision - 1}:#{revision}`
cmd_output.lines.to_a
end
def find_changed_files(changes)
changed_files, deleted_files = changes.inject([[], []]) do |acc, change|
changed, deleted = acc
changes_in_revision = get_files_in_revision(change['revision'].to_i).map &:split
new_deleted, new_changed = changes_in_revision.partition {|action, file| action == 'D'}
changed += new_changed.map {|action, file| file}
deleted += new_deleted.map {|action, file| file}
[changed, deleted]
end
(changed_files - deleted_files).sort.uniq.map { |f| f.gsub /\\/, '/' }
end
first_revision = $r || "{#{(Time.now - 3600 * 24 * 7).strftime('%Y-%m-%d')}}"
users = if $users then $users.split(",") else nil end
message = $msg || ''
if $help
usage
exit(1)
end
xml = Nokogiri::XML.parse(`svn log -r #{first_revision}:HEAD --xml`)
changes = get_changes(xml)
filtered = filter_changes_by_users(changes, users)
filtered = filter_changes_by_log(filtered, message)
puts find_changed_files(filtered)