##// END OF EJS Templates
Changing revision label and identifier at SCM adapter level (#3724, #6092)...
Toshi MARUYAMA -
r4493:2e1bcb2abff6
parent child
Show More
@@ -174,6 +174,9 class RepositoriesController < ApplicationController
174 @diff = @repository.diff(@path, @rev, @rev_to)
174 @diff = @repository.diff(@path, @rev, @rev_to)
175 show_error_not_found unless @diff
175 show_error_not_found unless @diff
176 end
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 end
180 end
178 end
181 end
179
182
@@ -104,8 +104,10 module ApplicationHelper
104 # * :text - Link text (default to the formatted revision)
104 # * :text - Link text (default to the formatted revision)
105 def link_to_revision(revision, project, options={})
105 def link_to_revision(revision, project, options={})
106 text = options.delete(:text) || format_revision(revision)
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 end
111 end
110
112
111 # Generates a link to a project if active
113 # Generates a link to a project if active
@@ -18,8 +18,12
18 require 'iconv'
18 require 'iconv'
19
19
20 module RepositoriesHelper
20 module RepositoriesHelper
21 def format_revision(txt)
21 def format_revision(revision)
22 txt.to_s[0,8]
22 if revision.respond_to? :format_identifier
23 revision.format_identifier
24 else
25 revision.to_s
26 end
23 end
27 end
24
28
25 def truncate_at_line_break(text, length = 255)
29 def truncate_at_line_break(text, length = 255)
@@ -87,7 +91,7 module RepositoriesHelper
87 :action => 'show',
91 :action => 'show',
88 :id => @project,
92 :id => @project,
89 :path => path_param,
93 :path => path_param,
90 :rev => @changeset.revision)
94 :rev => @changeset.identifier)
91 output << "<li class='#{style}'>#{text}</li>"
95 output << "<li class='#{style}'>#{text}</li>"
92 output << render_changes_tree(s)
96 output << render_changes_tree(s)
93 elsif c = tree[file][:c]
97 elsif c = tree[file][:c]
@@ -97,13 +101,13 module RepositoriesHelper
97 :action => 'entry',
101 :action => 'entry',
98 :id => @project,
102 :id => @project,
99 :path => path_param,
103 :path => path_param,
100 :rev => @changeset.revision) unless c.action == 'D'
104 :rev => @changeset.identifier) unless c.action == 'D'
101 text << " - #{c.revision}" unless c.revision.blank?
105 text << " - #{c.revision}" unless c.revision.blank?
102 text << ' (' + link_to('diff', :controller => 'repositories',
106 text << ' (' + link_to('diff', :controller => 'repositories',
103 :action => 'diff',
107 :action => 'diff',
104 :id => @project,
108 :id => @project,
105 :path => path_param,
109 :path => path_param,
106 :rev => @changeset.revision) + ') ' if c.action == 'M'
110 :rev => @changeset.identifier) + ') ' if c.action == 'M'
107 text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
111 text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
108 output << "<li class='#{style}'>#{text}</li>"
112 output << "<li class='#{style}'>#{text}</li>"
109 end
113 end
@@ -23,10 +23,10 class Changeset < ActiveRecord::Base
23 has_many :changes, :dependent => :delete_all
23 has_many :changes, :dependent => :delete_all
24 has_and_belongs_to_many :issues
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 :description => :long_comments,
27 :description => :long_comments,
28 :datetime => :committed_on,
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 acts_as_searchable :columns => 'comments',
31 acts_as_searchable :columns => 'comments',
32 :include => {:repository => :project},
32 :include => {:repository => :project},
@@ -47,6 +47,15 class Changeset < ActiveRecord::Base
47 def revision=(r)
47 def revision=(r)
48 write_attribute :revision, (r.nil? ? nil : r.to_s)
48 write_attribute :revision, (r.nil? ? nil : r.to_s)
49 end
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 def comments=(comment)
60 def comments=(comment)
52 write_attribute(:comments, Changeset.normalize_comments(comment))
61 write_attribute(:comments, Changeset.normalize_comments(comment))
@@ -56,6 +65,15 class Changeset < ActiveRecord::Base
56 self.commit_date = date
65 self.commit_date = date
57 super
66 super
58 end
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 def committer=(arg)
78 def committer=(arg)
61 write_attribute(:committer, self.class.to_utf8(arg.to_s))
79 write_attribute(:committer, self.class.to_utf8(arg.to_s))
@@ -29,6 +29,16 class Repository::Git < Repository
29 'Git'
29 'Git'
30 end
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 def branches
42 def branches
33 scm.branches
43 scm.branches
34 end
44 end
@@ -17,7 +17,7
17 </td>
17 </td>
18 <td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
18 <td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
19 <% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
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 <td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
21 <td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
22 <td class="author"><%= changeset.nil? ? h(entry.lastrev.author.to_s.split('<').first) : changeset.author if entry.lastrev %></td>
22 <td class="author"><%= changeset.nil? ? h(entry.lastrev.author.to_s.split('<').first) : changeset.author if entry.lastrev %></td>
23 <td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td>
23 <td class="comments"><%=h truncate(changeset.comments, :length => 50) unless changeset.nil? %></td>
@@ -13,9 +13,9
13 <% line_num = 1 %>
13 <% line_num = 1 %>
14 <% revisions.each do |changeset| %>
14 <% revisions.each do |changeset| %>
15 <tr class="changeset <%= cycle 'odd', 'even' %>">
15 <tr class="changeset <%= cycle 'odd', 'even' %>">
16 <td class="id"><%= link_to_revision(changeset.revision, project) %></td>
16 <td class="id"><%= link_to_revision(changeset, 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>
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.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>
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 <td class="committed_on"><%= format_time(changeset.committed_on) %></td>
19 <td class="committed_on"><%= format_time(changeset.committed_on) %></td>
20 <td class="author"><%=h changeset.author %></td>
20 <td class="author"><%=h changeset.author %></td>
21 <td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td>
21 <td class="comments"><%= textilizable(truncate_at_line_break(changeset.comments)) %></td>
@@ -19,7 +19,7
19 <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
19 <tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
20 <th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th>
20 <th class="line-num" id="L<%= line_num %>"><a href="#L<%= line_num %>"><%= line_num %></a></th>
21 <td class="revision">
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 <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
23 <td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
24 <td class="line-code"><pre><%= line %></pre></td>
24 <td class="line-code"><pre><%= line %></pre></td>
25 </tr>
25 </tr>
@@ -1,4 +1,4
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 <!-- Choose view type -->
3 <!-- Choose view type -->
4 <% form_tag({:path => to_path_param(@path)}, :method => 'get') do %>
4 <% form_tag({:path => to_path_param(@path)}, :method => 'get') do %>
@@ -1,25 +1,25
1 <div class="contextual">
1 <div class="contextual">
2 &#171;
2 &#171;
3 <% unless @changeset.previous.nil? -%>
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 <% else -%>
5 <% else -%>
6 <%= l(:label_previous) %>
6 <%= l(:label_previous) %>
7 <% end -%>
7 <% end -%>
8 |
8 |
9 <% unless @changeset.next.nil? -%>
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 <% else -%>
11 <% else -%>
12 <%= l(:label_next) %>
12 <%= l(:label_next) %>
13 <% end -%>
13 <% end -%>
14 &#187;&nbsp;
14 &#187;&nbsp;
15
15
16 <% form_tag({:controller => 'repositories', :action => 'revision', :id => @project, :rev => nil}, :method => :get) do %>
16 <% form_tag({:controller => 'repositories', :action => 'revision', :id => @project, :rev => nil}, :method => :get) do %>
17 <%= text_field_tag 'rev', @rev[0,8], :size => 8 %>
17 <%= text_field_tag 'rev', @rev, :size => 8 %>
18 <%= submit_tag 'OK', :name => nil %>
18 <%= submit_tag 'OK', :name => nil %>
19 <% end %>
19 <% end %>
20 </div>
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 <p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %>
24 <p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %>
25 <span class="author"><%= authoring(@changeset.committed_on, @changeset.author) %></span></p>
25 <span class="author"><%= authoring(@changeset.committed_on, @changeset.author) %></span></p>
@@ -45,7 +45,7
45 <li class="change change-D"><%= l(:label_deleted) %></li>
45 <li class="change change-D"><%= l(:label_deleted) %></li>
46 </ul>
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 <div class="changeset-changes">
50 <div class="changeset-changes">
51 <%= render_changeset_changes %>
51 <%= render_changeset_changes %>
@@ -56,4 +56,4
56 <%= stylesheet_link_tag "scm" %>
56 <%= stylesheet_link_tag "scm" %>
57 <% end %>
57 <% end %>
58
58
59 <% html_title("#{l(:label_revision)} #{@changeset.revision}") -%>
59 <% html_title("#{l(:label_revision)} #{format_revision(@changeset)}") -%>
@@ -271,7 +271,8 module Redmine
271 end
271 end
272
272
273 class Revision
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 def initialize(attributes={})
277 def initialize(attributes={})
277 self.identifier = attributes[:identifier]
278 self.identifier = attributes[:identifier]
@@ -285,6 +286,16 module Redmine
285 self.branch = attributes[:branch]
286 self.branch = attributes[:branch]
286 end
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 def save(repo)
299 def save(repo)
289 Changeset.transaction do
300 Changeset.transaction do
290 changeset = Changeset.new(
301 changeset = Changeset.new(
@@ -264,6 +264,13 module Redmine
264 return nil if $? && $?.exitstatus != 0
264 return nil if $? && $?.exitstatus != 0
265 cat
265 cat
266 end
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 end
274 end
268 end
275 end
269 end
276 end
@@ -218,4 +218,9 class ChangesetTest < ActiveSupport::TestCase
218 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
218 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
219 assert_equal "Texte encod en ISO-8859-1.", c.comments
219 assert_equal "Texte encod en ISO-8859-1.", c.comments
220 end
220 end
221
222 def test_identifier
223 c = Changeset.find_by_revision('1')
224 assert_equal c.revision, c.identifier
225 end
221 end
226 end
@@ -77,7 +77,7 class RepositoryBazaarTest < ActiveSupport::TestCase
77 def test_annotate
77 def test_annotate
78 annotate = @repository.scm.annotate('doc-mkdir.txt')
78 annotate = @repository.scm.annotate('doc-mkdir.txt')
79 assert_equal 17, annotate.lines.size
79 assert_equal 17, annotate.lines.size
80 assert_equal 1, annotate.revisions[0].identifier
80 assert_equal '1', annotate.revisions[0].identifier
81 assert_equal 'jsmith@', annotate.revisions[0].author
81 assert_equal 'jsmith@', annotate.revisions[0].author
82 assert_equal 'mkdir', annotate.lines[0]
82 assert_equal 'mkdir', annotate.lines[0]
83 end
83 end
@@ -18,7 +18,7
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RepositoryGitTest < ActiveSupport::TestCase
20 class RepositoryGitTest < ActiveSupport::TestCase
21 fixtures :projects
21 fixtures :projects, :repositories, :enabled_modules, :users, :roles
22
22
23 # No '..' in the repository path
23 # No '..' in the repository path
24 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
24 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
@@ -62,6 +62,32 class RepositoryGitTest < ActiveSupport::TestCase
62 @repository.fetch_changesets
62 @repository.fetch_changesets
63 assert_equal 15, @repository.changesets.count
63 assert_equal 15, @repository.changesets.count
64 end
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[-9]
88 assert eve.event_title.include?('7234cb27:')
89 assert_equal eve.event_url[:rev], '7234cb2750b63f47bff735edc50a1c0a433c2518'
90 end
65 else
91 else
66 puts "Git test repository NOT FOUND. Skipping unit tests !!!"
92 puts "Git test repository NOT FOUND. Skipping unit tests !!!"
67 def test_fake; assert true end
93 def test_fake; assert true end
@@ -18,7 +18,7
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RepositorySubversionTest < ActiveSupport::TestCase
20 class RepositorySubversionTest < ActiveSupport::TestCase
21 fixtures :projects, :repositories
21 fixtures :projects, :repositories, :enabled_modules, :users, :roles
22
22
23 def setup
23 def setup
24 @project = Project.find(1)
24 @project = Project.find(1)
@@ -88,6 +88,57 class RepositorySubversionTest < ActiveSupport::TestCase
88 assert_equal 1, entries.size, 'Expect a single entry'
88 assert_equal 1, entries.size, 'Expect a single entry'
89 assert_equal 'README.txt', entries.first.name
89 assert_equal 'README.txt', entries.first.name
90 end
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[-9]
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[-11]
139 assert eve.event_title.include?('123456789:')
140 assert_equal eve.event_url[:rev], '123456789'
141 end
91 else
142 else
92 puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
143 puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
93 def test_fake; assert true end
144 def test_fake; assert true end
General Comments 0
You need to be logged in to leave comments. Login now