Added Annotate/Blame view for Subversion, CVS and Mercurial repositories.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@947 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
+1
-1
@@ -76,7 +76,7 @@ Redmine::AccessControl.map do |map|
|
||||
|
||||
map.project_module :repository do |map|
|
||||
map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
|
||||
map.permission :browse_repository, :repositories => [:show, :browse, :entry, :changes, :diff, :stats, :graph]
|
||||
map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
|
||||
map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
|
||||
end
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ module Redmine
|
||||
def supports_cat?
|
||||
true
|
||||
end
|
||||
|
||||
def supports_annotate?
|
||||
respond_to?('annotate')
|
||||
end
|
||||
|
||||
def root_url
|
||||
@root_url
|
||||
@@ -76,7 +80,7 @@ module Redmine
|
||||
def cat(path, identifier=nil)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
def with_leading_slash(path)
|
||||
path ||= ''
|
||||
(path[0,1]!="/") ? "/#{path}" : path
|
||||
@@ -237,7 +241,7 @@ module Redmine
|
||||
|
||||
# Initialize with a Diff file and the type of Diff View
|
||||
# The type view must be inline or sbs (side_by_side)
|
||||
def initialize (type="inline")
|
||||
def initialize(type="inline")
|
||||
@parsing = false
|
||||
@nb_line = 1
|
||||
@start = false
|
||||
@@ -312,7 +316,7 @@ module Redmine
|
||||
CGI.escapeHTML(line)
|
||||
end
|
||||
|
||||
def parse_line (line, type="inline")
|
||||
def parse_line(line, type="inline")
|
||||
if line[0, 1] == "+"
|
||||
diff = sbs? type, 'add'
|
||||
@before = 'add'
|
||||
@@ -348,6 +352,28 @@ module Redmine
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Annotate
|
||||
attr_reader :lines, :revisions
|
||||
|
||||
def initialize
|
||||
@lines = []
|
||||
@revisions = []
|
||||
end
|
||||
|
||||
def add_line(line, revision)
|
||||
@lines << line
|
||||
@revisions << revision
|
||||
end
|
||||
|
||||
def content
|
||||
content = lines.join("\n")
|
||||
end
|
||||
|
||||
def empty?
|
||||
lines.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -268,7 +268,25 @@ module Redmine
|
||||
rescue Errno::ENOENT => e
|
||||
raise CommandFailed
|
||||
end
|
||||
|
||||
|
||||
def annotate(path, identifier=nil)
|
||||
identifier = (identifier) ? identifier : "HEAD"
|
||||
logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
|
||||
path_with_project="#{url}#{with_leading_slash(path)}"
|
||||
cmd = "#{CVS_BIN} -d #{root_url} rannotate -r#{identifier} #{path_with_project}"
|
||||
blame = Annotate.new
|
||||
shellout(cmd) do |io|
|
||||
io.each_line do |line|
|
||||
next unless line =~ %r{^([\d\.]+)\s+\(([^\)]+)\s+[^\)]+\):\s(.*)$}
|
||||
blame.add_line($3.rstrip, Revision.new(:revision => $1, :author => $2.strip))
|
||||
end
|
||||
end
|
||||
return nil if $? && $?.exitstatus != 0
|
||||
blame
|
||||
rescue Errno::ENOENT => e
|
||||
raise CommandFailed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# convert a date/time into the CVS-format
|
||||
|
||||
@@ -157,6 +157,25 @@ module Redmine
|
||||
rescue Errno::ENOENT => e
|
||||
raise CommandFailed
|
||||
end
|
||||
|
||||
def annotate(path, identifier=nil)
|
||||
path ||= ''
|
||||
cmd = "#{HG_BIN} -R #{target('')}"
|
||||
cmd << " annotate -n -u"
|
||||
cmd << " -r #{identifier.to_i}" if identifier
|
||||
cmd << " #{target(path)}"
|
||||
blame = Annotate.new
|
||||
shellout(cmd) do |io|
|
||||
io.each_line do |line|
|
||||
next unless line =~ %r{^([^:]+)\s(\d+):(.*)$}
|
||||
blame.add_line($3.rstrip, Revision.new(:identifier => $2.to_i, :author => $1.strip))
|
||||
end
|
||||
end
|
||||
return nil if $? && $?.exitstatus != 0
|
||||
blame
|
||||
rescue Errno::ENOENT => e
|
||||
raise CommandFailed
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -173,6 +173,23 @@ module Redmine
|
||||
raise CommandFailed
|
||||
end
|
||||
|
||||
def annotate(path, identifier=nil)
|
||||
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
|
||||
cmd = "#{SVN_BIN} blame #{target(path)}@#{identifier}"
|
||||
cmd << credentials_string
|
||||
blame = Annotate.new
|
||||
shellout(cmd) do |io|
|
||||
io.each_line do |line|
|
||||
next unless line =~ %r{^\s*(\d+)\s*(\S+)\s(.*)$}
|
||||
blame.add_line($3.rstrip, Revision.new(:identifier => $1.to_i, :author => $2.strip))
|
||||
end
|
||||
end
|
||||
return nil if $? && $?.exitstatus != 0
|
||||
blame
|
||||
rescue Errno::ENOENT => e
|
||||
raise CommandFailed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def credentials_string
|
||||
|
||||
Reference in New Issue
Block a user