@@ -0,0 +1,21 | |||||
|
1 | <%= link_to 'root', :action => 'show', :id => @project, :path => '', :rev => @rev %> | |||
|
2 | <% | |||
|
3 | dirs = path.split('/') | |||
|
4 | if 'file' == kind | |||
|
5 | filename = dirs.pop | |||
|
6 | end | |||
|
7 | link_path = '' | |||
|
8 | dirs.each do |dir| | |||
|
9 | next if dir.blank? | |||
|
10 | link_path << '/' unless link_path.empty? | |||
|
11 | link_path << "#{dir}" | |||
|
12 | %> | |||
|
13 | / <%= link_to h(dir), :action => 'show', :id => @project, :path => to_path_param(link_path), :rev => @rev %> | |||
|
14 | <% end %> | |||
|
15 | <% if filename %> | |||
|
16 | / <%= link_to h(filename), :action => 'changes', :id => @project, :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %> | |||
|
17 | <% end %> | |||
|
18 | ||||
|
19 | <%= "@ #{revision}" if revision %> | |||
|
20 | ||||
|
21 | <% html_title(with_leading_slash(path)) -%> |
@@ -0,0 +1,35 | |||||
|
1 | Event.observe(window,'load',function() { | |||
|
2 | /* | |||
|
3 | If we're viewing a tag or branch, don't display it in the | |||
|
4 | revision box | |||
|
5 | */ | |||
|
6 | var branch_selected = $('branch') && $('rev').getValue() == $('branch').getValue(); | |||
|
7 | var tag_selected = $('tag') && $('rev').getValue() == $('tag').getValue(); | |||
|
8 | if (branch_selected || tag_selected) { | |||
|
9 | $('rev').setValue(''); | |||
|
10 | } | |||
|
11 | ||||
|
12 | /* | |||
|
13 | Copy the branch/tag value into the revision box, then disable | |||
|
14 | the dropdowns before submitting the form | |||
|
15 | */ | |||
|
16 | $$('#branch,#tag').each(function(e) { | |||
|
17 | e.observe('change',function(e) { | |||
|
18 | $('rev').setValue(e.element().getValue()); | |||
|
19 | $$('#branch,#tag').invoke('disable'); | |||
|
20 | e.element().parentNode.submit(); | |||
|
21 | $$('#branch,#tag').invoke('enable'); | |||
|
22 | }); | |||
|
23 | }); | |||
|
24 | ||||
|
25 | /* | |||
|
26 | Disable the branch/tag dropdowns before submitting the revision form | |||
|
27 | */ | |||
|
28 | $('rev').observe('keydown', function(e) { | |||
|
29 | if (e.keyCode == 13) { | |||
|
30 | $$('#branch,#tag').invoke('disable'); | |||
|
31 | e.element().parentNode.submit(); | |||
|
32 | $$('#branch,#tag').invoke('enable'); | |||
|
33 | } | |||
|
34 | }); | |||
|
35 | }) |
@@ -0,0 +1,22 | |||||
|
1 | require File.dirname(__FILE__) + '/../test_helper' | |||
|
2 | ||||
|
3 | class GitAdapterTest < Test::Unit::TestCase | |||
|
4 | REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository' | |||
|
5 | ||||
|
6 | if File.directory?(REPOSITORY_PATH) | |||
|
7 | def setup | |||
|
8 | @adapter = Redmine::Scm::Adapters::GitAdapter.new(REPOSITORY_PATH) | |||
|
9 | end | |||
|
10 | ||||
|
11 | def test_branches | |||
|
12 | assert_equal @adapter.branches, ['master', 'test_branch'] | |||
|
13 | end | |||
|
14 | ||||
|
15 | def test_getting_all_revisions | |||
|
16 | assert_equal 12, @adapter.revisions('',nil,nil,:all => true).length | |||
|
17 | end | |||
|
18 | else | |||
|
19 | puts "Git test repository NOT FOUND. Skipping unit tests !!!" | |||
|
20 | def test_fake; assert true end | |||
|
21 | end | |||
|
22 | end |
@@ -64,31 +64,26 class RepositoriesController < ApplicationController | |||||
64 | redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository' |
|
64 | redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository' | |
65 | end |
|
65 | end | |
66 |
|
66 | |||
67 | def show |
|
67 | def show | |
68 | # check if new revisions have been committed in the repository |
|
68 | @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty? | |
69 | @repository.fetch_changesets if Setting.autofetch_changesets? |
|
69 | ||
70 | # root entries |
|
|||
71 | @entries = @repository.entries('', @rev) |
|
|||
72 | # latest changesets |
|
|||
73 | @changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC") |
|
|||
74 | show_error_not_found unless @entries || @changesets.any? |
|
|||
75 | end |
|
|||
76 |
|
||||
77 | def browse |
|
|||
78 | @entries = @repository.entries(@path, @rev) |
|
70 | @entries = @repository.entries(@path, @rev) | |
79 | if request.xhr? |
|
71 | if request.xhr? | |
80 | @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) |
|
72 | @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) | |
81 | else |
|
73 | else | |
82 | show_error_not_found and return unless @entries |
|
74 | show_error_not_found and return unless @entries | |
|
75 | @changesets = @repository.latest_changesets(@path, @rev) | |||
83 | @properties = @repository.properties(@path, @rev) |
|
76 | @properties = @repository.properties(@path, @rev) | |
84 |
render :action => ' |
|
77 | render :action => 'show' | |
85 | end |
|
78 | end | |
86 | end |
|
79 | end | |
|
80 | ||||
|
81 | alias_method :browse, :show | |||
87 |
|
82 | |||
88 | def changes |
|
83 | def changes | |
89 | @entry = @repository.entry(@path, @rev) |
|
84 | @entry = @repository.entry(@path, @rev) | |
90 | show_error_not_found and return unless @entry |
|
85 | show_error_not_found and return unless @entry | |
91 |
@changesets = @repository.changesets |
|
86 | @changesets = @repository.latest_changesets(@path, @rev, Setting.repository_log_display_limit.to_i) | |
92 | @properties = @repository.properties(@path, @rev) |
|
87 | @properties = @repository.properties(@path, @rev) | |
93 | end |
|
88 | end | |
94 |
|
89 | |||
@@ -135,7 +130,7 class RepositoriesController < ApplicationController | |||||
135 | end |
|
130 | end | |
136 |
|
131 | |||
137 | def revision |
|
132 | def revision | |
138 |
@changeset = @repository.changesets.find |
|
133 | @changeset = @repository.changesets.find(:first, :conditions => ["revision LIKE ?", @rev + '%']) | |
139 | raise ChangesetNotFound unless @changeset |
|
134 | raise ChangesetNotFound unless @changeset | |
140 |
|
135 | |||
141 | respond_to do |format| |
|
136 | respond_to do |format| | |
@@ -199,17 +194,14 private | |||||
199 | render_404 |
|
194 | render_404 | |
200 | end |
|
195 | end | |
201 |
|
196 | |||
202 | REV_PARAM_RE = %r{^[a-f0-9]*$} |
|
|||
203 |
|
||||
204 | def find_repository |
|
197 | def find_repository | |
205 | @project = Project.find(params[:id]) |
|
198 | @project = Project.find(params[:id]) | |
206 | @repository = @project.repository |
|
199 | @repository = @project.repository | |
207 | render_404 and return false unless @repository |
|
200 | render_404 and return false unless @repository | |
208 | @path = params[:path].join('/') unless params[:path].nil? |
|
201 | @path = params[:path].join('/') unless params[:path].nil? | |
209 | @path ||= '' |
|
202 | @path ||= '' | |
210 | @rev = params[:rev] |
|
203 | @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].strip | |
211 | @rev_to = params[:rev_to] |
|
204 | @rev_to = params[:rev_to] | |
212 | raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE) |
|
|||
213 | rescue ActiveRecord::RecordNotFound |
|
205 | rescue ActiveRecord::RecordNotFound | |
214 | render_404 |
|
206 | render_404 | |
215 | rescue InvalidRevisionParam |
|
207 | rescue InvalidRevisionParam |
@@ -62,6 +62,18 class Repository < ActiveRecord::Base | |||||
62 | def entries(path=nil, identifier=nil) |
|
62 | def entries(path=nil, identifier=nil) | |
63 | scm.entries(path, identifier) |
|
63 | scm.entries(path, identifier) | |
64 | end |
|
64 | end | |
|
65 | ||||
|
66 | def branches | |||
|
67 | scm.branches | |||
|
68 | end | |||
|
69 | ||||
|
70 | def tags | |||
|
71 | scm.tags | |||
|
72 | end | |||
|
73 | ||||
|
74 | def default_branch | |||
|
75 | scm.default_branch | |||
|
76 | end | |||
65 |
|
77 | |||
66 | def properties(path, identifier=nil) |
|
78 | def properties(path, identifier=nil) | |
67 | scm.properties(path, identifier) |
|
79 | scm.properties(path, identifier) | |
@@ -92,11 +104,15 class Repository < ActiveRecord::Base | |||||
92 | def latest_changeset |
|
104 | def latest_changeset | |
93 | @latest_changeset ||= changesets.find(:first) |
|
105 | @latest_changeset ||= changesets.find(:first) | |
94 | end |
|
106 | end | |
|
107 | ||||
|
108 | def latest_changesets(path,rev,limit=10) | |||
|
109 | @latest_changesets ||= changesets.find(:all, limit, :order => "committed_on DESC") | |||
|
110 | end | |||
95 |
|
111 | |||
96 | def scan_changesets_for_issue_ids |
|
112 | def scan_changesets_for_issue_ids | |
97 | self.changesets.each(&:scan_comment_for_issue_ids) |
|
113 | self.changesets.each(&:scan_comment_for_issue_ids) | |
98 | end |
|
114 | end | |
99 |
|
115 | |||
100 | # Returns an array of committers usernames and associated user_id |
|
116 | # Returns an array of committers usernames and associated user_id | |
101 | def committers |
|
117 | def committers | |
102 | @committers ||= Changeset.connection.select_rows("SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}") |
|
118 | @committers ||= Changeset.connection.select_rows("SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}") |
@@ -29,43 +29,60 class Repository::Git < Repository | |||||
29 | 'Git' |
|
29 | 'Git' | |
30 | end |
|
30 | end | |
31 |
|
31 | |||
|
32 | def branches | |||
|
33 | scm.branches | |||
|
34 | end | |||
|
35 | ||||
|
36 | def tags | |||
|
37 | scm.tags | |||
|
38 | end | |||
|
39 | ||||
32 | def changesets_for_path(path, options={}) |
|
40 | def changesets_for_path(path, options={}) | |
33 | Change.find(:all, :include => {:changeset => :user}, |
|
41 | Change.find( | |
34 | :conditions => ["repository_id = ? AND path = ?", id, path], |
|
42 | :all, | |
35 | :order => "committed_on DESC, #{Changeset.table_name}.revision DESC", |
|
43 | :include => {:changeset => :user}, | |
36 | :limit => options[:limit]).collect(&:changeset) |
|
44 | :conditions => ["repository_id = ? AND path = ?", id, path], | |
|
45 | :order => "committed_on DESC, #{Changeset.table_name}.revision DESC", | |||
|
46 | :limit => options[:limit] | |||
|
47 | ).collect(&:changeset) | |||
37 | end |
|
48 | end | |
38 |
|
49 | |||
|
50 | # With SCM's that have a sequential commit numbering, redmine is able to be | |||
|
51 | # clever and only fetch changesets going forward from the most recent one | |||
|
52 | # it knows about. However, with git, you never know if people have merged | |||
|
53 | # commits into the middle of the repository history, so we always have to | |||
|
54 | # parse the entire log. | |||
39 | def fetch_changesets |
|
55 | def fetch_changesets | |
40 | scm_info = scm.info |
|
56 | # Save ourselves an expensive operation if we're already up to date | |
41 | if scm_info |
|
57 | return if scm.num_revisions == changesets.count | |
42 | # latest revision found in database |
|
58 | ||
43 | db_revision = latest_changeset ? latest_changeset.revision : nil |
|
59 | revisions = scm.revisions('', nil, nil, :all => true) | |
44 | # latest revision in the repository |
|
60 | return if revisions.nil? || revisions.empty? | |
45 | scm_revision = scm_info.lastrev.scmid |
|
61 | ||
|
62 | # Find revisions that redmine knows about already | |||
|
63 | existing_revisions = changesets.find(:all).map!{|c| c.scmid} | |||
|
64 | ||||
|
65 | # Clean out revisions that are no longer in git | |||
|
66 | Changeset.delete_all(["scmid NOT IN (?) AND repository_id = (?)", revisions.map{|r| r.scmid}, self.id]) | |||
|
67 | ||||
|
68 | # Subtract revisions that redmine already knows about | |||
|
69 | revisions.reject!{|r| existing_revisions.include?(r.scmid)} | |||
|
70 | ||||
|
71 | # Save the remaining ones to the database | |||
|
72 | revisions.each{|r| r.save(self)} unless revisions.nil? | |||
|
73 | end | |||
|
74 | ||||
|
75 | def latest_changesets(path,rev,limit=10) | |||
|
76 | revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false) | |||
|
77 | return [] if revisions.nil? || revisions.empty? | |||
46 |
|
78 | |||
47 | unless changesets.find_by_scmid(scm_revision) |
|
79 | changesets.find( | |
48 | scm.revisions('', db_revision, nil, :reverse => true) do |revision| |
|
80 | :all, | |
49 | if changesets.find_by_scmid(revision.scmid.to_s).nil? |
|
81 | :conditions => [ | |
50 | transaction do |
|
82 | "scmid IN (?)", | |
51 | changeset = Changeset.create!(:repository => self, |
|
83 | revisions.map!{|c| c.scmid} | |
52 | :revision => revision.identifier, |
|
84 | ], | |
53 | :scmid => revision.scmid, |
|
85 | :order => 'committed_on DESC' | |
54 | :committer => revision.author, |
|
86 | ) | |
55 | :committed_on => revision.time, |
|
|||
56 | :comments => revision.message) |
|
|||
57 |
|
||||
58 | revision.paths.each do |change| |
|
|||
59 | Change.create!(:changeset => changeset, |
|
|||
60 | :action => change[:action], |
|
|||
61 | :path => change[:path], |
|
|||
62 | :from_path => change[:from_path], |
|
|||
63 | :from_revision => change[:from_revision]) |
|
|||
64 | end |
|
|||
65 | end |
|
|||
66 | end |
|
|||
67 | end |
|
|||
68 | end |
|
|||
69 | end |
|
|||
70 | end |
|
87 | end | |
71 | end |
|
88 | end |
@@ -4,7 +4,7 | |||||
4 | <tr id="<%= tr_id %>" class="<%= params[:parent_id] %> entry <%= entry.kind %>"> |
|
4 | <tr id="<%= tr_id %>" class="<%= params[:parent_id] %> entry <%= entry.kind %>"> | |
5 | <td style="padding-left: <%=18 * depth%>px;" class="filename"> |
|
5 | <td style="padding-left: <%=18 * depth%>px;" class="filename"> | |
6 | <% if entry.is_dir? %> |
|
6 | <% if entry.is_dir? %> | |
7 |
<span class="expander" onclick="<%= remote_function :url => {:action => ' |
|
7 | <span class="expander" onclick="<%= remote_function :url => {:action => 'show', :id => @project, :path => to_path_param(entry.path), :rev => @rev, :depth => (depth + 1), :parent_id => tr_id}, | |
8 | :method => :get, |
|
8 | :method => :get, | |
9 | :update => { :success => tr_id }, |
|
9 | :update => { :success => tr_id }, | |
10 | :position => :after, |
|
10 | :position => :after, | |
@@ -12,7 +12,7 | |||||
12 | :condition => "scmEntryClick('#{tr_id}')"%>"> </span> |
|
12 | :condition => "scmEntryClick('#{tr_id}')"%>"> </span> | |
13 | <% end %> |
|
13 | <% end %> | |
14 | <%= link_to h(entry.name), |
|
14 | <%= link_to h(entry.name), | |
15 |
{:action => (entry.is_dir? ? ' |
|
15 | {:action => (entry.is_dir? ? 'show' : 'changes'), :id => @project, :path => to_path_param(entry.path), :rev => @rev}, | |
16 | :class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(entry.name)}")%> |
|
16 | :class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(entry.name)}")%> | |
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> |
@@ -1,21 +1,21 | |||||
1 | <%= link_to 'root', :action => 'browse', :id => @project, :path => '', :rev => @rev %> |
|
1 | <% content_for :header_tags do %> | |
2 | <% |
|
2 | <%= javascript_include_tag 'repository_navigation' %> | |
3 | dirs = path.split('/') |
|
|||
4 | if 'file' == kind |
|
|||
5 | filename = dirs.pop |
|
|||
6 | end |
|
|||
7 | link_path = '' |
|
|||
8 | dirs.each do |dir| |
|
|||
9 | next if dir.blank? |
|
|||
10 | link_path << '/' unless link_path.empty? |
|
|||
11 | link_path << "#{dir}" |
|
|||
12 | %> |
|
|||
13 | / <%= link_to h(dir), :action => 'browse', :id => @project, :path => to_path_param(link_path), :rev => @rev %> |
|
|||
14 | <% end %> |
|
|||
15 | <% if filename %> |
|
|||
16 | / <%= link_to h(filename), :action => 'changes', :id => @project, :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %> |
|
|||
17 | <% end %> |
|
3 | <% end %> | |
18 |
|
4 | |||
19 | <%= "@ #{revision}" if revision %> |
|
5 | <%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %> | |
|
6 | ||||
|
7 | <% form_tag({:action => controller.action_name, :id => @project, :path => @path, :rev => ''}, {:method => :get, :id => 'revision_selector'}) do -%> | |||
|
8 | <!-- Branches Dropdown --> | |||
|
9 | <% if !@repository.branches.nil? && @repository.branches.length > 0 -%> | |||
|
10 | | <%= l(:label_branch) %>: | |||
|
11 | <%= select_tag :branch, options_for_select([''] + @repository.branches,@rev), :id => 'branch' %> | |||
|
12 | <% end -%> | |||
|
13 | ||||
|
14 | <% if !@repository.tags.nil? && @repository.tags.length > 0 -%> | |||
|
15 | | <%= l(:label_tag) %>: | |||
|
16 | <%= select_tag :tag, options_for_select([''] + @repository.tags,@rev), :id => 'tag' %> | |||
|
17 | <% end -%> | |||
20 |
|
18 | |||
21 | <% html_title(with_leading_slash(path)) -%> |
|
19 | | <%= l(:label_revision) %>: | |
|
20 | <%= text_field_tag 'rev', @rev, :size => 8 %> | |||
|
21 | <% end -%> |
@@ -1,4 +1,10 | |||||
1 | <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2> |
|
1 | <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> | |
|
2 | ||||
|
3 | <div class="contextual"> | |||
|
4 | <%= render :partial => 'navigation' %> | |||
|
5 | </div> | |||
|
6 | ||||
|
7 | <h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2> | |||
2 |
|
8 | |||
3 | <p><%= render :partial => 'link_to_functions' %></p> |
|
9 | <p><%= render :partial => 'link_to_functions' %></p> | |
4 |
|
10 |
@@ -1,10 +1,8 | |||||
1 | <div class="contextual"> |
|
1 | <div class="contextual"> | |
2 | <% form_tag({}, :method => :get) do %> |
|
2 | <%= render :partial => 'navigation' %> | |
3 | <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %> |
|
|||
4 | <% end %> |
|
|||
5 | </div> |
|
3 | </div> | |
6 |
|
4 | |||
7 |
<h2><%= render :partial => ' |
|
5 | <h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'dir', :revision => @rev } %></h2> | |
8 |
|
6 | |||
9 | <%= render :partial => 'dir_list' %> |
|
7 | <%= render :partial => 'dir_list' %> | |
10 | <%= render_properties(@properties) %> |
|
8 | <%= render_properties(@properties) %> |
@@ -1,4 +1,12 | |||||
1 | <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %></h2> |
|
1 | <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> | |
|
2 | ||||
|
3 | <div class="contextual"> | |||
|
4 | <%= render :partial => 'navigation' %> | |||
|
5 | </div> | |||
|
6 | ||||
|
7 | <h2> | |||
|
8 | <%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %> | |||
|
9 | </h2> | |||
2 |
|
10 | |||
3 | <p><%= render :partial => 'link_to_functions' %></p> |
|
11 | <p><%= render :partial => 'link_to_functions' %></p> | |
4 |
|
12 |
@@ -1,4 +1,10 | |||||
1 | <h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2> |
|
1 | <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> | |
|
2 | ||||
|
3 | <div class="contextual"> | |||
|
4 | <%= render :partial => 'navigation' %> | |||
|
5 | </div> | |||
|
6 | ||||
|
7 | <h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'file', :revision => @rev } %></h2> | |||
2 |
|
8 | |||
3 | <p><%= render :partial => 'link_to_functions' %></p> |
|
9 | <p><%= render :partial => 'link_to_functions' %></p> | |
4 |
|
10 |
@@ -14,7 +14,7 | |||||
14 | » |
|
14 | » | |
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, :size => |
|
17 | <%= text_field_tag 'rev', @rev[0,8], :size => 8 %> | |
18 | <%= submit_tag 'OK', :name => nil %> |
|
18 | <%= submit_tag 'OK', :name => nil %> | |
19 | <% end %> |
|
19 | <% end %> | |
20 | </div> |
|
20 | </div> |
@@ -1,6 +1,6 | |||||
1 | <div class="contextual"> |
|
1 | <div class="contextual"> | |
2 | <% form_tag({:action => 'revision', :id => @project}) do %> |
|
2 | <% form_tag({:action => 'revision', :id => @project}) do %> | |
3 |
<%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => |
|
3 | <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 8 %> | |
4 | <%= submit_tag 'OK' %> |
|
4 | <%= submit_tag 'OK' %> | |
5 | <% end %> |
|
5 | <% end %> | |
6 | </div> |
|
6 | </div> |
@@ -1,15 +1,10 | |||||
1 | <div class="contextual"> |
|
|||
2 | <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> |
|
1 | <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %> | |
3 | <%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %> |
|
|||
4 |
|
2 | |||
5 | <% if !@entries.nil? && authorize_for('repositories', 'browse') -%> |
|
3 | <div class="contextual"> | |
6 | <% form_tag({:action => 'browse', :id => @project}, :method => :get) do -%> |
|
4 | <%= render :partial => 'navigation' %> | |
7 | | <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %> |
|
|||
8 | <% end -%> |
|
|||
9 | <% end -%> |
|
|||
10 | </div> |
|
5 | </div> | |
11 |
|
6 | |||
12 | <h2><%= l(:label_repository) %> (<%= @repository.scm_name %>)</h2> |
|
7 | <h2><%= render :partial => 'breadcrumbs', :locals => { :path => @path, :kind => 'dir', :revision => @rev } %></h2> | |
13 |
|
8 | |||
14 | <% if !@entries.nil? && authorize_for('repositories', 'browse') %> |
|
9 | <% if !@entries.nil? && authorize_for('repositories', 'browse') %> | |
15 | <%= render :partial => 'dir_list' %> |
|
10 | <%= render :partial => 'dir_list' %> | |
@@ -18,7 +13,7 | |||||
18 | <% if !@changesets.empty? && authorize_for('repositories', 'revisions') %> |
|
13 | <% if !@changesets.empty? && authorize_for('repositories', 'revisions') %> | |
19 | <h3><%= l(:label_latest_revision_plural) %></h3> |
|
14 | <h3><%= l(:label_latest_revision_plural) %></h3> | |
20 | <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%> |
|
15 | <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%> | |
21 | <p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p> |
|
16 | <p><%= link_to l(:label_view_all_revisions), :action => 'revisions', :id => @project %></p> | |
22 | <% content_for :header_tags do %> |
|
17 | <% content_for :header_tags do %> | |
23 | <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :action => 'revisions', :id => @project, :page => nil, :key => User.current.rss_key})) %> |
|
18 | <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :action => 'revisions', :id => @project, :page => nil, :key => User.current.rss_key})) %> | |
24 | <% end %> |
|
19 | <% end %> |
@@ -798,3 +798,6 bg: | |||||
798 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
798 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
799 | permission_add_project: Create project |
|
799 | permission_add_project: Create project | |
800 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
800 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
801 | label_view_all_revisions: View all revisions | |||
|
802 | label_tag: Tag | |||
|
803 | label_branch: Branch |
@@ -831,3 +831,6 bs: | |||||
831 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
831 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
832 | permission_add_project: Create project |
|
832 | permission_add_project: Create project | |
833 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
833 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
834 | label_view_all_revisions: View all revisions | |||
|
835 | label_tag: Tag | |||
|
836 | label_branch: Branch |
@@ -801,3 +801,6 ca: | |||||
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
802 | permission_add_project: Create project |
|
802 | permission_add_project: Create project | |
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
804 | label_view_all_revisions: View all revisions | |||
|
805 | label_tag: Tag | |||
|
806 | label_branch: Branch |
@@ -804,3 +804,6 cs: | |||||
804 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
804 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
805 | permission_add_project: Create project |
|
805 | permission_add_project: Create project | |
806 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
806 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
807 | label_view_all_revisions: View all revisions | |||
|
808 | label_tag: Tag | |||
|
809 | label_branch: Branch |
@@ -831,3 +831,6 da: | |||||
831 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
831 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
832 | permission_add_project: Create project |
|
832 | permission_add_project: Create project | |
833 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
833 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
834 | label_view_all_revisions: View all revisions | |||
|
835 | label_tag: Tag | |||
|
836 | label_branch: Branch |
@@ -830,3 +830,6 de: | |||||
830 | mail_body_wiki_content_updated: "Die Wiki-Seite '{{page}}' wurde von {{author}} aktualisiert." |
|
830 | mail_body_wiki_content_updated: "Die Wiki-Seite '{{page}}' wurde von {{author}} aktualisiert." | |
831 | permission_add_project: Erstelle Projekt |
|
831 | permission_add_project: Erstelle Projekt | |
832 | setting_new_project_user_role_id: Rolle einem Nicht-Administrator zugeordnet, welcher ein Projekt erstellt |
|
832 | setting_new_project_user_role_id: Rolle einem Nicht-Administrator zugeordnet, welcher ein Projekt erstellt | |
|
833 | label_view_all_revisions: View all revisions | |||
|
834 | label_tag: Tag | |||
|
835 | label_branch: Branch |
@@ -543,6 +543,8 en: | |||||
543 | label_browse: Browse |
|
543 | label_browse: Browse | |
544 | label_modification: "{{count}} change" |
|
544 | label_modification: "{{count}} change" | |
545 | label_modification_plural: "{{count}} changes" |
|
545 | label_modification_plural: "{{count}} changes" | |
|
546 | label_branch: Branch | |||
|
547 | label_tag: Tag | |||
546 | label_revision: Revision |
|
548 | label_revision: Revision | |
547 | label_revision_plural: Revisions |
|
549 | label_revision_plural: Revisions | |
548 | label_associated_revisions: Associated revisions |
|
550 | label_associated_revisions: Associated revisions | |
@@ -554,6 +556,7 en: | |||||
554 | label_latest_revision: Latest revision |
|
556 | label_latest_revision: Latest revision | |
555 | label_latest_revision_plural: Latest revisions |
|
557 | label_latest_revision_plural: Latest revisions | |
556 | label_view_revisions: View revisions |
|
558 | label_view_revisions: View revisions | |
|
559 | label_view_all_revisions: View all revisions | |||
557 | label_max_size: Maximum size |
|
560 | label_max_size: Maximum size | |
558 | label_sort_highest: Move to top |
|
561 | label_sort_highest: Move to top | |
559 | label_sort_higher: Move up |
|
562 | label_sort_higher: Move up |
@@ -851,3 +851,6 es: | |||||
851 | mail_body_wiki_content_updated: La página wiki '{{page}}' ha sido actualizada por {{author}}. |
|
851 | mail_body_wiki_content_updated: La página wiki '{{page}}' ha sido actualizada por {{author}}. | |
852 | permission_add_project: Crear proyecto |
|
852 | permission_add_project: Crear proyecto | |
853 | setting_new_project_user_role_id: Permiso asignado a un usuario no-administrador para crear proyectos |
|
853 | setting_new_project_user_role_id: Permiso asignado a un usuario no-administrador para crear proyectos | |
|
854 | label_view_all_revisions: View all revisions | |||
|
855 | label_tag: Tag | |||
|
856 | label_branch: Branch |
@@ -841,3 +841,6 fi: | |||||
841 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
841 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
842 | permission_add_project: Create project |
|
842 | permission_add_project: Create project | |
843 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
843 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
844 | label_view_all_revisions: View all revisions | |||
|
845 | label_tag: Tag | |||
|
846 | label_branch: Branch |
@@ -832,4 +832,7 fr: | |||||
832 | enumeration_doc_categories: Catégories des documents |
|
832 | enumeration_doc_categories: Catégories des documents | |
833 | enumeration_activities: Activités (suivi du temps) |
|
833 | enumeration_activities: Activités (suivi du temps) | |
834 | label_greater_or_equal: ">=" |
|
834 | label_greater_or_equal: ">=" | |
835 | label_less_or_equal: <= |
|
835 | label_less_or_equal: "<=" | |
|
836 | label_view_all_revisions: View all revisions | |||
|
837 | label_tag: Tag | |||
|
838 | label_branch: Branch |
@@ -830,3 +830,6 gl: | |||||
830 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
830 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
831 | permission_add_project: Create project |
|
831 | permission_add_project: Create project | |
832 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
832 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
833 | label_view_all_revisions: View all revisions | |||
|
834 | label_tag: Tag | |||
|
835 | label_branch: Branch |
@@ -813,3 +813,6 he: | |||||
813 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
813 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
814 | permission_add_project: Create project |
|
814 | permission_add_project: Create project | |
815 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
815 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
816 | label_view_all_revisions: View all revisions | |||
|
817 | label_tag: Tag | |||
|
818 | label_branch: Branch |
@@ -836,3 +836,6 | |||||
836 | mail_body_wiki_content_updated: A '{{page}}' wiki oldalt {{author}} frissítette. |
|
836 | mail_body_wiki_content_updated: A '{{page}}' wiki oldalt {{author}} frissítette. | |
837 | permission_add_project: Projekt létrehozása |
|
837 | permission_add_project: Projekt létrehozása | |
838 | setting_new_project_user_role_id: Projekt létrehozási jog nem adminisztrátor felhasználóknak |
|
838 | setting_new_project_user_role_id: Projekt létrehozási jog nem adminisztrátor felhasználóknak | |
|
839 | label_view_all_revisions: View all revisions | |||
|
840 | label_tag: Tag | |||
|
841 | label_branch: Branch |
@@ -816,3 +816,6 it: | |||||
816 | mail_body_wiki_content_updated: La pagina '{{page}}' wiki è stata aggiornata da{{author}}. |
|
816 | mail_body_wiki_content_updated: La pagina '{{page}}' wiki è stata aggiornata da{{author}}. | |
817 | permission_add_project: Crea progetto |
|
817 | permission_add_project: Crea progetto | |
818 | setting_new_project_user_role_id: Ruolo assegnato agli utenti non amministratori che creano un progetto |
|
818 | setting_new_project_user_role_id: Ruolo assegnato agli utenti non amministratori che creano un progetto | |
|
819 | label_view_all_revisions: View all revisions | |||
|
820 | label_tag: Tag | |||
|
821 | label_branch: Branch |
@@ -838,3 +838,6 ja: | |||||
838 | enumeration_issue_priorities: チケットの優先度 |
|
838 | enumeration_issue_priorities: チケットの優先度 | |
839 | enumeration_doc_categories: 文書カテゴリ |
|
839 | enumeration_doc_categories: 文書カテゴリ | |
840 | enumeration_activities: 作業分類 (時間トラッキング) |
|
840 | enumeration_activities: 作業分類 (時間トラッキング) | |
|
841 | label_view_all_revisions: View all revisions | |||
|
842 | label_tag: Tag | |||
|
843 | label_branch: Branch |
@@ -869,3 +869,6 ko: | |||||
869 | # by Kihyun Yoon(ddumbugie@gmail.com) |
|
869 | # by Kihyun Yoon(ddumbugie@gmail.com) | |
870 | # by John Hwang (jhwang@tavon.org),http://github.com/tavon |
|
870 | # by John Hwang (jhwang@tavon.org),http://github.com/tavon | |
871 | field_issue_to: Related issue |
|
871 | field_issue_to: Related issue | |
|
872 | label_view_all_revisions: View all revisions | |||
|
873 | label_tag: Tag | |||
|
874 | label_branch: Branch |
@@ -841,3 +841,6 lt: | |||||
841 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
841 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
842 | permission_add_project: Create project |
|
842 | permission_add_project: Create project | |
843 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
843 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
844 | label_view_all_revisions: View all revisions | |||
|
845 | label_tag: Tag | |||
|
846 | label_branch: Branch |
@@ -786,3 +786,6 nl: | |||||
786 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
786 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
787 | permission_add_project: Create project |
|
787 | permission_add_project: Create project | |
788 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
788 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
789 | label_view_all_revisions: View all revisions | |||
|
790 | label_tag: Tag | |||
|
791 | label_branch: Branch |
@@ -803,3 +803,6 | |||||
803 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
803 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
804 | permission_add_project: Create project |
|
804 | permission_add_project: Create project | |
805 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
805 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
806 | label_view_all_revisions: View all revisions | |||
|
807 | label_tag: Tag | |||
|
808 | label_branch: Branch |
@@ -834,3 +834,6 pl: | |||||
834 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
834 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
835 | permission_add_project: Create project |
|
835 | permission_add_project: Create project | |
836 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
836 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
837 | label_view_all_revisions: View all revisions | |||
|
838 | label_tag: Tag | |||
|
839 | label_branch: Branch |
@@ -836,3 +836,6 pt-BR: | |||||
836 | mail_body_wiki_content_updated: A página wiki '{{page}}' foi atualizada por {{author}}. |
|
836 | mail_body_wiki_content_updated: A página wiki '{{page}}' foi atualizada por {{author}}. | |
837 | permission_add_project: Criar projeto |
|
837 | permission_add_project: Criar projeto | |
838 | setting_new_project_user_role_id: Papel dado a um usuário não administrador que crie um projeto |
|
838 | setting_new_project_user_role_id: Papel dado a um usuário não administrador que crie um projeto | |
|
839 | label_view_all_revisions: View all revisions | |||
|
840 | label_tag: Tag | |||
|
841 | label_branch: Branch |
@@ -822,3 +822,6 pt: | |||||
822 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
822 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
823 | permission_add_project: Create project |
|
823 | permission_add_project: Create project | |
824 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
824 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
825 | label_view_all_revisions: View all revisions | |||
|
826 | label_tag: Tag | |||
|
827 | label_branch: Branch |
@@ -801,3 +801,6 ro: | |||||
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
802 | permission_add_project: Create project |
|
802 | permission_add_project: Create project | |
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
804 | label_view_all_revisions: View all revisions | |||
|
805 | label_tag: Tag | |||
|
806 | label_branch: Branch |
@@ -928,3 +928,6 ru: | |||||
928 | mail_body_wiki_content_updated: "{{author}} обновил(а) wiki-страницу '{{page}}'." |
|
928 | mail_body_wiki_content_updated: "{{author}} обновил(а) wiki-страницу '{{page}}'." | |
929 | permission_add_project: Создание проекта |
|
929 | permission_add_project: Создание проекта | |
930 | setting_new_project_user_role_id: Роль, назначаемая пользователю, создавшему проект |
|
930 | setting_new_project_user_role_id: Роль, назначаемая пользователю, создавшему проект | |
|
931 | label_view_all_revisions: View all revisions | |||
|
932 | label_tag: Tag | |||
|
933 | label_branch: Branch |
@@ -802,4 +802,7 sk: | |||||
802 | label_wiki_content_updated: Wiki stránka aktualizovaná |
|
802 | label_wiki_content_updated: Wiki stránka aktualizovaná | |
803 | mail_body_wiki_content_updated: Wiki stránka '{{page}}' bola aktualizovaná užívateľom {{author}}. |
|
803 | mail_body_wiki_content_updated: Wiki stránka '{{page}}' bola aktualizovaná užívateľom {{author}}. | |
804 | setting_repositories_encodings: Kódovanie repozitára |
|
804 | setting_repositories_encodings: Kódovanie repozitára | |
805 |
setting_new_project_user_role_id: Rola dána non-admin užívateľovi, ktorý vytvorí projekt |
|
805 | setting_new_project_user_role_id: Rola dána non-admin užívateľovi, ktorý vytvorí projekt | |
|
806 | label_view_all_revisions: View all revisions | |||
|
807 | label_tag: Tag | |||
|
808 | label_branch: Branch |
@@ -800,3 +800,6 sl: | |||||
800 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
800 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
801 | permission_add_project: Create project |
|
801 | permission_add_project: Create project | |
802 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
802 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
803 | label_view_all_revisions: View all revisions | |||
|
804 | label_tag: Tag | |||
|
805 | label_branch: Branch |
@@ -824,3 +824,6 | |||||
824 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
824 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
825 | permission_add_project: Create project |
|
825 | permission_add_project: Create project | |
826 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
826 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
827 | label_view_all_revisions: View all revisions | |||
|
828 | label_tag: Tag | |||
|
829 | label_branch: Branch |
@@ -858,3 +858,6 sv: | |||||
858 | enumeration_issue_priorities: Ärendeprioriteter |
|
858 | enumeration_issue_priorities: Ärendeprioriteter | |
859 | enumeration_doc_categories: Dokumentkategorier |
|
859 | enumeration_doc_categories: Dokumentkategorier | |
860 | enumeration_activities: Aktiviteter (tidsuppföljning) |
|
860 | enumeration_activities: Aktiviteter (tidsuppföljning) | |
|
861 | label_view_all_revisions: View all revisions | |||
|
862 | label_tag: Tag | |||
|
863 | label_branch: Branch |
@@ -801,3 +801,6 th: | |||||
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
801 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
802 | permission_add_project: Create project |
|
802 | permission_add_project: Create project | |
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
803 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
804 | label_view_all_revisions: View all revisions | |||
|
805 | label_tag: Tag | |||
|
806 | label_branch: Branch |
@@ -837,3 +837,6 tr: | |||||
837 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
837 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
838 | permission_add_project: Create project |
|
838 | permission_add_project: Create project | |
839 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
839 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
840 | label_view_all_revisions: View all revisions | |||
|
841 | label_tag: Tag | |||
|
842 | label_branch: Branch |
@@ -800,3 +800,6 uk: | |||||
800 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
800 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
801 | permission_add_project: Create project |
|
801 | permission_add_project: Create project | |
802 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
802 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
803 | label_view_all_revisions: View all revisions | |||
|
804 | label_tag: Tag | |||
|
805 | label_branch: Branch |
@@ -870,3 +870,6 vi: | |||||
870 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. |
|
870 | mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}. | |
871 | permission_add_project: Create project |
|
871 | permission_add_project: Create project | |
872 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
872 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
|
873 | label_view_all_revisions: View all revisions | |||
|
874 | label_tag: Tag | |||
|
875 | label_branch: Branch |
@@ -908,3 +908,6 | |||||
908 | enumeration_issue_priorities: 項目優先權 |
|
908 | enumeration_issue_priorities: 項目優先權 | |
909 | enumeration_doc_categories: 文件分類 |
|
909 | enumeration_doc_categories: 文件分類 | |
910 | enumeration_activities: 活動 (時間追蹤) |
|
910 | enumeration_activities: 活動 (時間追蹤) | |
|
911 | label_view_all_revisions: View all revisions | |||
|
912 | label_tag: Tag | |||
|
913 | label_branch: Branch |
@@ -833,3 +833,6 zh: | |||||
833 | enumeration_issue_priorities: 问题优先级 |
|
833 | enumeration_issue_priorities: 问题优先级 | |
834 | enumeration_doc_categories: 文档类别 |
|
834 | enumeration_doc_categories: 文档类别 | |
835 | enumeration_activities: 活动(时间跟踪) |
|
835 | enumeration_activities: 活动(时间跟踪) | |
|
836 | label_view_all_revisions: View all revisions | |||
|
837 | label_tag: Tag | |||
|
838 | label_branch: Branch |
@@ -218,7 +218,7 ActionController::Routing::Routes.draw do |map| | |||||
218 | repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision' |
|
218 | repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision' | |
219 | repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff' |
|
219 | repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff' | |
220 | repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff' |
|
220 | repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff' | |
221 | repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path' |
|
221 | repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ } | |
222 | repository_views.connect 'projects/:id/repository/:action/*path' |
|
222 | repository_views.connect 'projects/:id/repository/:action/*path' | |
223 | end |
|
223 | end | |
224 |
|
224 |
@@ -1,153 +1,155 | |||||
1 | class Diff |
|
1 | module RedmineDiff | |
|
2 | class Diff | |||
2 |
|
3 | |||
3 | VERSION = 0.3 |
|
4 | VERSION = 0.3 | |
4 |
|
5 | |||
5 | def Diff.lcs(a, b) |
|
6 | def Diff.lcs(a, b) | |
6 | astart = 0 |
|
7 | astart = 0 | |
7 | bstart = 0 |
|
8 | bstart = 0 | |
8 | afinish = a.length-1 |
|
9 | afinish = a.length-1 | |
9 | bfinish = b.length-1 |
|
10 | bfinish = b.length-1 | |
10 | mvector = [] |
|
11 | mvector = [] | |
11 |
|
12 | |||
12 | # First we prune off any common elements at the beginning |
|
13 | # First we prune off any common elements at the beginning | |
13 | while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart]) |
|
14 | while (astart <= afinish && bstart <= afinish && a[astart] == b[bstart]) | |
14 | mvector[astart] = bstart |
|
15 | mvector[astart] = bstart | |
15 | astart += 1 |
|
16 | astart += 1 | |
16 | bstart += 1 |
|
17 | bstart += 1 | |
17 | end |
|
18 | end | |
18 |
|
19 | |||
19 | # now the end |
|
20 | # now the end | |
20 | while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish]) |
|
21 | while (astart <= afinish && bstart <= bfinish && a[afinish] == b[bfinish]) | |
21 | mvector[afinish] = bfinish |
|
22 | mvector[afinish] = bfinish | |
22 | afinish -= 1 |
|
23 | afinish -= 1 | |
23 | bfinish -= 1 |
|
24 | bfinish -= 1 | |
24 | end |
|
25 | end | |
25 |
|
26 | |||
26 | bmatches = b.reverse_hash(bstart..bfinish) |
|
27 | bmatches = b.reverse_hash(bstart..bfinish) | |
27 | thresh = [] |
|
28 | thresh = [] | |
28 | links = [] |
|
29 | links = [] | |
29 |
|
30 | |||
30 | (astart..afinish).each { |aindex| |
|
31 | (astart..afinish).each { |aindex| | |
31 | aelem = a[aindex] |
|
32 | aelem = a[aindex] | |
32 | next unless bmatches.has_key? aelem |
|
33 | next unless bmatches.has_key? aelem | |
33 | k = nil |
|
34 | k = nil | |
34 | bmatches[aelem].reverse.each { |bindex| |
|
35 | bmatches[aelem].reverse.each { |bindex| | |
35 |
|
|
36 | if k && (thresh[k] > bindex) && (thresh[k-1] < bindex) | |
36 |
|
|
37 | thresh[k] = bindex | |
37 |
|
|
38 | else | |
38 |
|
|
39 | k = thresh.replacenextlarger(bindex, k) | |
39 | end |
|
40 | end | |
40 |
|
|
41 | links[k] = [ (k==0) ? nil : links[k-1], aindex, bindex ] if k | |
|
42 | } | |||
41 | } |
|
43 | } | |
42 | } |
|
|||
43 |
|
44 | |||
44 | if !thresh.empty? |
|
45 | if !thresh.empty? | |
45 | link = links[thresh.length-1] |
|
46 | link = links[thresh.length-1] | |
46 | while link |
|
47 | while link | |
47 |
|
|
48 | mvector[link[1]] = link[2] | |
48 |
|
|
49 | link = link[0] | |
|
50 | end | |||
49 | end |
|
51 | end | |
50 | end |
|
|||
51 |
|
52 | |||
52 | return mvector |
|
53 | return mvector | |
53 | end |
|
|||
54 |
|
||||
55 | def makediff(a, b) |
|
|||
56 | mvector = Diff.lcs(a, b) |
|
|||
57 | ai = bi = 0 |
|
|||
58 | while ai < mvector.length |
|
|||
59 | bline = mvector[ai] |
|
|||
60 | if bline |
|
|||
61 | while bi < bline |
|
|||
62 | discardb(bi, b[bi]) |
|
|||
63 | bi += 1 |
|
|||
64 | end |
|
|||
65 | match(ai, bi) |
|
|||
66 | bi += 1 |
|
|||
67 | else |
|
|||
68 | discarda(ai, a[ai]) |
|
|||
69 | end |
|
|||
70 | ai += 1 |
|
|||
71 | end |
|
|||
72 | while ai < a.length |
|
|||
73 | discarda(ai, a[ai]) |
|
|||
74 | ai += 1 |
|
|||
75 | end |
|
54 | end | |
76 | while bi < b.length |
|
55 | ||
|
56 | def makediff(a, b) | |||
|
57 | mvector = Diff.lcs(a, b) | |||
|
58 | ai = bi = 0 | |||
|
59 | while ai < mvector.length | |||
|
60 | bline = mvector[ai] | |||
|
61 | if bline | |||
|
62 | while bi < bline | |||
77 | discardb(bi, b[bi]) |
|
63 | discardb(bi, b[bi]) | |
78 | bi += 1 |
|
64 | bi += 1 | |
79 | end |
|
65 | end | |
80 | match(ai, bi) |
|
66 | match(ai, bi) | |
81 | 1 |
|
67 | bi += 1 | |
82 | end |
|
68 | else | |
83 |
|
69 | discarda(ai, a[ai]) | ||
84 | def compactdiffs |
|
70 | end | |
85 | diffs = [] |
|
71 | ai += 1 | |
86 | @diffs.each { |df| |
|
|||
87 | i = 0 |
|
|||
88 | curdiff = [] |
|
|||
89 | while i < df.length |
|
|||
90 | whot = df[i][0] |
|
|||
91 | s = @isstring ? df[i][2].chr : [df[i][2]] |
|
|||
92 | p = df[i][1] |
|
|||
93 | last = df[i][1] |
|
|||
94 | i += 1 |
|
|||
95 | while df[i] && df[i][0] == whot && df[i][1] == last+1 |
|
|||
96 | s << df[i][2] |
|
|||
97 | last = df[i][1] |
|
|||
98 | i += 1 |
|
|||
99 | end |
|
|||
100 | curdiff.push [whot, p, s] |
|
|||
101 | end |
|
72 | end | |
102 | diffs.push curdiff |
|
73 | while ai < a.length | |
103 | } |
|
74 | discarda(ai, a[ai]) | |
104 | return diffs |
|
75 | ai += 1 | |
105 | end |
|
76 | end | |
|
77 | while bi < b.length | |||
|
78 | discardb(bi, b[bi]) | |||
|
79 | bi += 1 | |||
|
80 | end | |||
|
81 | match(ai, bi) | |||
|
82 | 1 | |||
|
83 | end | |||
106 |
|
84 | |||
107 | attr_reader :diffs, :difftype |
|
85 | def compactdiffs | |
|
86 | diffs = [] | |||
|
87 | @diffs.each { |df| | |||
|
88 | i = 0 | |||
|
89 | curdiff = [] | |||
|
90 | while i < df.length | |||
|
91 | whot = df[i][0] | |||
|
92 | s = @isstring ? df[i][2].chr : [df[i][2]] | |||
|
93 | p = df[i][1] | |||
|
94 | last = df[i][1] | |||
|
95 | i += 1 | |||
|
96 | while df[i] && df[i][0] == whot && df[i][1] == last+1 | |||
|
97 | s << df[i][2] | |||
|
98 | last = df[i][1] | |||
|
99 | i += 1 | |||
|
100 | end | |||
|
101 | curdiff.push [whot, p, s] | |||
|
102 | end | |||
|
103 | diffs.push curdiff | |||
|
104 | } | |||
|
105 | return diffs | |||
|
106 | end | |||
108 |
|
107 | |||
109 | def initialize(diffs_or_a, b = nil, isstring = nil) |
|
108 | attr_reader :diffs, :difftype | |
110 | if b.nil? |
|
109 | ||
111 | @diffs = diffs_or_a |
|
110 | def initialize(diffs_or_a, b = nil, isstring = nil) | |
112 | @isstring = isstring |
|
111 | if b.nil? | |
113 | else |
|
112 | @diffs = diffs_or_a | |
114 | @diffs = [] |
|
113 | @isstring = isstring | |
|
114 | else | |||
|
115 | @diffs = [] | |||
|
116 | @curdiffs = [] | |||
|
117 | makediff(diffs_or_a, b) | |||
|
118 | @difftype = diffs_or_a.class | |||
|
119 | end | |||
|
120 | end | |||
|
121 | ||||
|
122 | def match(ai, bi) | |||
|
123 | @diffs.push @curdiffs unless @curdiffs.empty? | |||
115 | @curdiffs = [] |
|
124 | @curdiffs = [] | |
116 | makediff(diffs_or_a, b) |
|
|||
117 | @difftype = diffs_or_a.class |
|
|||
118 | end |
|
125 | end | |
119 | end |
|
|||
120 |
|
||||
121 | def match(ai, bi) |
|
|||
122 | @diffs.push @curdiffs unless @curdiffs.empty? |
|
|||
123 | @curdiffs = [] |
|
|||
124 | end |
|
|||
125 |
|
126 | |||
126 | def discarda(i, elem) |
|
127 | def discarda(i, elem) | |
127 | @curdiffs.push ['-', i, elem] |
|
128 | @curdiffs.push ['-', i, elem] | |
128 | end |
|
129 | end | |
129 |
|
130 | |||
130 | def discardb(i, elem) |
|
131 | def discardb(i, elem) | |
131 | @curdiffs.push ['+', i, elem] |
|
132 | @curdiffs.push ['+', i, elem] | |
132 | end |
|
133 | end | |
133 |
|
134 | |||
134 | def compact |
|
135 | def compact | |
135 | return Diff.new(compactdiffs) |
|
136 | return Diff.new(compactdiffs) | |
136 | end |
|
137 | end | |
137 |
|
138 | |||
138 | def compact! |
|
139 | def compact! | |
139 | @diffs = compactdiffs |
|
140 | @diffs = compactdiffs | |
140 | end |
|
141 | end | |
141 |
|
142 | |||
142 | def inspect |
|
143 | def inspect | |
143 | @diffs.inspect |
|
144 | @diffs.inspect | |
144 | end |
|
145 | end | |
145 |
|
146 | |||
|
147 | end | |||
146 | end |
|
148 | end | |
147 |
|
149 | |||
148 | module Diffable |
|
150 | module Diffable | |
149 | def diff(b) |
|
151 | def diff(b) | |
150 | Diff.new(self, b) |
|
152 | RedmineDiff::Diff.new(self, b) | |
151 | end |
|
153 | end | |
152 |
|
154 | |||
153 | # Create a hash that maps elements of the array to arrays of indices |
|
155 | # Create a hash that maps elements of the array to arrays of indices | |
@@ -158,9 +160,9 module Diffable | |||||
158 | range.each { |i| |
|
160 | range.each { |i| | |
159 | elem = self[i] |
|
161 | elem = self[i] | |
160 | if revmap.has_key? elem |
|
162 | if revmap.has_key? elem | |
161 |
|
|
163 | revmap[elem].push i | |
162 | else |
|
164 | else | |
163 |
|
|
165 | revmap[elem] = [i] | |
164 | end |
|
166 | end | |
165 | } |
|
167 | } | |
166 | return revmap |
|
168 | return revmap | |
@@ -179,9 +181,9 module Diffable | |||||
179 | found = self[index] |
|
181 | found = self[index] | |
180 | return nil if value == found |
|
182 | return nil if value == found | |
181 | if value > found |
|
183 | if value > found | |
182 |
|
|
184 | low = index + 1 | |
183 | else |
|
185 | else | |
184 |
|
|
186 | high = index | |
185 | end |
|
187 | end | |
186 | end |
|
188 | end | |
187 |
|
189 | |||
@@ -204,25 +206,25 module Diffable | |||||
204 | bi = 0 |
|
206 | bi = 0 | |
205 | diff.diffs.each { |d| |
|
207 | diff.diffs.each { |d| | |
206 | d.each { |mod| |
|
208 | d.each { |mod| | |
207 |
|
|
209 | case mod[0] | |
208 |
|
|
210 | when '-' | |
209 |
|
|
211 | while ai < mod[1] | |
210 |
|
|
212 | newary << self[ai] | |
211 |
|
|
213 | ai += 1 | |
212 |
|
|
214 | bi += 1 | |
213 |
|
|
215 | end | |
214 |
|
|
216 | ai += 1 | |
215 |
|
|
217 | when '+' | |
216 |
|
|
218 | while bi < mod[1] | |
217 |
|
|
219 | newary << self[ai] | |
218 |
|
|
220 | ai += 1 | |
219 |
|
|
221 | bi += 1 | |
220 |
|
|
222 | end | |
221 |
|
|
223 | newary << mod[2] | |
222 |
|
|
224 | bi += 1 | |
223 |
|
|
225 | else | |
224 |
|
|
226 | raise "Unknown diff action" | |
225 |
|
|
227 | end | |
226 | } |
|
228 | } | |
227 | } |
|
229 | } | |
228 | while ai < self.length |
|
230 | while ai < self.length | |
@@ -243,38 +245,38 class String | |||||
243 | end |
|
245 | end | |
244 |
|
246 | |||
245 | =begin |
|
247 | =begin | |
246 | = Diff |
|
248 | = Diff | |
247 | (({diff.rb})) - computes the differences between two arrays or |
|
249 | (({diff.rb})) - computes the differences between two arrays or | |
248 | strings. Copyright (C) 2001 Lars Christensen |
|
250 | strings. Copyright (C) 2001 Lars Christensen | |
249 |
|
251 | |||
250 | == Synopsis |
|
252 | == Synopsis | |
251 |
|
253 | |||
252 | diff = Diff.new(a, b) |
|
254 | diff = Diff.new(a, b) | |
253 | b = a.patch(diff) |
|
255 | b = a.patch(diff) | |
254 |
|
256 | |||
255 | == Class Diff |
|
257 | == Class Diff | |
256 | === Class Methods |
|
258 | === Class Methods | |
257 | --- Diff.new(a, b) |
|
259 | --- Diff.new(a, b) | |
258 | --- a.diff(b) |
|
260 | --- a.diff(b) | |
259 | Creates a Diff object which represent the differences between |
|
261 | Creates a Diff object which represent the differences between | |
260 | ((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays |
|
262 | ((|a|)) and ((|b|)). ((|a|)) and ((|b|)) can be either be arrays | |
261 | of any objects, strings, or object of any class that include |
|
263 | of any objects, strings, or object of any class that include | |
262 | module ((|Diffable|)) |
|
264 | module ((|Diffable|)) | |
263 |
|
265 | |||
264 | == Module Diffable |
|
266 | == Module Diffable | |
265 | The module ((|Diffable|)) is intended to be included in any class for |
|
267 | The module ((|Diffable|)) is intended to be included in any class for | |
266 | which differences are to be computed. Diffable is included into String |
|
268 | which differences are to be computed. Diffable is included into String | |
267 | and Array when (({diff.rb})) is (({require}))'d. |
|
269 | and Array when (({diff.rb})) is (({require}))'d. | |
268 |
|
270 | |||
269 | Classes including Diffable should implement (({[]})) to get element at |
|
271 | Classes including Diffable should implement (({[]})) to get element at | |
270 | integer indices, (({<<})) to append elements to the object and |
|
272 | integer indices, (({<<})) to append elements to the object and | |
271 | (({ClassName#new})) should accept 0 arguments to create a new empty |
|
273 | (({ClassName#new})) should accept 0 arguments to create a new empty | |
272 | object. |
|
274 | object. | |
273 |
|
275 | |||
274 | === Instance Methods |
|
276 | === Instance Methods | |
275 | --- Diffable#patch(diff) |
|
277 | --- Diffable#patch(diff) | |
276 | Applies the differences from ((|diff|)) to the object ((|obj|)) |
|
278 | Applies the differences from ((|diff|)) to the object ((|obj|)) | |
277 | and return the result. ((|obj|)) is not changed. ((|obj|)) and |
|
279 | and return the result. ((|obj|)) is not changed. ((|obj|)) and | |
278 | can be either an array or a string, but must match the object |
|
280 | can be either an array or a string, but must match the object | |
279 | from which the ((|diff|)) was created. |
|
281 | from which the ((|diff|)) was created. | |
280 | =end |
|
282 | =end |
@@ -100,6 +100,18 module Redmine | |||||
100 | def entries(path=nil, identifier=nil) |
|
100 | def entries(path=nil, identifier=nil) | |
101 | return nil |
|
101 | return nil | |
102 | end |
|
102 | end | |
|
103 | ||||
|
104 | def branches | |||
|
105 | return nil | |||
|
106 | end | |||
|
107 | ||||
|
108 | def tags | |||
|
109 | return nil | |||
|
110 | end | |||
|
111 | ||||
|
112 | def default_branch | |||
|
113 | return nil | |||
|
114 | end | |||
103 |
|
115 | |||
104 | def properties(path, identifier=nil) |
|
116 | def properties(path, identifier=nil) | |
105 | return nil |
|
117 | return nil | |
@@ -260,6 +272,7 module Redmine | |||||
260 |
|
272 | |||
261 | class Revision |
|
273 | class Revision | |
262 | attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch |
|
274 | attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch | |
|
275 | ||||
263 | def initialize(attributes={}) |
|
276 | def initialize(attributes={}) | |
264 | self.identifier = attributes[:identifier] |
|
277 | self.identifier = attributes[:identifier] | |
265 | self.scmid = attributes[:scmid] |
|
278 | self.scmid = attributes[:scmid] | |
@@ -271,7 +284,25 module Redmine | |||||
271 | self.revision = attributes[:revision] |
|
284 | self.revision = attributes[:revision] | |
272 | self.branch = attributes[:branch] |
|
285 | self.branch = attributes[:branch] | |
273 | end |
|
286 | end | |
274 |
|
287 | |||
|
288 | def save(repo) | |||
|
289 | if repo.changesets.find_by_scmid(scmid.to_s).nil? | |||
|
290 | changeset = Changeset.create!( | |||
|
291 | :repository => repo, | |||
|
292 | :revision => identifier, | |||
|
293 | :scmid => scmid, | |||
|
294 | :committer => author, | |||
|
295 | :committed_on => time, | |||
|
296 | :comments => message) | |||
|
297 | ||||
|
298 | paths.each do |file| | |||
|
299 | Change.create!( | |||
|
300 | :changeset => changeset, | |||
|
301 | :action => file[:action], | |||
|
302 | :path => file[:path]) | |||
|
303 | end | |||
|
304 | end | |||
|
305 | end | |||
275 | end |
|
306 | end | |
276 |
|
307 | |||
277 | class Annotate |
|
308 | class Annotate |
@@ -21,90 +21,38 module Redmine | |||||
21 | module Scm |
|
21 | module Scm | |
22 | module Adapters |
|
22 | module Adapters | |
23 | class GitAdapter < AbstractAdapter |
|
23 | class GitAdapter < AbstractAdapter | |
24 |
|
||||
25 | # Git executable name |
|
24 | # Git executable name | |
26 | GIT_BIN = "git" |
|
25 | GIT_BIN = "git" | |
27 |
|
26 | |||
28 | # Get the revision of a particuliar file |
|
27 | def info | |
29 | def get_rev (rev,path) |
|
28 | begin | |
30 |
|
29 | Info.new(:root_url => url, :lastrev => lastrev('',nil)) | ||
31 | if rev != 'latest' && !rev.nil? |
|
30 | rescue | |
32 | cmd="#{GIT_BIN} --git-dir #{target('')} show --date=iso --pretty=fuller #{shell_quote rev} -- #{shell_quote path}" |
|
31 | nil | |
33 | else |
|
|||
34 | @branch ||= shellout("#{GIT_BIN} --git-dir #{target('')} branch") { |io| io.grep(/\*/)[0].strip.match(/\* (.*)/)[1] } |
|
|||
35 | cmd="#{GIT_BIN} --git-dir #{target('')} log --date=iso --pretty=fuller -1 #{@branch} -- #{shell_quote path}" |
|
|||
36 | end |
|
32 | end | |
37 |
|
|
33 | end | |
38 | i=0 |
|
|||
39 | shellout(cmd) do |io| |
|
|||
40 | files=[] |
|
|||
41 | changeset = {} |
|
|||
42 | parsing_descr = 0 #0: not parsing desc or files, 1: parsing desc, 2: parsing files |
|
|||
43 |
|
34 | |||
|
35 | def branches | |||
|
36 | branches = [] | |||
|
37 | cmd = "#{GIT_BIN} --git-dir #{target('')} branch" | |||
|
38 | shellout(cmd) do |io| | |||
44 | io.each_line do |line| |
|
39 | io.each_line do |line| | |
45 | if line =~ /^commit ([0-9a-f]{40})$/ |
|
40 | branches << line.match('\s*\*?\s*(.*)$')[1] | |
46 | key = "commit" |
|
41 | end | |
47 | value = $1 |
|
|||
48 | if (parsing_descr == 1 || parsing_descr == 2) |
|
|||
49 | parsing_descr = 0 |
|
|||
50 | rev = Revision.new({:identifier => changeset[:commit], |
|
|||
51 | :scmid => changeset[:commit], |
|
|||
52 | :author => changeset[:author], |
|
|||
53 | :time => Time.parse(changeset[:date]), |
|
|||
54 | :message => changeset[:description], |
|
|||
55 | :paths => files |
|
|||
56 | }) |
|
|||
57 | changeset = {} |
|
|||
58 | files = [] |
|
|||
59 | end |
|
|||
60 | changeset[:commit] = $1 |
|
|||
61 | elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/ |
|
|||
62 | key = $1 |
|
|||
63 | value = $2 |
|
|||
64 | if key == "Author" |
|
|||
65 | changeset[:author] = value |
|
|||
66 | elsif key == "CommitDate" |
|
|||
67 | changeset[:date] = value |
|
|||
68 | end |
|
|||
69 | elsif (parsing_descr == 0) && line.chomp.to_s == "" |
|
|||
70 | parsing_descr = 1 |
|
|||
71 | changeset[:description] = "" |
|
|||
72 | elsif (parsing_descr == 1 || parsing_descr == 2) && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/ |
|
|||
73 | parsing_descr = 2 |
|
|||
74 | fileaction = $1 |
|
|||
75 | filepath = $2 |
|
|||
76 | files << {:action => fileaction, :path => filepath} |
|
|||
77 | elsif (parsing_descr == 1) && line.chomp.to_s == "" |
|
|||
78 | parsing_descr = 2 |
|
|||
79 | elsif (parsing_descr == 1) |
|
|||
80 | changeset[:description] << line |
|
|||
81 | end |
|
|||
82 | end |
|
|||
83 | rev = Revision.new({:identifier => changeset[:commit], |
|
|||
84 | :scmid => changeset[:commit], |
|
|||
85 | :author => changeset[:author], |
|
|||
86 | :time => (changeset[:date] ? Time.parse(changeset[:date]) : nil), |
|
|||
87 | :message => changeset[:description], |
|
|||
88 | :paths => files |
|
|||
89 | }) |
|
|||
90 |
|
||||
91 | end |
|
42 | end | |
92 |
|
43 | branches.sort! | ||
93 | get_rev('latest',path) if rev == [] |
|
|||
94 |
|
||||
95 | return nil if $? && $?.exitstatus != 0 |
|
|||
96 | return rev |
|
|||
97 | end |
|
44 | end | |
98 |
|
45 | |||
99 |
def |
|
46 | def tags | |
100 | revs = revisions(url,nil,nil,{:limit => 1}) |
|
47 | tags = [] | |
101 | if revs && revs.any? |
|
48 | cmd = "#{GIT_BIN} --git-dir #{target('')} tag" | |
102 | Info.new(:root_url => url, :lastrev => revs.first) |
|
49 | shellout(cmd) do |io| | |
103 | else |
|
50 | io.readlines.sort!.map{|t| t.strip} | |
104 | nil |
|
|||
105 | end |
|
51 | end | |
106 | rescue Errno::ENOENT => e |
|
52 | end | |
107 | return nil |
|
53 | ||
|
54 | def default_branch | |||
|
55 | branches.include?('master') ? 'master' : branches.first | |||
108 | end |
|
56 | end | |
109 |
|
57 | |||
110 | def entries(path=nil, identifier=nil) |
|
58 | def entries(path=nil, identifier=nil) | |
@@ -121,27 +69,63 module Redmine | |||||
121 | sha = $2 |
|
69 | sha = $2 | |
122 | size = $3 |
|
70 | size = $3 | |
123 | name = $4 |
|
71 | name = $4 | |
|
72 | full_path = path.empty? ? name : "#{path}/#{name}" | |||
124 | entries << Entry.new({:name => name, |
|
73 | entries << Entry.new({:name => name, | |
125 | :path => (path.empty? ? name : "#{path}/#{name}"), |
|
74 | :path => full_path, | |
126 |
|
|
75 | :kind => (type == "tree") ? 'dir' : 'file', | |
127 |
|
|
76 | :size => (type == "tree") ? nil : size, | |
128 | :lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}")) |
|
77 | :lastrev => lastrev(full_path,identifier) | |
129 |
|
78 | }) unless entries.detect{|entry| entry.name == name} | ||
130 | }) unless entries.detect{|entry| entry.name == name} |
|
|||
131 | end |
|
79 | end | |
132 | end |
|
80 | end | |
133 | end |
|
81 | end | |
134 | return nil if $? && $?.exitstatus != 0 |
|
82 | return nil if $? && $?.exitstatus != 0 | |
135 | entries.sort_by_name |
|
83 | entries.sort_by_name | |
136 | end |
|
84 | end | |
137 |
|
85 | |||
|
86 | def lastrev(path,rev) | |||
|
87 | return nil if path.nil? | |||
|
88 | cmd = "#{GIT_BIN} --git-dir #{target('')} log --pretty=fuller --no-merges -n 1 " | |||
|
89 | cmd << " #{shell_quote rev} " if rev | |||
|
90 | cmd << "-- #{path} " unless path.empty? | |||
|
91 | shellout(cmd) do |io| | |||
|
92 | begin | |||
|
93 | id = io.gets.split[1] | |||
|
94 | author = io.gets.match('Author:\s+(.*)$')[1] | |||
|
95 | 2.times { io.gets } | |||
|
96 | time = io.gets.match('CommitDate:\s+(.*)$')[1] | |||
|
97 | ||||
|
98 | Revision.new({ | |||
|
99 | :identifier => id, | |||
|
100 | :scmid => id, | |||
|
101 | :author => author, | |||
|
102 | :time => time, | |||
|
103 | :message => nil, | |||
|
104 | :paths => nil | |||
|
105 | }) | |||
|
106 | rescue NoMethodError => e | |||
|
107 | logger.error("The revision '#{path}' has a wrong format") | |||
|
108 | return nil | |||
|
109 | end | |||
|
110 | end | |||
|
111 | end | |||
|
112 | ||||
|
113 | def num_revisions | |||
|
114 | cmd = "#{GIT_BIN} --git-dir #{target('')} log --all --pretty=format:'' | wc -l" | |||
|
115 | shellout(cmd) {|io| io.gets.chomp.to_i + 1} | |||
|
116 | end | |||
|
117 | ||||
138 | def revisions(path, identifier_from, identifier_to, options={}) |
|
118 | def revisions(path, identifier_from, identifier_to, options={}) | |
139 | revisions = Revisions.new |
|
119 | revisions = Revisions.new | |
140 | cmd = "#{GIT_BIN} --git-dir #{target('')} log --raw --date=iso --pretty=fuller" |
|
120 | ||
|
121 | cmd = "#{GIT_BIN} --git-dir #{target('')} log --find-copies-harder --raw --date=iso --pretty=fuller" | |||
141 | cmd << " --reverse" if options[:reverse] |
|
122 | cmd << " --reverse" if options[:reverse] | |
142 | cmd << " -n #{options[:limit].to_i} " if (!options.nil?) && options[:limit] |
|
123 | cmd << " --all" if options[:all] | |
|
124 | cmd << " -n #{options[:limit]} " if options[:limit] | |||
143 | cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from |
|
125 | cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from | |
144 | cmd << " #{shell_quote identifier_to} " if identifier_to |
|
126 | cmd << " #{shell_quote identifier_to} " if identifier_to | |
|
127 | cmd << " -- #{path}" if path && !path.empty? | |||
|
128 | ||||
145 | shellout(cmd) do |io| |
|
129 | shellout(cmd) do |io| | |
146 | files=[] |
|
130 | files=[] | |
147 | changeset = {} |
|
131 | changeset = {} | |
@@ -154,13 +138,14 module Redmine | |||||
154 | value = $1 |
|
138 | value = $1 | |
155 | if (parsing_descr == 1 || parsing_descr == 2) |
|
139 | if (parsing_descr == 1 || parsing_descr == 2) | |
156 | parsing_descr = 0 |
|
140 | parsing_descr = 0 | |
157 |
revision = Revision.new({ |
|
141 | revision = Revision.new({ | |
158 |
|
|
142 | :identifier => changeset[:commit], | |
159 |
|
|
143 | :scmid => changeset[:commit], | |
160 |
|
|
144 | :author => changeset[:author], | |
161 |
|
|
145 | :time => Time.parse(changeset[:date]), | |
162 | :paths => files |
|
146 | :message => changeset[:description], | |
163 | }) |
|
147 | :paths => files | |
|
148 | }) | |||
164 | if block_given? |
|
149 | if block_given? | |
165 | yield revision |
|
150 | yield revision | |
166 | else |
|
151 | else | |
@@ -182,26 +167,35 module Redmine | |||||
182 | elsif (parsing_descr == 0) && line.chomp.to_s == "" |
|
167 | elsif (parsing_descr == 0) && line.chomp.to_s == "" | |
183 | parsing_descr = 1 |
|
168 | parsing_descr = 1 | |
184 | changeset[:description] = "" |
|
169 | changeset[:description] = "" | |
185 |
elsif (parsing_descr == 1 || parsing_descr == 2) |
|
170 | elsif (parsing_descr == 1 || parsing_descr == 2) \ | |
|
171 | && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/ | |||
186 | parsing_descr = 2 |
|
172 | parsing_descr = 2 | |
187 | fileaction = $1 |
|
173 | fileaction = $1 | |
188 | filepath = $2 |
|
174 | filepath = $2 | |
189 | files << {:action => fileaction, :path => filepath} |
|
175 | files << {:action => fileaction, :path => filepath} | |
|
176 | elsif (parsing_descr == 1 || parsing_descr == 2) \ | |||
|
177 | && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\d+\s+(\S+)\s+(.+)$/ | |||
|
178 | parsing_descr = 2 | |||
|
179 | fileaction = $1 | |||
|
180 | filepath = $3 | |||
|
181 | files << {:action => fileaction, :path => filepath} | |||
190 | elsif (parsing_descr == 1) && line.chomp.to_s == "" |
|
182 | elsif (parsing_descr == 1) && line.chomp.to_s == "" | |
191 | parsing_descr = 2 |
|
183 | parsing_descr = 2 | |
192 | elsif (parsing_descr == 1) |
|
184 | elsif (parsing_descr == 1) | |
193 | changeset[:description] << line[4..-1] |
|
185 | changeset[:description] << line[4..-1] | |
194 | end |
|
186 | end | |
195 |
end |
|
187 | end | |
196 |
|
188 | |||
197 | if changeset[:commit] |
|
189 | if changeset[:commit] | |
198 |
revision = Revision.new({ |
|
190 | revision = Revision.new({ | |
199 |
|
|
191 | :identifier => changeset[:commit], | |
200 |
|
|
192 | :scmid => changeset[:commit], | |
201 |
|
|
193 | :author => changeset[:author], | |
202 | :message => changeset[:description], |
|
194 | :time => Time.parse(changeset[:date]), | |
203 | :paths => files |
|
195 | :message => changeset[:description], | |
204 | }) |
|
196 | :paths => files | |
|
197 | }) | |||
|
198 | ||||
205 | if block_given? |
|
199 | if block_given? | |
206 | yield revision |
|
200 | yield revision | |
207 | else |
|
201 | else | |
@@ -213,15 +207,16 module Redmine | |||||
213 | return nil if $? && $?.exitstatus != 0 |
|
207 | return nil if $? && $?.exitstatus != 0 | |
214 | revisions |
|
208 | revisions | |
215 | end |
|
209 | end | |
216 |
|
210 | |||
217 | def diff(path, identifier_from, identifier_to=nil) |
|
211 | def diff(path, identifier_from, identifier_to=nil) | |
218 | path ||= '' |
|
212 | path ||= '' | |
219 | if !identifier_to |
|
213 | ||
220 |
|
|
214 | if identifier_to | |
|
215 | cmd = "#{GIT_BIN} --git-dir #{target('')} diff #{shell_quote identifier_to} #{shell_quote identifier_from}" | |||
|
216 | else | |||
|
217 | cmd = "#{GIT_BIN} --git-dir #{target('')} show #{shell_quote identifier_from}" | |||
221 | end |
|
218 | end | |
222 |
|
219 | |||
223 | cmd = "#{GIT_BIN} --git-dir #{target('')} show #{shell_quote identifier_from}" if identifier_to.nil? |
|
|||
224 | cmd = "#{GIT_BIN} --git-dir #{target('')} diff #{shell_quote identifier_to} #{shell_quote identifier_from}" if !identifier_to.nil? |
|
|||
225 | cmd << " -- #{shell_quote path}" unless path.empty? |
|
220 | cmd << " -- #{shell_quote path}" unless path.empty? | |
226 | diff = [] |
|
221 | diff = [] | |
227 | shellout(cmd) do |io| |
|
222 | shellout(cmd) do |io| | |
@@ -265,6 +260,4 module Redmine | |||||
265 | end |
|
260 | end | |
266 | end |
|
261 | end | |
267 | end |
|
262 | end | |
268 |
|
||||
269 | end |
|
263 | end | |
270 |
|
@@ -181,7 +181,7 div.square { | |||||
181 | width: .6em; height: .6em; |
|
181 | width: .6em; height: .6em; | |
182 | } |
|
182 | } | |
183 | .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;} |
|
183 | .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;} | |
184 | .contextual input {font-size:0.9em;} |
|
184 | .contextual input,select {font-size:0.9em;} | |
185 | .message .contextual { margin-top: 0; } |
|
185 | .message .contextual { margin-top: 0; } | |
186 |
|
186 | |||
187 | .splitcontentleft{float:left; width:49%;} |
|
187 | .splitcontentleft{float:left; width:49%;} |
1 | NO CONTENT: modified file, binary diff hidden |
|
NO CONTENT: modified file, binary diff hidden |
@@ -45,9 +45,9 class RepositoriesBazaarControllerTest < Test::Unit::TestCase | |||||
45 | end |
|
45 | end | |
46 |
|
46 | |||
47 | def test_browse_root |
|
47 | def test_browse_root | |
48 |
get : |
|
48 | get :show, :id => 3 | |
49 | assert_response :success |
|
49 | assert_response :success | |
50 |
assert_template ' |
|
50 | assert_template 'show' | |
51 | assert_not_nil assigns(:entries) |
|
51 | assert_not_nil assigns(:entries) | |
52 | assert_equal 2, assigns(:entries).size |
|
52 | assert_equal 2, assigns(:entries).size | |
53 | assert assigns(:entries).detect {|e| e.name == 'directory' && e.kind == 'dir'} |
|
53 | assert assigns(:entries).detect {|e| e.name == 'directory' && e.kind == 'dir'} | |
@@ -55,9 +55,9 class RepositoriesBazaarControllerTest < Test::Unit::TestCase | |||||
55 | end |
|
55 | end | |
56 |
|
56 | |||
57 | def test_browse_directory |
|
57 | def test_browse_directory | |
58 |
get : |
|
58 | get :show, :id => 3, :path => ['directory'] | |
59 | assert_response :success |
|
59 | assert_response :success | |
60 |
assert_template ' |
|
60 | assert_template 'show' | |
61 | assert_not_nil assigns(:entries) |
|
61 | assert_not_nil assigns(:entries) | |
62 | assert_equal ['doc-ls.txt', 'document.txt', 'edit.png'], assigns(:entries).collect(&:name) |
|
62 | assert_equal ['doc-ls.txt', 'document.txt', 'edit.png'], assigns(:entries).collect(&:name) | |
63 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} |
|
63 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} | |
@@ -67,9 +67,9 class RepositoriesBazaarControllerTest < Test::Unit::TestCase | |||||
67 | end |
|
67 | end | |
68 |
|
68 | |||
69 | def test_browse_at_given_revision |
|
69 | def test_browse_at_given_revision | |
70 |
get : |
|
70 | get :show, :id => 3, :path => [], :rev => 3 | |
71 | assert_response :success |
|
71 | assert_response :success | |
72 |
assert_template ' |
|
72 | assert_template 'show' | |
73 | assert_not_nil assigns(:entries) |
|
73 | assert_not_nil assigns(:entries) | |
74 | assert_equal ['directory', 'doc-deleted.txt', 'doc-ls.txt', 'doc-mkdir.txt'], assigns(:entries).collect(&:name) |
|
74 | assert_equal ['directory', 'doc-deleted.txt', 'doc-ls.txt', 'doc-mkdir.txt'], assigns(:entries).collect(&:name) | |
75 | end |
|
75 | end | |
@@ -102,7 +102,7 class RepositoriesBazaarControllerTest < Test::Unit::TestCase | |||||
102 | def test_directory_entry |
|
102 | def test_directory_entry | |
103 | get :entry, :id => 3, :path => ['directory'] |
|
103 | get :entry, :id => 3, :path => ['directory'] | |
104 | assert_response :success |
|
104 | assert_response :success | |
105 |
assert_template ' |
|
105 | assert_template 'show' | |
106 | assert_not_nil assigns(:entry) |
|
106 | assert_not_nil assigns(:entry) | |
107 | assert_equal 'directory', assigns(:entry).name |
|
107 | assert_equal 'directory', assigns(:entry).name | |
108 | end |
|
108 | end |
@@ -51,9 +51,9 class RepositoriesCvsControllerTest < Test::Unit::TestCase | |||||
51 | end |
|
51 | end | |
52 |
|
52 | |||
53 | def test_browse_root |
|
53 | def test_browse_root | |
54 |
get : |
|
54 | get :show, :id => 1 | |
55 | assert_response :success |
|
55 | assert_response :success | |
56 |
assert_template ' |
|
56 | assert_template 'show' | |
57 | assert_not_nil assigns(:entries) |
|
57 | assert_not_nil assigns(:entries) | |
58 | assert_equal 3, assigns(:entries).size |
|
58 | assert_equal 3, assigns(:entries).size | |
59 |
|
59 | |||
@@ -65,9 +65,9 class RepositoriesCvsControllerTest < Test::Unit::TestCase | |||||
65 | end |
|
65 | end | |
66 |
|
66 | |||
67 | def test_browse_directory |
|
67 | def test_browse_directory | |
68 |
get : |
|
68 | get :show, :id => 1, :path => ['images'] | |
69 | assert_response :success |
|
69 | assert_response :success | |
70 |
assert_template ' |
|
70 | assert_template 'show' | |
71 | assert_not_nil assigns(:entries) |
|
71 | assert_not_nil assigns(:entries) | |
72 | assert_equal ['add.png', 'delete.png', 'edit.png'], assigns(:entries).collect(&:name) |
|
72 | assert_equal ['add.png', 'delete.png', 'edit.png'], assigns(:entries).collect(&:name) | |
73 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} |
|
73 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} | |
@@ -78,9 +78,9 class RepositoriesCvsControllerTest < Test::Unit::TestCase | |||||
78 |
|
78 | |||
79 | def test_browse_at_given_revision |
|
79 | def test_browse_at_given_revision | |
80 | Project.find(1).repository.fetch_changesets |
|
80 | Project.find(1).repository.fetch_changesets | |
81 |
get : |
|
81 | get :show, :id => 1, :path => ['images'], :rev => 1 | |
82 | assert_response :success |
|
82 | assert_response :success | |
83 |
assert_template ' |
|
83 | assert_template 'show' | |
84 | assert_not_nil assigns(:entries) |
|
84 | assert_not_nil assigns(:entries) | |
85 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) |
|
85 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) | |
86 | end |
|
86 | end | |
@@ -118,7 +118,7 class RepositoriesCvsControllerTest < Test::Unit::TestCase | |||||
118 | def test_directory_entry |
|
118 | def test_directory_entry | |
119 | get :entry, :id => 1, :path => ['sources'] |
|
119 | get :entry, :id => 1, :path => ['sources'] | |
120 | assert_response :success |
|
120 | assert_response :success | |
121 |
assert_template ' |
|
121 | assert_template 'show' | |
122 | assert_not_nil assigns(:entry) |
|
122 | assert_not_nil assigns(:entry) | |
123 | assert_equal 'sources', assigns(:entry).name |
|
123 | assert_equal 'sources', assigns(:entry).name | |
124 | end |
|
124 | end |
@@ -45,9 +45,9 class RepositoriesDarcsControllerTest < Test::Unit::TestCase | |||||
45 | end |
|
45 | end | |
46 |
|
46 | |||
47 | def test_browse_root |
|
47 | def test_browse_root | |
48 |
get : |
|
48 | get :show, :id => 3 | |
49 | assert_response :success |
|
49 | assert_response :success | |
50 |
assert_template ' |
|
50 | assert_template 'show' | |
51 | assert_not_nil assigns(:entries) |
|
51 | assert_not_nil assigns(:entries) | |
52 | assert_equal 3, assigns(:entries).size |
|
52 | assert_equal 3, assigns(:entries).size | |
53 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} |
|
53 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} | |
@@ -56,9 +56,9 class RepositoriesDarcsControllerTest < Test::Unit::TestCase | |||||
56 | end |
|
56 | end | |
57 |
|
57 | |||
58 | def test_browse_directory |
|
58 | def test_browse_directory | |
59 |
get : |
|
59 | get :show, :id => 3, :path => ['images'] | |
60 | assert_response :success |
|
60 | assert_response :success | |
61 |
assert_template ' |
|
61 | assert_template 'show' | |
62 | assert_not_nil assigns(:entries) |
|
62 | assert_not_nil assigns(:entries) | |
63 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) |
|
63 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) | |
64 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} |
|
64 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} | |
@@ -69,9 +69,9 class RepositoriesDarcsControllerTest < Test::Unit::TestCase | |||||
69 |
|
69 | |||
70 | def test_browse_at_given_revision |
|
70 | def test_browse_at_given_revision | |
71 | Project.find(3).repository.fetch_changesets |
|
71 | Project.find(3).repository.fetch_changesets | |
72 |
get : |
|
72 | get :show, :id => 3, :path => ['images'], :rev => 1 | |
73 | assert_response :success |
|
73 | assert_response :success | |
74 |
assert_template ' |
|
74 | assert_template 'show' | |
75 | assert_not_nil assigns(:entries) |
|
75 | assert_not_nil assigns(:entries) | |
76 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) |
|
76 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) | |
77 | end |
|
77 | end |
@@ -46,22 +46,37 class RepositoriesGitControllerTest < Test::Unit::TestCase | |||||
46 | end |
|
46 | end | |
47 |
|
47 | |||
48 | def test_browse_root |
|
48 | def test_browse_root | |
49 |
get : |
|
49 | get :show, :id => 3 | |
50 | assert_response :success |
|
50 | assert_response :success | |
51 |
assert_template ' |
|
51 | assert_template 'show' | |
52 | assert_not_nil assigns(:entries) |
|
52 | assert_not_nil assigns(:entries) | |
53 |
assert_equal |
|
53 | assert_equal 6, assigns(:entries).size | |
54 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} |
|
54 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} | |
55 | assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'} |
|
55 | assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'} | |
56 | assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'} |
|
56 | assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'} | |
|
57 | assert assigns(:entries).detect {|e| e.name == 'copied_README' && e.kind == 'file'} | |||
|
58 | assert assigns(:entries).detect {|e| e.name == 'new_file.txt' && e.kind == 'file'} | |||
|
59 | assert assigns(:entries).detect {|e| e.name == 'renamed_test.txt' && e.kind == 'file'} | |||
57 | end |
|
60 | end | |
58 |
|
61 | |||
|
62 | def test_browse_branch | |||
|
63 | get :show, :id => 3, :rev => 'test_branch' | |||
|
64 | assert_response :success | |||
|
65 | assert_template 'show' | |||
|
66 | assert_not_nil assigns(:entries) | |||
|
67 | assert_equal 4, assigns(:entries).size | |||
|
68 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} | |||
|
69 | assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'} | |||
|
70 | assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'} | |||
|
71 | assert assigns(:entries).detect {|e| e.name == 'test.txt' && e.kind == 'file'} | |||
|
72 | end | |||
|
73 | ||||
59 | def test_browse_directory |
|
74 | def test_browse_directory | |
60 |
get : |
|
75 | get :show, :id => 3, :path => ['images'] | |
61 | assert_response :success |
|
76 | assert_response :success | |
62 |
assert_template ' |
|
77 | assert_template 'show' | |
63 | assert_not_nil assigns(:entries) |
|
78 | assert_not_nil assigns(:entries) | |
64 |
assert_equal [ |
|
79 | assert_equal ['edit.png'], assigns(:entries).collect(&:name) | |
65 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} |
|
80 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} | |
66 | assert_not_nil entry |
|
81 | assert_not_nil entry | |
67 | assert_equal 'file', entry.kind |
|
82 | assert_equal 'file', entry.kind | |
@@ -69,9 +84,9 class RepositoriesGitControllerTest < Test::Unit::TestCase | |||||
69 | end |
|
84 | end | |
70 |
|
85 | |||
71 | def test_browse_at_given_revision |
|
86 | def test_browse_at_given_revision | |
72 |
get : |
|
87 | get :show, :id => 3, :path => ['images'], :rev => '7234cb2750b63f47bff735edc50a1c0a433c2518' | |
73 | assert_response :success |
|
88 | assert_response :success | |
74 |
assert_template ' |
|
89 | assert_template 'show' | |
75 | assert_not_nil assigns(:entries) |
|
90 | assert_not_nil assigns(:entries) | |
76 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) |
|
91 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) | |
77 | end |
|
92 | end | |
@@ -89,7 +104,7 class RepositoriesGitControllerTest < Test::Unit::TestCase | |||||
89 | assert_template 'entry' |
|
104 | assert_template 'entry' | |
90 | # Line 19 |
|
105 | # Line 19 | |
91 | assert_tag :tag => 'th', |
|
106 | assert_tag :tag => 'th', | |
92 |
:content => /1 |
|
107 | :content => /11/, | |
93 | :attributes => { :class => /line-num/ }, |
|
108 | :attributes => { :class => /line-num/ }, | |
94 | :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ } |
|
109 | :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ } | |
95 | end |
|
110 | end | |
@@ -104,7 +119,7 class RepositoriesGitControllerTest < Test::Unit::TestCase | |||||
104 | def test_directory_entry |
|
119 | def test_directory_entry | |
105 | get :entry, :id => 3, :path => ['sources'] |
|
120 | get :entry, :id => 3, :path => ['sources'] | |
106 | assert_response :success |
|
121 | assert_response :success | |
107 |
assert_template ' |
|
122 | assert_template 'show' | |
108 | assert_not_nil assigns(:entry) |
|
123 | assert_not_nil assigns(:entry) | |
109 | assert_equal 'sources', assigns(:entry).name |
|
124 | assert_equal 'sources', assigns(:entry).name | |
110 | end |
|
125 | end | |
@@ -127,14 +142,14 class RepositoriesGitControllerTest < Test::Unit::TestCase | |||||
127 | assert_response :success |
|
142 | assert_response :success | |
128 | assert_template 'annotate' |
|
143 | assert_template 'annotate' | |
129 | # Line 23, changeset 2f9c0091 |
|
144 | # Line 23, changeset 2f9c0091 | |
130 |
assert_tag :tag => 'th', :content => /2 |
|
145 | assert_tag :tag => 'th', :content => /24/, | |
131 | :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /2f9c0091/ } }, |
|
146 | :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /2f9c0091/ } }, | |
132 | :sibling => { :tag => 'td', :content => /jsmith/ }, |
|
147 | :sibling => { :tag => 'td', :content => /jsmith/ }, | |
133 | :sibling => { :tag => 'td', :content => /watcher =/ } |
|
148 | :sibling => { :tag => 'td', :content => /watcher =/ } | |
134 | end |
|
149 | end | |
135 |
|
150 | |||
136 | def test_annotate_binary_file |
|
151 | def test_annotate_binary_file | |
137 |
get :annotate, :id => 3, :path => ['images', ' |
|
152 | get :annotate, :id => 3, :path => ['images', 'edit.png'] | |
138 | assert_response 500 |
|
153 | assert_response 500 | |
139 | assert_tag :tag => 'div', :attributes => { :class => /error/ }, |
|
154 | assert_tag :tag => 'div', :attributes => { :class => /error/ }, | |
140 | :content => /can not be annotated/ |
|
155 | :content => /can not be annotated/ |
@@ -44,10 +44,10 class RepositoriesMercurialControllerTest < Test::Unit::TestCase | |||||
44 | assert_not_nil assigns(:changesets) |
|
44 | assert_not_nil assigns(:changesets) | |
45 | end |
|
45 | end | |
46 |
|
46 | |||
47 |
def test_ |
|
47 | def test_show_root | |
48 |
get : |
|
48 | get :show, :id => 3 | |
49 | assert_response :success |
|
49 | assert_response :success | |
50 |
assert_template ' |
|
50 | assert_template 'show' | |
51 | assert_not_nil assigns(:entries) |
|
51 | assert_not_nil assigns(:entries) | |
52 | assert_equal 3, assigns(:entries).size |
|
52 | assert_equal 3, assigns(:entries).size | |
53 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} |
|
53 | assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'} | |
@@ -55,10 +55,10 class RepositoriesMercurialControllerTest < Test::Unit::TestCase | |||||
55 | assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'} |
|
55 | assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'} | |
56 | end |
|
56 | end | |
57 |
|
57 | |||
58 |
def test_ |
|
58 | def test_show_directory | |
59 |
get : |
|
59 | get :show, :id => 3, :path => ['images'] | |
60 | assert_response :success |
|
60 | assert_response :success | |
61 |
assert_template ' |
|
61 | assert_template 'show' | |
62 | assert_not_nil assigns(:entries) |
|
62 | assert_not_nil assigns(:entries) | |
63 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) |
|
63 | assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name) | |
64 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} |
|
64 | entry = assigns(:entries).detect {|e| e.name == 'edit.png'} | |
@@ -67,10 +67,10 class RepositoriesMercurialControllerTest < Test::Unit::TestCase | |||||
67 | assert_equal 'images/edit.png', entry.path |
|
67 | assert_equal 'images/edit.png', entry.path | |
68 | end |
|
68 | end | |
69 |
|
69 | |||
70 |
def test_ |
|
70 | def test_show_at_given_revision | |
71 |
get : |
|
71 | get :show, :id => 3, :path => ['images'], :rev => 0 | |
72 | assert_response :success |
|
72 | assert_response :success | |
73 |
assert_template ' |
|
73 | assert_template 'show' | |
74 | assert_not_nil assigns(:entries) |
|
74 | assert_not_nil assigns(:entries) | |
75 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) |
|
75 | assert_equal ['delete.png'], assigns(:entries).collect(&:name) | |
76 | end |
|
76 | end | |
@@ -103,7 +103,7 class RepositoriesMercurialControllerTest < Test::Unit::TestCase | |||||
103 | def test_directory_entry |
|
103 | def test_directory_entry | |
104 | get :entry, :id => 3, :path => ['sources'] |
|
104 | get :entry, :id => 3, :path => ['sources'] | |
105 | assert_response :success |
|
105 | assert_response :success | |
106 |
assert_template ' |
|
106 | assert_template 'show' | |
107 | assert_not_nil assigns(:entry) |
|
107 | assert_not_nil assigns(:entry) | |
108 | assert_equal 'sources', assigns(:entry).name |
|
108 | assert_equal 'sources', assigns(:entry).name | |
109 | end |
|
109 | end |
@@ -47,18 +47,18 class RepositoriesSubversionControllerTest < Test::Unit::TestCase | |||||
47 | end |
|
47 | end | |
48 |
|
48 | |||
49 | def test_browse_root |
|
49 | def test_browse_root | |
50 |
get : |
|
50 | get :show, :id => 1 | |
51 | assert_response :success |
|
51 | assert_response :success | |
52 |
assert_template ' |
|
52 | assert_template 'show' | |
53 | assert_not_nil assigns(:entries) |
|
53 | assert_not_nil assigns(:entries) | |
54 | entry = assigns(:entries).detect {|e| e.name == 'subversion_test'} |
|
54 | entry = assigns(:entries).detect {|e| e.name == 'subversion_test'} | |
55 | assert_equal 'dir', entry.kind |
|
55 | assert_equal 'dir', entry.kind | |
56 | end |
|
56 | end | |
57 |
|
57 | |||
58 | def test_browse_directory |
|
58 | def test_browse_directory | |
59 |
get : |
|
59 | get :show, :id => 1, :path => ['subversion_test'] | |
60 | assert_response :success |
|
60 | assert_response :success | |
61 |
assert_template ' |
|
61 | assert_template 'show' | |
62 | assert_not_nil assigns(:entries) |
|
62 | assert_not_nil assigns(:entries) | |
63 | assert_equal ['folder', '.project', 'helloworld.c', 'textfile.txt'], assigns(:entries).collect(&:name) |
|
63 | assert_equal ['folder', '.project', 'helloworld.c', 'textfile.txt'], assigns(:entries).collect(&:name) | |
64 | entry = assigns(:entries).detect {|e| e.name == 'helloworld.c'} |
|
64 | entry = assigns(:entries).detect {|e| e.name == 'helloworld.c'} | |
@@ -68,9 +68,9 class RepositoriesSubversionControllerTest < Test::Unit::TestCase | |||||
68 | end |
|
68 | end | |
69 |
|
69 | |||
70 | def test_browse_at_given_revision |
|
70 | def test_browse_at_given_revision | |
71 |
get : |
|
71 | get :show, :id => 1, :path => ['subversion_test'], :rev => 4 | |
72 | assert_response :success |
|
72 | assert_response :success | |
73 |
assert_template ' |
|
73 | assert_template 'show' | |
74 | assert_not_nil assigns(:entries) |
|
74 | assert_not_nil assigns(:entries) | |
75 | assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'], assigns(:entries).collect(&:name) |
|
75 | assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'], assigns(:entries).collect(&:name) | |
76 | end |
|
76 | end | |
@@ -131,7 +131,7 class RepositoriesSubversionControllerTest < Test::Unit::TestCase | |||||
131 | def test_directory_entry |
|
131 | def test_directory_entry | |
132 | get :entry, :id => 1, :path => ['subversion_test', 'folder'] |
|
132 | get :entry, :id => 1, :path => ['subversion_test', 'folder'] | |
133 | assert_response :success |
|
133 | assert_response :success | |
134 |
assert_template ' |
|
134 | assert_template 'show' | |
135 | assert_not_nil assigns(:entry) |
|
135 | assert_not_nil assigns(:entry) | |
136 | assert_equal 'folder', assigns(:entry).name |
|
136 | assert_equal 'folder', assigns(:entry).name | |
137 | end |
|
137 | end |
@@ -34,8 +34,8 class RepositoryGitTest < Test::Unit::TestCase | |||||
34 | @repository.fetch_changesets |
|
34 | @repository.fetch_changesets | |
35 | @repository.reload |
|
35 | @repository.reload | |
36 |
|
36 | |||
37 |
assert_equal |
|
37 | assert_equal 12, @repository.changesets.count | |
38 |
assert_equal |
|
38 | assert_equal 20, @repository.changes.count | |
39 |
|
39 | |||
40 | commit = @repository.changesets.find(:first, :order => 'committed_on ASC') |
|
40 | commit = @repository.changesets.find(:first, :order => 'committed_on ASC') | |
41 | assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments |
|
41 | assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments | |
@@ -57,10 +57,10 class RepositoryGitTest < Test::Unit::TestCase | |||||
57 | # Remove the 3 latest changesets |
|
57 | # Remove the 3 latest changesets | |
58 | @repository.changesets.find(:all, :order => 'committed_on DESC', :limit => 3).each(&:destroy) |
|
58 | @repository.changesets.find(:all, :order => 'committed_on DESC', :limit => 3).each(&:destroy) | |
59 | @repository.reload |
|
59 | @repository.reload | |
60 |
assert_equal |
|
60 | assert_equal 9, @repository.changesets.count | |
61 |
|
61 | |||
62 | @repository.fetch_changesets |
|
62 | @repository.fetch_changesets | |
63 |
assert_equal |
|
63 | assert_equal 12, @repository.changesets.count | |
64 | end |
|
64 | end | |
65 | else |
|
65 | else | |
66 | puts "Git test repository NOT FOUND. Skipping unit tests !!!" |
|
66 | puts "Git test repository NOT FOUND. Skipping unit tests !!!" |
General Comments 0
You need to be logged in to leave comments.
Login now