Feature #6092 » revision-truncate-20101213.diff
| app/controllers/repositories_controller.rb | ||
|---|---|---|
| 174 | 174 |
@diff = @repository.diff(@path, @rev, @rev_to) |
| 175 | 175 |
show_error_not_found unless @diff |
| 176 | 176 |
end |
| 177 | ||
| 178 |
@changeset = @repository.find_changeset_by_name(@rev) |
|
| 179 |
@changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil |
|
| 177 | 180 |
end |
| 178 | 181 |
end |
| 179 | 182 |
|
| app/helpers/application_helper.rb | ||
|---|---|---|
| 104 | 104 |
# * :text - Link text (default to the formatted revision) |
| 105 | 105 |
def link_to_revision(revision, project, options={})
|
| 106 | 106 |
text = options.delete(:text) || format_revision(revision) |
| 107 |
rev = revision.respond_to?(:identifier) ? revision.identifier : revision |
|
| 107 | 108 | |
| 108 |
link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => revision}, :title => l(:label_revision_id, revision))
|
|
| 109 |
link_to(text, {:controller => 'repositories', :action => 'revision', :id => project, :rev => rev},
|
|
| 110 |
:title => l(:label_revision_id, format_revision(revision))) |
|
| 109 | 111 |
end |
| 110 | 112 | |
| 111 | 113 |
# Generates a link to a project if active |
| app/helpers/repositories_helper.rb | ||
|---|---|---|
| 18 | 18 |
require 'iconv' |
| 19 | 19 | |
| 20 | 20 |
module RepositoriesHelper |
| 21 |
def format_revision(txt) |
|
| 22 |
txt.to_s[0,8] |
|
| 21 |
def format_revision(revision) |
|
| 22 |
if revision.respond_to? :format_identifier |
|
| 23 |
revision.format_identifier |
|
| 24 |
else |
|
| 25 |
revision.to_s |
|
| 26 |
end |
|
| 23 | 27 |
end |
| 24 | 28 |
|
| 25 | 29 |
def truncate_at_line_break(text, length = 255) |
| ... | ... | |
| 87 | 91 |
:action => 'show', |
| 88 | 92 |
:id => @project, |
| 89 | 93 |
:path => path_param, |
| 90 |
:rev => @changeset.revision)
|
|
| 94 |
:rev => @changeset.identifier)
|
|
| 91 | 95 |
output << "<li class='#{style}'>#{text}</li>"
|
| 92 | 96 |
output << render_changes_tree(s) |
| 93 | 97 |
elsif c = tree[file][:c] |
| ... | ... | |
| 97 | 101 |
:action => 'entry', |
| 98 | 102 |
:id => @project, |
| 99 | 103 |
:path => path_param, |
| 100 |
:rev => @changeset.revision) unless c.action == 'D'
|
|
| 104 |
:rev => @changeset.identifier) unless c.action == 'D'
|
|
| 101 | 105 |
text << " - #{c.revision}" unless c.revision.blank?
|
| 102 | 106 |
text << ' (' + link_to('diff', :controller => 'repositories',
|
| 103 | 107 |
:action => 'diff', |
| 104 | 108 |
:id => @project, |
| 105 | 109 |
:path => path_param, |
| 106 |
:rev => @changeset.revision) + ') ' if c.action == 'M'
|
|
| 110 |
:rev => @changeset.identifier) + ') ' if c.action == 'M'
|
|
| 107 | 111 |
text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
|
| 108 | 112 |
output << "<li class='#{style}'>#{text}</li>"
|
| 109 | 113 |
end |
| app/models/changeset.rb | ||
|---|---|---|
| 23 | 23 |
has_many :changes, :dependent => :delete_all |
| 24 | 24 |
has_and_belongs_to_many :issues |
| 25 | 25 | |
| 26 |
acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.revision}" + (o.short_comments.blank? ? '' : (': ' + o.short_comments))},
|
|
| 26 |
acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.format_identifier}" + (o.short_comments.blank? ? '' : (': ' + o.short_comments))},
|
|
| 27 | 27 |
:description => :long_comments, |
| 28 | 28 |
:datetime => :committed_on, |
| 29 |
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :rev => o.revision}}
|
|
| 29 |
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :rev => o.identifier}}
|
|
| 30 | 30 |
|
| 31 | 31 |
acts_as_searchable :columns => 'comments', |
| 32 | 32 |
:include => {:repository => :project},
|
| ... | ... | |
| 47 | 47 |
def revision=(r) |
| 48 | 48 |
write_attribute :revision, (r.nil? ? nil : r.to_s) |
| 49 | 49 |
end |
| 50 | ||
| 51 |
# Returns the identifier of this changeset; depending on repository backends |
|
| 52 |
def identifier |
|
| 53 |
if repository.class.respond_to? :changeset_identifier |
|
| 54 |
repository.class.changeset_identifier self |
|
| 55 |
else |
|
| 56 |
revision.to_s |
|
| 57 |
end |
|
| 58 |
end |
|
| 50 | 59 |
|
| 51 | 60 |
def comments=(comment) |
| 52 | 61 |
write_attribute(:comments, Changeset.normalize_comments(comment)) |
| ... | ... | |
| 56 | 65 |
self.commit_date = date |
| 57 | 66 |
super |
| 58 | 67 |
end |
| 68 | ||
| 69 |
# Returns the readable identifier |
|
| 70 |
def format_identifier |
|
| 71 |
if repository.class.respond_to? :format_changeset_identifier |
|
| 72 |
repository.class.format_changeset_identifier self |
|
| 73 |
else |
|
| 74 |
identifier |
|
| 75 |
end |
|
| 76 |
end |
|
| 59 | 77 |
|
| 60 | 78 |
def committer=(arg) |
| 61 | 79 |
write_attribute(:committer, self.class.to_utf8(arg.to_s)) |
| app/models/repository/git.rb | ||
|---|---|---|
| 29 | 29 |
'Git' |
| 30 | 30 |
end |
| 31 | 31 | |
| 32 |
# Returns the identifier for the given git changeset |
|
| 33 |
def self.changeset_identifier(changeset) |
|
| 34 |
changeset.scmid |
|
| 35 |
end |
|
| 36 | ||
| 37 |
# Returns the readable identifier for the given git changeset |
|
| 38 |
def self.format_changeset_identifier(changeset) |
|
| 39 |
changeset.revision[0, 8] |
|
| 40 |
end |
|
| 41 | ||
| 32 | 42 |
def branches |
| 33 | 43 |
scm.branches |
| 34 | 44 |
end |
| app/views/repositories/_dir_list_content.rhtml | ||
|---|---|---|
| 17 | 17 |
</td> |
| 18 | 18 |
<td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td> |
| 19 | 19 |
<% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %> |
| 20 |
<td class="revision"><%= link_to_revision(changeset.revision, @project) if changeset %></td>
|
|
| 20 |
<td class="revision"><%= link_to_revision(changeset, @project) if changeset %></td> |
|
| 21 | 21 |
<td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td> |
| 22 | 22 |
<td class="author"><%= changeset.nil? ? h(entry.lastrev.author.to_s.split('<').first) : changeset.author if entry.lastrev %></td>
|
| 23 | 23 |
<td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td> |
| app/views/repositories/_revisions.rhtml | ||
|---|---|---|
| 13 | 13 |
<% line_num = 1 %> |
| 14 | 14 |
<% revisions.each do |changeset| %> |
| 15 | 15 |
<tr class="changeset <%= cycle 'odd', 'even' %>"> |
| 16 |
<td class="id"><%= link_to_revision(changeset.revision, project) %></td>
|
|
| 17 |
<td class="checkbox"><%= radio_button_tag('rev', changeset.revision, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
|
|
| 18 |
<td class="checkbox"><%= radio_button_tag('rev_to', changeset.revision, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
|
|
| 16 |
<td class="id"><%= link_to_revision(changeset, project) %></td> |
|
| 17 |
<td class="checkbox"><%= radio_button_tag('rev', changeset.identifier, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
|
|
| 18 |
<td class="checkbox"><%= radio_button_tag('rev_to', changeset.identifier, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
|
|
| 19 | 19 |
<td class="committed_on"><%= format_time(changeset.committed_on) %></td> |
| 20 | 20 |
<td class="author"><%=h changeset.author %></td> |
| 21 | 21 |
<td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td> |
| app/views/repositories/annotate.rhtml | ||
|---|---|---|
| 19 | 19 |
<tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>"> |
| 20 | 20 |
<th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th> |
| 21 | 21 |
<td class="revision"> |
| 22 |
<%= (revision.identifier ? link_to(format_revision(revision.identifier), :action => 'revision', :id => @project, :rev => revision.identifier) : format_revision(revision.revision)) if revision %></td>
|
|
| 22 |
<%= (revision.identifier ? link_to_revision(revision, @project) : format_revision(revision)) if revision %></td>
|
|
| 23 | 23 |
<td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
|
| 24 | 24 |
<td class="line-code"><pre><%= line %></pre></td> |
| 25 | 25 |
</tr> |
| app/views/repositories/diff.rhtml | ||
|---|---|---|
| 1 |
<h2><%= l(:label_revision) %> <%= format_revision(@rev_to) + ':' if @rev_to %><%= format_revision(@rev) %> <%=h @path %></h2>
|
|
| 1 |
<h2><%= l(:label_revision) %> <%= format_revision(@changeset_to) + ' ' if @changeset_to %><%= format_revision(@changeset) %> <%=h @path %></h2>
|
|
| 2 | 2 | |
| 3 | 3 |
<!-- Choose view type --> |
| 4 | 4 |
<% form_tag({:path => to_path_param(@path)}, :method => 'get') do %>
|
| app/views/repositories/revision.rhtml | ||
|---|---|---|
| 1 | 1 |
<div class="contextual"> |
| 2 | 2 |
« |
| 3 | 3 |
<% unless @changeset.previous.nil? -%> |
| 4 |
<%= link_to_revision(@changeset.previous.revision, @project, :text => l(:label_previous)) %>
|
|
| 4 |
<%= link_to_revision(@changeset.previous, @project, :text => l(:label_previous)) %> |
|
| 5 | 5 |
<% else -%> |
| 6 | 6 |
<%= l(:label_previous) %> |
| 7 | 7 |
<% end -%> |
| 8 | 8 |
| |
| 9 | 9 |
<% unless @changeset.next.nil? -%> |
| 10 |
<%= link_to_revision(@changeset.next.revision, @project, :text => l(:label_next)) %>
|
|
| 10 |
<%= link_to_revision(@changeset.next, @project, :text => l(:label_next)) %> |
|
| 11 | 11 |
<% else -%> |
| 12 | 12 |
<%= l(:label_next) %> |
| 13 | 13 |
<% end -%> |
| ... | ... | |
| 19 | 19 |
<% end %> |
| 20 | 20 |
</div> |
| 21 | 21 | |
| 22 |
<h2><%= l(:label_revision) %> <%= format_revision(@changeset.revision) %></h2>
|
|
| 22 |
<h2><%= l(:label_revision) %> <%= format_revision(@changeset) %></h2> |
|
| 23 | 23 | |
| 24 | 24 |
<p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %> |
| 25 | 25 |
<span class="author"><%= authoring(@changeset.committed_on, @changeset.author) %></span></p> |
| ... | ... | |
| 45 | 45 |
<li class="change change-D"><%= l(:label_deleted) %></li> |
| 46 | 46 |
</ul> |
| 47 | 47 | |
| 48 |
<p><%= link_to(l(:label_view_diff), :action => 'diff', :id => @project, :path => "", :rev => @changeset.revision) if @changeset.changes.any? %></p>
|
|
| 48 |
<p><%= link_to(l(:label_view_diff), :action => 'diff', :id => @project, :path => "", :rev => @changeset.identifier) if @changeset.changes.any? %></p>
|
|
| 49 | 49 | |
| 50 | 50 |
<div class="changeset-changes"> |
| 51 | 51 |
<%= render_changeset_changes %> |
| ... | ... | |
| 56 | 56 |
<%= stylesheet_link_tag "scm" %> |
| 57 | 57 |
<% end %> |
| 58 | 58 | |
| 59 |
<% html_title("#{l(:label_revision)} #{@changeset.revision}") -%>
|
|
| 59 |
<% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%>
|
|
| lib/redmine/scm/adapters/abstract_adapter.rb | ||
|---|---|---|
| 271 | 271 |
end |
| 272 | 272 |
|
| 273 | 273 |
class Revision |
| 274 |
attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch |
|
| 274 |
attr_accessor :scmid, :name, :author, :time, :message, :paths, :revision, :branch |
|
| 275 |
attr_writer :identifier |
|
| 275 | 276 | |
| 276 | 277 |
def initialize(attributes={})
|
| 277 | 278 |
self.identifier = attributes[:identifier] |
| ... | ... | |
| 285 | 286 |
self.branch = attributes[:branch] |
| 286 | 287 |
end |
| 287 | 288 | |
| 289 |
# Returns the identifier of this revision; see also Changeset model |
|
| 290 |
def identifier |
|
| 291 |
(@identifier || revision).to_s |
|
| 292 |
end |
|
| 293 | ||
| 294 |
# Returns the readable identifier. |
|
| 295 |
def format_identifier |
|
| 296 |
identifier |
|
| 297 |
end |
|
| 298 | ||
| 288 | 299 |
def save(repo) |
| 289 | 300 |
Changeset.transaction do |
| 290 | 301 |
changeset = Changeset.new( |
| lib/redmine/scm/adapters/git_adapter.rb | ||
|---|---|---|
| 264 | 264 |
return nil if $? && $?.exitstatus != 0 |
| 265 | 265 |
cat |
| 266 | 266 |
end |
| 267 | ||
| 268 |
class Revision < Redmine::Scm::Adapters::Revision |
|
| 269 |
# Returns the readable identifier |
|
| 270 |
def format_identifier |
|
| 271 |
identifier[0,8] |
|
| 272 |
end |
|
| 273 |
end |
|
| 267 | 274 |
end |
| 268 | 275 |
end |
| 269 | 276 |
end |
| test/unit/changeset_test.rb | ||
|---|---|---|
| 218 | 218 |
c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
|
| 219 | 219 |
assert_equal "Texte encod en ISO-8859-1.", c.comments |
| 220 | 220 |
end |
| 221 | ||
| 222 |
def test_identifier |
|
| 223 |
c = Changeset.find_by_revision('1')
|
|
| 224 |
assert_equal c.revision, c.identifier |
|
| 225 |
end |
|
| 221 | 226 |
end |
| test/unit/repository_bazaar_test.rb | ||
|---|---|---|
| 77 | 77 |
def test_annotate |
| 78 | 78 |
annotate = @repository.scm.annotate('doc-mkdir.txt')
|
| 79 | 79 |
assert_equal 17, annotate.lines.size |
| 80 |
assert_equal 1, annotate.revisions[0].identifier
|
|
| 80 |
assert_equal '1', annotate.revisions[0].identifier
|
|
| 81 | 81 |
assert_equal 'jsmith@', annotate.revisions[0].author |
| 82 | 82 |
assert_equal 'mkdir', annotate.lines[0] |
| 83 | 83 |
end |
| test/unit/repository_git_test.rb | ||
|---|---|---|
| 62 | 62 |
@repository.fetch_changesets |
| 63 | 63 |
assert_equal 15, @repository.changesets.count |
| 64 | 64 |
end |
| 65 | ||
| 66 |
def test_identifier |
|
| 67 |
@repository.fetch_changesets |
|
| 68 |
@repository.reload |
|
| 69 |
c = @repository.changesets.find_by_revision('7234cb2750b63f47bff735edc50a1c0a433c2518')
|
|
| 70 |
assert_equal c.scmid, c.identifier |
|
| 71 |
end |
|
| 72 | ||
| 73 |
def test_format_identifier |
|
| 74 |
@repository.fetch_changesets |
|
| 75 |
@repository.reload |
|
| 76 |
c = @repository.changesets.find_by_revision('7234cb2750b63f47bff735edc50a1c0a433c2518')
|
|
| 77 |
assert_equal c.format_identifier, '7234cb27' |
|
| 78 |
end |
|
| 79 | ||
| 80 |
def test_activities |
|
| 81 |
@repository.fetch_changesets |
|
| 82 |
@repository.reload |
|
| 83 |
f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1)) |
|
| 84 |
f.scope = ['changesets'] |
|
| 85 |
events = f.events |
|
| 86 |
assert_kind_of Array, events |
|
| 87 |
eve = events[-1] |
|
| 88 |
assert eve.event_title.include?('7234cb27:')
|
|
| 89 |
assert_equal eve.event_url[:rev], '7234cb2750b63f47bff735edc50a1c0a433c2518' |
|
| 90 |
end |
|
| 65 | 91 |
else |
| 66 | 92 |
puts "Git test repository NOT FOUND. Skipping unit tests !!!" |
| 67 | 93 |
def test_fake; assert true end |
| test/unit/repository_subversion_test.rb | ||
|---|---|---|
| 88 | 88 |
assert_equal 1, entries.size, 'Expect a single entry' |
| 89 | 89 |
assert_equal 'README.txt', entries.first.name |
| 90 | 90 |
end |
| 91 | ||
| 92 |
def test_identifier |
|
| 93 |
@repository.fetch_changesets |
|
| 94 |
@repository.reload |
|
| 95 |
c = @repository.changesets.find_by_revision('1')
|
|
| 96 |
assert_equal c.revision, c.identifier |
|
| 97 |
end |
|
| 98 | ||
| 99 |
def test_identifier_nine_digit |
|
| 100 |
c = Changeset.new(:repository => @repository, :committed_on => Time.now, |
|
| 101 |
:revision => '123456789', :comments => 'test') |
|
| 102 |
assert_equal c.identifier, c.revision |
|
| 103 |
end |
|
| 104 | ||
| 105 |
def test_format_identifier |
|
| 106 |
@repository.fetch_changesets |
|
| 107 |
@repository.reload |
|
| 108 |
c = @repository.changesets.find_by_revision('1')
|
|
| 109 |
assert_equal c.format_identifier, c.revision |
|
| 110 |
end |
|
| 111 | ||
| 112 |
def test_format_identifier_nine_digit |
|
| 113 |
c = Changeset.new(:repository => @repository, :committed_on => Time.now, |
|
| 114 |
:revision => '123456789', :comments => 'test') |
|
| 115 |
assert_equal c.format_identifier, c.revision |
|
| 116 |
end |
|
| 117 | ||
| 118 |
def test_activities |
|
| 119 |
@repository.fetch_changesets |
|
| 120 |
@repository.reload |
|
| 121 |
f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1)) |
|
| 122 |
f.scope = ['changesets'] |
|
| 123 |
events = f.events |
|
| 124 |
assert_kind_of Array, events |
|
| 125 |
eve = events[-1] |
|
| 126 |
assert eve.event_title.include?('1:')
|
|
| 127 |
assert_equal eve.event_url[:rev], '1' |
|
| 128 |
end |
|
| 129 | ||
| 130 |
def test_activities_nine_digit |
|
| 131 |
c = Changeset.new(:repository => @repository, :committed_on => Time.now, |
|
| 132 |
:revision => '123456789', :comments => 'test') |
|
| 133 |
assert( c.save ) |
|
| 134 |
f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1)) |
|
| 135 |
f.scope = ['changesets'] |
|
| 136 |
events = f.events |
|
| 137 |
assert_kind_of Array, events |
|
| 138 |
eve = events[-1] |
|
| 139 |
assert eve.event_title.include?('123456789:')
|
|
| 140 |
assert_equal eve.event_url[:rev], '123456789' |
|
| 141 |
end |
|
| 91 | 142 |
else |
| 92 | 143 |
puts "Subversion test repository NOT FOUND. Skipping unit tests !!!" |
| 93 | 144 |
def test_fake; assert true end |