diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index ad19014..216fb26 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -72,9 +72,12 @@ class RepositoriesController < ApplicationController
def show
@repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty?
- @entries = @repository.entries(@path, @rev)
+ json_lookup = request.xhr? && 'all' == params[:details]
+ @entries = @repository.entries(@path, @rev, json_lookup ? false : true)
@changeset = @repository.find_changeset_by_name(@rev)
- if request.xhr?
+ if json_lookup
+ @entries ? render(:partial => 'dir_list_json') : render(:nothing => true)
+ elsif request.xhr?
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
else
(show_error_not_found; return) unless @entries
diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
index a3268df..ce7d963 100644
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -111,6 +111,24 @@ module RepositoriesHelper
output << ''
output
end
+
+ def render_content_json(entries)
+ data = {}
+ entries.each do |entry|
+ next if !entry.lastrev
+ changeset = @project.repository.find_changeset_by_name(entry.lastrev.identifier) if entry.lastrev.identifier
+
+ info = {}
+ info["revision"] = link_to_revision(changeset, @project) if changeset
+ info["age"] = distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev.time
+ info["author"] = changeset.nil? ? h(replace_invalid_utf8(entry.lastrev.author.to_s.split('<').first)) : h(changeset.author)
+ info["comments"] =truncate(Changeset.to_utf8(changeset.comments, changeset.repository.repo_log_encoding), :length => 50) unless changeset.nil?
+
+ hash = Digest::MD5.hexdigest(entry.path)
+ data[hash] = info
+ end
+ data.to_json
+ end
def to_utf8_for_repositories(str)
return str if str.nil?
diff --git a/app/models/repository.rb b/app/models/repository.rb
index eaf0cdb..194b717 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -76,11 +76,11 @@ class Repository < ActiveRecord::Base
end
def entry(path=nil, identifier=nil)
- scm.entry(path, identifier)
+ scm.entry(path, identifier, true)
end
- def entries(path=nil, identifier=nil)
- scm.entries(path, identifier)
+ def entries(path=nil, identifier=nil, skip_rev_lookup=false)
+ scm.entries(path, identifier, skip_rev_lookup)
end
def branches
diff --git a/app/views/repositories/_dir_list_content.rhtml b/app/views/repositories/_dir_list_content.rhtml
index 5207e3f..1d46cba 100644
--- a/app/views/repositories/_dir_list_content.rhtml
+++ b/app/views/repositories/_dir_list_content.rhtml
@@ -1,3 +1,4 @@
+<% extern_load = false %>
<% @entries.each do |entry| %>
<% tr_id = Digest::MD5.hexdigest(entry.path)
depth = params[:depth].to_i %>
@@ -18,10 +19,27 @@
:class => (entry.is_dir? ? 'icon icon-folder' : "icon icon-file #{Redmine::MimeType.css_class_of(ent_name)}")%>
<%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %> |
+<% if entry.lastrev.nil? %>
+<% if !extern_load %>
+
+<% javascript_tag :defer => "defer" do -%>
+<%= remote_function :url => {:action => 'show', :id => @project, :path => to_path_param(@path), :rev => @rev, :details => 'all'},
+ :method => :get, :complete => "scmRevisionsLoaded(request.responseText)" %>
+<% end -%>
+ |
+<% extern_load = true %>
+<% else %>
+ |
+<% end %>
+ |
+ |
+
+<% else %>
<% changeset = @project.repository.find_changeset_by_name(entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %>
<%= link_to_revision(changeset, @project) if changeset %> |
<%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %> |
<%= changeset.nil? ? h(replace_invalid_utf8(entry.lastrev.author.to_s.split('<').first)) : h(changeset.author) if entry.lastrev %> |
+<% end %>
<% end %>
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
index 5192618..0d8994e 100644
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -94,7 +94,7 @@ module Redmine
# Returns the entry identified by path and revision identifier
# or nil if entry doesn't exist in the repository
- def entry(path=nil, identifier=nil)
+ def entry(path=nil, identifier=nil, skip_rev_lookup=false)
parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
search_path = parts[0..-2].join('/')
search_name = parts[-1]
@@ -103,14 +103,14 @@ module Redmine
Entry.new(:path => '', :kind => 'dir')
else
# Search for the entry in the parent directory
- es = entries(search_path, identifier)
+ es = entries(search_path, identifier, skip_rev_lookup)
es ? es.detect {|e| e.name == search_name} : nil
end
end
# Returns an Entries collection
# or nil if the given path doesn't exist in the repository
- def entries(path=nil, identifier=nil)
+ def entries(path=nil, identifier=nil, skip_rev_lookup=false)
return nil
end
diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb
index 798a556..8ae1851 100644
--- a/lib/redmine/scm/adapters/git_adapter.rb
+++ b/lib/redmine/scm/adapters/git_adapter.rb
@@ -102,7 +102,7 @@ module Redmine
bras.include?('master') ? 'master' : bras.first
end
- def entries(path=nil, identifier=nil)
+ def entries(path=nil, identifier=nil, skip_rev_lookup=false)
path ||= ''
p = scm_iconv(@path_encoding, 'UTF-8', path)
entries = Entries.new
@@ -127,7 +127,7 @@ module Redmine
:path => full_p,
:kind => (type == "tree") ? 'dir' : 'file',
:size => (type == "tree") ? nil : size,
- :lastrev => @flag_report_last_commit ? lastrev(full_path, identifier) : Revision.new
+ :lastrev => @flag_report_last_commit ? lastrev(full_path, identifier, skip_rev_lookup) : Revision.new
}) unless entries.detect{|entry| entry.name == name}
end
end
@@ -137,8 +137,13 @@ module Redmine
nil
end
- def lastrev(path, rev)
+ def lastrev(path, rev, skip_rev_lookup)
return nil if path.nil?
+ cached_data = Rails.cache.read("repository_#{rev}_#{path}")
+ if skip_rev_lookup || cached_data
+ return Revision.new(cached_data) if cached_data
+ return nil
+ end
cmd_args = %w|log --no-color --encoding=UTF-8 --date=iso --pretty=fuller --no-merges -n 1|
cmd_args << rev if rev
cmd_args << "--" << path unless path.empty?
@@ -149,14 +154,16 @@ module Redmine
author = lines[1].match('Author:\s+(.*)$')[1]
time = Time.parse(lines[4].match('CommitDate:\s+(.*)$')[1])
- Revision.new({
+ data = {
:identifier => id,
:scmid => id,
:author => author,
:time => time,
:message => nil,
:paths => nil
- })
+ }
+ Rails.cache.write("repository_#{rev}_#{path}", data)
+ Revision.new(data)
rescue NoMethodError => e
logger.error("The revision '#{path}' has a wrong format")
return nil
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 11940f3..d06d900 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -234,6 +234,17 @@ function scmEntryLoaded(id) {
Element.removeClassName(id, 'loading');
}
+function scmRevisionsLoaded(jsondata) {
+ var data = JSON.parse( jsondata )
+ for( var file in data ) {
+ var el = document.getElementById(file)
+ el.getElementsByClassName("revision")[0].innerHTML = data[file]["revision"]
+ el.getElementsByClassName("age")[0].innerHTML = data[file]["age"]
+ el.getElementsByClassName("author")[0].innerHTML = data[file]["author"]
+ el.getElementsByClassName("comments")[0].innerHTML = data[file]["comments"]
+ }
+}
+
function randomKey(size) {
var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
var key = '';