SVN commits are now stored in the database, and added to the activity view and the search engine.
New commits are automatically retrieved and stored when consulting the repository in the app. This behaviour can be disabled by unchecking 'Autofecth commits' in configuration settings. Commits can be fetched offline by running (recommanded at least for the initial import of past commits): ruby script/runner "Repository.fetch_changesets" It will load commits for all of the repositories. git-svn-id: http://redmine.rubyforge.org/svn/trunk@377 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
6f1dcdc08f
commit
16f9f50f50
|
@ -519,6 +519,17 @@ class ProjectsController < ApplicationController
|
||||||
@show_wiki_edits = 1
|
@show_wiki_edits = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless @project.repository.nil? || params[:show_changesets] == "0"
|
||||||
|
@project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]).each { |i|
|
||||||
|
def i.created_on
|
||||||
|
self.committed_on
|
||||||
|
end
|
||||||
|
@events_by_day[i.created_on.to_date] ||= []
|
||||||
|
@events_by_day[i.created_on.to_date] << i
|
||||||
|
}
|
||||||
|
@show_changesets = 1
|
||||||
|
end
|
||||||
|
|
||||||
render :layout => false if request.xhr?
|
render :layout => false if request.xhr?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -581,10 +592,10 @@ class ProjectsController < ApplicationController
|
||||||
@question = params[:q] || ""
|
@question = params[:q] || ""
|
||||||
@question.strip!
|
@question.strip!
|
||||||
@all_words = params[:all_words] || (params[:submit] ? false : true)
|
@all_words = params[:all_words] || (params[:submit] ? false : true)
|
||||||
@scope = params[:scope] || (params[:submit] ? [] : %w(issues news documents wiki) )
|
@scope = params[:scope] || (params[:submit] ? [] : %w(issues changesets news documents wiki) )
|
||||||
if !@question.empty?
|
# tokens must be at least 3 character long
|
||||||
# tokens must be at least 3 character long
|
@tokens = @question.split.uniq.select {|w| w.length > 2 }
|
||||||
@tokens = @question.split.uniq.select {|w| w.length > 2 }
|
if !@tokens.empty?
|
||||||
# no more than 5 tokens to search for
|
# no more than 5 tokens to search for
|
||||||
@tokens.slice! 5..-1 if @tokens.size > 5
|
@tokens.slice! 5..-1 if @tokens.size > 5
|
||||||
# strings used in sql like statement
|
# strings used in sql like statement
|
||||||
|
@ -596,7 +607,10 @@ class ProjectsController < ApplicationController
|
||||||
@results += @project.news.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort], :include => :author ) if @scope.include? 'news'
|
@results += @project.news.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort], :include => :author ) if @scope.include? 'news'
|
||||||
@results += @project.documents.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'documents'
|
@results += @project.documents.find(:all, :limit => limit, :conditions => [ (["(LOWER(title) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'documents'
|
||||||
@results += @project.wiki.pages.find(:all, :limit => limit, :include => :content, :conditions => [ (["(LOWER(title) like ? OR LOWER(text) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @project.wiki && @scope.include?('wiki')
|
@results += @project.wiki.pages.find(:all, :limit => limit, :include => :content, :conditions => [ (["(LOWER(title) like ? OR LOWER(text) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @project.wiki && @scope.include?('wiki')
|
||||||
|
@results += @project.repository.changesets.find(:all, :limit => limit, :conditions => [ (["(LOWER(comment) like ?)"] * like_tokens.size).join(operator), * (like_tokens).sort] ) if @project.repository && @scope.include?('changesets')
|
||||||
@question = @tokens.join(" ")
|
@question = @tokens.join(" ")
|
||||||
|
else
|
||||||
|
@question = ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# redMine - project management software
|
# redMine - project management software
|
||||||
# Copyright (C) 2006 Jean-Philippe Lang
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
|
@ -20,9 +20,16 @@ class RepositoriesController < ApplicationController
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
# get entries for the browse frame
|
||||||
@entries = @repository.scm.entries('')
|
@entries = @repository.scm.entries('')
|
||||||
show_error and return unless @entries
|
show_error and return unless @entries
|
||||||
@latest_revision = @entries.revisions.latest
|
# check if new revisions have been committed in the repository
|
||||||
|
scm_latestrev = @entries.revisions.latest
|
||||||
|
if Setting.autofetch_changesets? && scm_latestrev && ((@repository.latest_changeset.nil?) || (@repository.latest_changeset.revision < scm_latestrev.identifier.to_i))
|
||||||
|
@repository.fetch_changesets
|
||||||
|
@repository.reload
|
||||||
|
end
|
||||||
|
@changesets = @repository.changesets.find(:all, :limit => 5, :order => "committed_on DESC")
|
||||||
end
|
end
|
||||||
|
|
||||||
def browse
|
def browse
|
||||||
|
@ -31,9 +38,11 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions
|
def revisions
|
||||||
@entry = @repository.scm.entry(@path, @rev)
|
unless @path == ''
|
||||||
@revisions = @repository.scm.revisions(@path, @rev)
|
@entry = @repository.scm.entry(@path, @rev)
|
||||||
show_error and return unless @entry && @revisions
|
show_error and return unless @entry
|
||||||
|
end
|
||||||
|
@changesets = @repository.changesets_for_path(@path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def entry
|
def entry
|
||||||
|
@ -45,9 +54,8 @@ class RepositoriesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def revision
|
def revision
|
||||||
@revisions = @repository.scm.revisions '', @rev, @rev, :with_paths => true
|
@changeset = @repository.changesets.find_by_revision(@rev)
|
||||||
show_error and return unless @revisions
|
show_error and return unless @changeset
|
||||||
@revision = @revisions.first
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff
|
def diff
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Change < ActiveRecord::Base
|
||||||
|
belongs_to :changeset
|
||||||
|
|
||||||
|
validates_presence_of :changeset_id, :action, :path
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Changeset < ActiveRecord::Base
|
||||||
|
belongs_to :repository
|
||||||
|
has_many :changes, :dependent => :delete_all
|
||||||
|
|
||||||
|
validates_presence_of :repository_id, :revision, :committed_on
|
||||||
|
validates_numericality_of :revision, :only_integer => true
|
||||||
|
validates_uniqueness_of :revision, :scope => :repository_id
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
# redMine - project management software
|
# redMine - project management software
|
||||||
# Copyright (C) 2006 Jean-Philippe Lang
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
|
@ -17,6 +17,11 @@
|
||||||
|
|
||||||
class Repository < ActiveRecord::Base
|
class Repository < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
|
has_many :changesets, :dependent => :destroy, :order => 'revision DESC'
|
||||||
|
has_one :latest_changeset, :class_name => 'Changeset', :foreign_key => :repository_id, :order => 'revision DESC'
|
||||||
|
|
||||||
|
attr_protected :root_url
|
||||||
|
|
||||||
validates_presence_of :url
|
validates_presence_of :url
|
||||||
validates_format_of :url, :with => /^(http|https|svn|file):\/\/.+/i
|
validates_format_of :url, :with => /^(http|https|svn|file):\/\/.+/i
|
||||||
|
|
||||||
|
@ -27,10 +32,55 @@ class Repository < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def url=(str)
|
def url=(str)
|
||||||
unless str == self.url
|
super if root_url.blank?
|
||||||
self.attributes = {:root_url => nil }
|
end
|
||||||
@scm = nil
|
|
||||||
|
def changesets_for_path(path="")
|
||||||
|
path = "/#{path}%"
|
||||||
|
path = url.gsub(/^#{root_url}/, '') + path if root_url && root_url != url
|
||||||
|
path.squeeze!("/")
|
||||||
|
changesets.find(:all, :include => :changes,
|
||||||
|
:conditions => ["#{Change.table_name}.path LIKE ?", path])
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_changesets
|
||||||
|
scm_info = scm.info
|
||||||
|
if scm_info
|
||||||
|
lastrev_identifier = scm_info.lastrev.identifier.to_i
|
||||||
|
if latest_changeset.nil? || latest_changeset.revision < lastrev_identifier
|
||||||
|
logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
|
||||||
|
identifier_from = latest_changeset ? latest_changeset.revision + 1 : 1
|
||||||
|
while (identifier_from <= lastrev_identifier)
|
||||||
|
# loads changesets by batches of 200
|
||||||
|
identifier_to = [identifier_from + 199, lastrev_identifier].min
|
||||||
|
revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
|
||||||
|
transaction do
|
||||||
|
revisions.reverse_each do |revision|
|
||||||
|
changeset = Changeset.create(:repository => self,
|
||||||
|
:revision => revision.identifier,
|
||||||
|
:committer => revision.author,
|
||||||
|
:committed_on => revision.time,
|
||||||
|
:comment => revision.message)
|
||||||
|
|
||||||
|
revision.paths.each do |change|
|
||||||
|
Change.create(:changeset => changeset,
|
||||||
|
:action => change[:action],
|
||||||
|
:path => change[:path],
|
||||||
|
:from_path => change[:from_path],
|
||||||
|
:from_revision => change[:from_revision])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
identifier_from = identifier_to + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
super
|
end
|
||||||
|
|
||||||
|
# fetch new changesets for all repositories
|
||||||
|
# can be called periodically by an external script
|
||||||
|
# eg. ruby script/runner "Repository.fetch_changesets"
|
||||||
|
def self.fetch_changesets
|
||||||
|
find(:all).each(&:fetch_changesets)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# redMine - project management software
|
# redMine - project management software
|
||||||
# Copyright (C) 2006 Jean-Philippe Lang
|
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,20 +39,27 @@ module SvnRepos
|
||||||
@url
|
@url
|
||||||
end
|
end
|
||||||
|
|
||||||
# finds the root url of the svn repository
|
# get info about the svn repository
|
||||||
def retrieve_root_url
|
def info
|
||||||
cmd = "svn info --xml #{target('')}"
|
cmd = "svn info --xml #{target('')}"
|
||||||
cmd << " --username #{@login} --password #{@password}" if @login
|
cmd << " --username #{@login} --password #{@password}" if @login
|
||||||
root_url = nil
|
info = nil
|
||||||
shellout(cmd) do |io|
|
shellout(cmd) do |io|
|
||||||
begin
|
begin
|
||||||
doc = REXML::Document.new(io)
|
doc = REXML::Document.new(io)
|
||||||
root_url = doc.elements["info/entry/repository/root"].text
|
#root_url = doc.elements["info/entry/repository/root"].text
|
||||||
|
info = Info.new({:root_url => doc.elements["info/entry/repository/root"].text,
|
||||||
|
:lastrev => Revision.new({
|
||||||
|
:identifier => doc.elements["info/entry/commit"].attributes['revision'],
|
||||||
|
:time => Time.parse(doc.elements["info/entry/commit/date"].text),
|
||||||
|
:author => (doc.elements["info/entry/commit/author"] ? doc.elements["info/entry/commit/author"].text : "")
|
||||||
|
})
|
||||||
|
})
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil if $? && $?.exitstatus != 0
|
return nil if $? && $?.exitstatus != 0
|
||||||
root_url
|
info
|
||||||
rescue Errno::ENOENT => e
|
rescue Errno::ENOENT => e
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
@ -83,7 +90,7 @@ module SvnRepos
|
||||||
:lastrev => Revision.new({
|
:lastrev => Revision.new({
|
||||||
:identifier => entry.elements['commit'].attributes['revision'],
|
:identifier => entry.elements['commit'].attributes['revision'],
|
||||||
:time => Time.parse(entry.elements['commit'].elements['date'].text),
|
:time => Time.parse(entry.elements['commit'].elements['date'].text),
|
||||||
:author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "anonymous")
|
:author => (entry.elements['commit'].elements['author'] ? entry.elements['commit'].elements['author'].text : "")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -112,13 +119,15 @@ module SvnRepos
|
||||||
paths = []
|
paths = []
|
||||||
logentry.elements.each("paths/path") do |path|
|
logentry.elements.each("paths/path") do |path|
|
||||||
paths << {:action => path.attributes['action'],
|
paths << {:action => path.attributes['action'],
|
||||||
:path => path.text
|
:path => path.text,
|
||||||
|
:from_path => path.attributes['copyfrom-path'],
|
||||||
|
:from_revision => path.attributes['copyfrom-rev']
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
paths.sort! { |x,y| x[:path] <=> y[:path] }
|
paths.sort! { |x,y| x[:path] <=> y[:path] }
|
||||||
|
|
||||||
revisions << Revision.new({:identifier => logentry.attributes['revision'],
|
revisions << Revision.new({:identifier => logentry.attributes['revision'],
|
||||||
:author => (logentry.elements['author'] ? logentry.elements['author'].text : "anonymous"),
|
:author => (logentry.elements['author'] ? logentry.elements['author'].text : ""),
|
||||||
:time => Time.parse(logentry.elements['date'].text),
|
:time => Time.parse(logentry.elements['date'].text),
|
||||||
:message => logentry.elements['msg'].text,
|
:message => logentry.elements['msg'].text,
|
||||||
:paths => paths
|
:paths => paths
|
||||||
|
@ -171,7 +180,12 @@ module SvnRepos
|
||||||
raise CommandFailed
|
raise CommandFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def retrieve_root_url
|
||||||
|
info = self.info
|
||||||
|
info ? info.root_url : nil
|
||||||
|
end
|
||||||
|
|
||||||
def target(path)
|
def target(path)
|
||||||
path ||= ""
|
path ||= ""
|
||||||
base = path.match(/^\//) ? root_url : url
|
base = path.match(/^\//) ? root_url : url
|
||||||
|
@ -207,6 +221,14 @@ module SvnRepos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Info
|
||||||
|
attr_accessor :root_url, :lastrev
|
||||||
|
def initialize(attributes={})
|
||||||
|
self.root_url = attributes[:root_url] if attributes[:root_url]
|
||||||
|
self.lastrev = attributes[:lastrev]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Entry
|
class Entry
|
||||||
attr_accessor :name, :path, :kind, :size, :lastrev
|
attr_accessor :name, :path, :kind, :size, :lastrev
|
||||||
def initialize(attributes={})
|
def initialize(attributes={})
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<%= hidden_field_tag "repository_enabled", 0 %>
|
<%= hidden_field_tag "repository_enabled", 0 %>
|
||||||
<div id="repository">
|
<div id="repository">
|
||||||
<% fields_for :repository, @project.repository, { :builder => TabularFormBuilder, :lang => current_language} do |repository| %>
|
<% fields_for :repository, @project.repository, { :builder => TabularFormBuilder, :lang => current_language} do |repository| %>
|
||||||
<p><%= repository.text_field :url, :size => 60, :required => true %><br />(http://, https://, svn://, file:///)</p>
|
<p><%= repository.text_field :url, :size => 60, :required => true, :disabled => (@project.repository && !@project.repository.root_url.blank?) %><br />(http://, https://, svn://, file:///)</p>
|
||||||
<p><%= repository.text_field :login, :size => 30 %></p>
|
<p><%= repository.text_field :login, :size => 30 %></p>
|
||||||
<p><%= repository.password_field :password, :size => 30 %></p>
|
<p><%= repository.password_field :password, :size => 30 %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<%= select_year(@year, :prefix => "year", :discard_type => true) %></p>
|
<%= select_year(@year, :prefix => "year", :discard_type => true) %></p>
|
||||||
<p>
|
<p>
|
||||||
<%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0, :id => nil %> <%=l(:label_issue_plural)%><br />
|
<%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0, :id => nil %> <%=l(:label_issue_plural)%><br />
|
||||||
|
<% if @project.repository %><%= check_box_tag 'show_changesets', 1, @show_changesets %><%= hidden_field_tag 'show_changesets', 0, :id => nil %> <%=l(:label_revision_plural)%><br /><% end %>
|
||||||
<%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0, :id => nil %> <%=l(:label_news_plural)%><br />
|
<%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0, :id => nil %> <%=l(:label_news_plural)%><br />
|
||||||
<%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0, :id => nil %> <%=l(:label_attachment_plural)%><br />
|
<%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0, :id => nil %> <%=l(:label_attachment_plural)%><br />
|
||||||
<%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0, :id => nil %> <%=l(:label_document_plural)%><br />
|
<%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0, :id => nil %> <%=l(:label_document_plural)%><br />
|
||||||
|
@ -39,6 +40,9 @@
|
||||||
<% elsif e.is_a? WikiContent.versioned_class %>
|
<% elsif e.is_a? WikiContent.versioned_class %>
|
||||||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> (<%= link_to '#' + e.version.to_s, :controller => 'wiki', :page => e.title, :version => e.version %>)<br />
|
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> (<%= link_to '#' + e.version.to_s, :controller => 'wiki', :page => e.title, :version => e.version %>)<br />
|
||||||
<% unless e.comment.blank? %><em><%=h e.comment %></em><% end %>
|
<% unless e.comment.blank? %><em><%=h e.comment %></em><% end %>
|
||||||
|
<% elsif e.is_a? Changeset %>
|
||||||
|
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br />
|
||||||
|
<em><%=h e.committer %><%= h(": #{e.comment}") unless e.comment.blank? %></em>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p></li>
|
</p></li>
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
<% form_tag({:action => 'search', :id => @project}, :method => :get) do %>
|
<% form_tag({:action => 'search', :id => @project}, :method => :get) do %>
|
||||||
<p><%= text_field_tag 'q', @question, :size => 30 %>
|
<p><%= text_field_tag 'q', @question, :size => 30 %>
|
||||||
<%= check_box_tag 'scope[]', 'issues', (@scope.include? 'issues') %> <label><%= l(:label_issue_plural) %></label>
|
<%= check_box_tag 'scope[]', 'issues', (@scope.include? 'issues') %> <label><%= l(:label_issue_plural) %></label>
|
||||||
|
<% if @project.repository %>
|
||||||
|
<%= check_box_tag 'scope[]', 'changesets', (@scope.include? 'changesets') %> <label><%= l(:label_revision_plural) %></label>
|
||||||
|
<% end %>
|
||||||
<%= check_box_tag 'scope[]', 'news', (@scope.include? 'news') %> <label><%= l(:label_news_plural) %></label>
|
<%= check_box_tag 'scope[]', 'news', (@scope.include? 'news') %> <label><%= l(:label_news_plural) %></label>
|
||||||
<%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label>
|
<%= check_box_tag 'scope[]', 'documents', (@scope.include? 'documents') %> <label><%= l(:label_document_plural) %></label>
|
||||||
<% if @project.wiki %>
|
<% if @project.wiki %>
|
||||||
|
@ -36,6 +39,10 @@
|
||||||
<%=l(:label_wiki)%>: <%= link_to highlight_tokens(h(e.pretty_title), @tokens), :controller => 'wiki', :action => 'index', :id => @project, :page => e.title %><br />
|
<%=l(:label_wiki)%>: <%= link_to highlight_tokens(h(e.pretty_title), @tokens), :controller => 'wiki', :action => 'index', :id => @project, :page => e.title %><br />
|
||||||
<%= highlight_tokens(e.content.text, @tokens) %><br />
|
<%= highlight_tokens(e.content.text, @tokens) %><br />
|
||||||
<i><%= e.content.author ? e.content.author.name : "Anonymous" %>, <%= format_time(e.content.updated_on) %></i>
|
<i><%= e.content.author ? e.content.author.name : "Anonymous" %>, <%= format_time(e.content.updated_on) %></i>
|
||||||
|
<% elsif e.is_a? Changeset %>
|
||||||
|
<%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br />
|
||||||
|
<%= highlight_tokens(e.comment, @tokens) %><br />
|
||||||
|
<em><%= e.committer.blank? ? e.committer : "Anonymous" %>, <%= format_time(e.committed_on) %></em>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p></li>
|
</p></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<table class="list">
|
||||||
|
<thead><tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th><%= l(:field_author) %></th>
|
||||||
|
<th><%= l(:label_date) %></th>
|
||||||
|
<th><%= l(:field_comment) %></th>
|
||||||
|
<th></th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<% changesets.each do |changeset| %>
|
||||||
|
<tr class="<%= cycle 'odd', 'even' %>">
|
||||||
|
<th align="center"><%= link_to changeset.revision, :action => 'revision', :id => project, :rev => changeset.revision %></th>
|
||||||
|
<td align="center"><em><%=h changeset.committer %></em></td>
|
||||||
|
<td align="center"><%= format_time(changeset.committed_on) %></td>
|
||||||
|
<td style="width:70%"><%= textilizable(changeset.comment) %></td>
|
||||||
|
<td align="center"><%= link_to 'Diff', :action => 'diff', :id => project, :path => path, :rev => changeset.revision if entry && entry.is_file? && changeset != changesets.last %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
|
@ -5,10 +5,10 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2><%= l(:label_revision) %> <%= @revision.identifier %></h2>
|
<h2><%= l(:label_revision) %> <%= @changeset.revision %></h2>
|
||||||
|
|
||||||
<p><em><%= @revision.author %>, <%= format_time(@revision.time) %></em></p>
|
<p><em><%= @changeset.committer %>, <%= format_time(@changeset.committed_on) %></em></p>
|
||||||
<%= textilizable @revision.message %>
|
<%= textilizable @changeset.comment %>
|
||||||
|
|
||||||
<div style="float:right;">
|
<div style="float:right;">
|
||||||
<div class="square action_A"></div> <div style="float:left;"><%= l(:label_added) %> </div>
|
<div class="square action_A"></div> <div style="float:left;"><%= l(:label_added) %> </div>
|
||||||
|
@ -19,19 +19,19 @@
|
||||||
<h3><%= l(:label_attachment_plural) %></h3>
|
<h3><%= l(:label_attachment_plural) %></h3>
|
||||||
<table class="list">
|
<table class="list">
|
||||||
<tbody>
|
<tbody>
|
||||||
<% @revision.paths.each do |path| %>
|
<% @changeset.changes.each do |change| %>
|
||||||
<tr class="<%= cycle 'odd', 'even' %>">
|
<tr class="<%= cycle 'odd', 'even' %>">
|
||||||
<td><div class="square action_<%= path[:action] %>"></div> <%= path[:path] %></td>
|
<td><div class="square action_<%= change.action %>"></div> <%= change.path %></td>
|
||||||
<td>
|
<td>
|
||||||
<% if path[:action] == "M" %>
|
<% if change.action == "M" %>
|
||||||
<%= link_to 'View diff', :action => 'diff', :id => @project, :path => path[:path], :rev => @revision.identifier %>
|
<%= link_to 'View diff', :action => 'diff', :id => @project, :path => change.path, :rev => @changeset.revision %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p><%= lwr(:label_modification, @revision.paths.length) %></p>
|
<p><%= lwr(:label_modification, @changeset.changes.length) %></p>
|
||||||
|
|
||||||
<% content_for :header_tags do %>
|
<% content_for :header_tags do %>
|
||||||
<%= stylesheet_link_tag "scm" %>
|
<%= stylesheet_link_tag "scm" %>
|
||||||
|
|
|
@ -5,36 +5,17 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => @entry.kind, :revision => @rev } %></h2>
|
<h2><%= render :partial => 'navigation', :locals => { :path => @path, :kind => (@entry ? @entry.kind : nil), :revision => @rev } %></h2>
|
||||||
|
|
||||||
<% if @entry.is_file? %>
|
<% if @entry && @entry.is_file? %>
|
||||||
<h3><%=h @entry.name %></h3>
|
<h3><%=h @entry.name %></h3>
|
||||||
<p><%= link_to 'Download', {:action => 'entry', :id => @project, :path => @path, :rev => @rev, :format => 'raw' }, :class => "icon file" %> (<%= number_to_human_size @entry.size %>)</p>
|
<p><%= link_to 'Download', {:action => 'entry', :id => @project, :path => @path, :rev => @rev, :format => 'raw' }, :class => "icon file" %> (<%= number_to_human_size @entry.size %>)</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<h3>Revisions</h3>
|
<h3>Revisions</h3>
|
||||||
|
|
||||||
<table class="list">
|
<%= render :partial => 'revisions', :locals => {:project => @project, :path => @path, :changesets => @changesets, :entry => @entry }%>
|
||||||
<thead><tr>
|
<p><%= lwr(:label_modification, @changesets.length) %></p>
|
||||||
<th>#</th>
|
|
||||||
<th><%= l(:field_author) %></th>
|
|
||||||
<th><%= l(:label_date) %></th>
|
|
||||||
<th><%= l(:field_description) %></th>
|
|
||||||
<th></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody>
|
|
||||||
<% @revisions.each do |revision| %>
|
|
||||||
<tr class="<%= cycle 'odd', 'even' %>">
|
|
||||||
<th align="center"><%= link_to revision.identifier, :action => 'revision', :id => @project, :rev => revision.identifier %></th>
|
|
||||||
<td align="center"><em><%=h revision.author %></em></td>
|
|
||||||
<td align="center"><%= format_time(revision.time) %></td>
|
|
||||||
<td style="width:70%"><%= textilizable(revision.message) %></td>
|
|
||||||
<td align="center"><%= link_to 'Diff', :action => 'diff', :id => @project, :path => @path, :rev => revision.identifier if @entry.is_file? && revision != @revisions.last %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<p><%= lwr(:label_modification, @revisions.length) %></p>
|
|
||||||
|
|
||||||
<% content_for :header_tags do %>
|
<% content_for :header_tags do %>
|
||||||
<%= stylesheet_link_tag "scm" %>
|
<%= stylesheet_link_tag "scm" %>
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
<h2><%= l(:label_repository) %></h2>
|
<h2><%= l(:label_repository) %></h2>
|
||||||
|
|
||||||
<h3><%= l(:label_revision_plural) %></h3>
|
|
||||||
<% if @latest_revision %>
|
|
||||||
<p><%= l(:label_latest_revision) %>:
|
|
||||||
<%= link_to @latest_revision.identifier, :action => 'revision', :id => @project, :rev => @latest_revision.identifier %><br />
|
|
||||||
<em><%= @latest_revision.author %>, <%= format_time(@latest_revision.time) %></em></p>
|
|
||||||
<% end %>
|
|
||||||
<p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3><%= l(:label_browse) %></h3>
|
<h3><%= l(:label_browse) %></h3>
|
||||||
<%= render :partial => 'dir_list' %>
|
<%= render :partial => 'dir_list' %>
|
||||||
|
|
||||||
|
<% unless @changesets.empty? %>
|
||||||
|
<h3><%= l(:label_latest_revision_plural) %></h3>
|
||||||
|
<%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :changesets => @changesets, :entry => nil }%>
|
||||||
|
<p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% content_for :header_tags do %>
|
<% content_for :header_tags do %>
|
||||||
<%= stylesheet_link_tag "scm" %>
|
<%= stylesheet_link_tag "scm" %>
|
||||||
<% end %>
|
<% end %>
|
|
@ -45,6 +45,9 @@
|
||||||
<p><label><%= l(:setting_feeds_limit) %></label>
|
<p><label><%= l(:setting_feeds_limit) %></label>
|
||||||
<%= text_field_tag 'settings[feeds_limit]', Setting.feeds_limit, :size => 6 %></p>
|
<%= text_field_tag 'settings[feeds_limit]', Setting.feeds_limit, :size => 6 %></p>
|
||||||
|
|
||||||
|
<p><label><%= l(:setting_autofetch_changesets) %></label>
|
||||||
|
<%= check_box_tag 'settings[autofetch_changesets]', 1, Setting.autofetch_changesets? %><%= hidden_field_tag 'settings[autofetch_changesets]', 0 %></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<%= submit_tag l(:button_save) %>
|
<%= submit_tag l(:button_save) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -50,3 +50,5 @@ host_name:
|
||||||
feeds_limit:
|
feeds_limit:
|
||||||
format: int
|
format: int
|
||||||
default: 15
|
default: 15
|
||||||
|
autofetch_changesets:
|
||||||
|
default: 1
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
class CreateChangesets < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :changesets do |t|
|
||||||
|
t.column :repository_id, :integer, :null => false
|
||||||
|
t.column :revision, :integer, :null => false
|
||||||
|
t.column :committer, :string, :limit => 30
|
||||||
|
t.column :committed_on, :datetime, :null => false
|
||||||
|
t.column :comment, :text
|
||||||
|
end
|
||||||
|
add_index :changesets, [:repository_id, :revision], :unique => true, :name => :changesets_repos_rev
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :changesets
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
class CreateChanges < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :changes do |t|
|
||||||
|
t.column :changeset_id, :integer, :null => false
|
||||||
|
t.column :action, :string, :limit => 1, :default => "", :null => false
|
||||||
|
t.column :path, :string, :default => "", :null => false
|
||||||
|
t.column :from_path, :string
|
||||||
|
t.column :from_revision, :integer
|
||||||
|
end
|
||||||
|
add_index :changes, [:changeset_id], :name => :changesets_changeset_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :changes
|
||||||
|
end
|
||||||
|
end
|
|
@ -160,6 +160,7 @@ setting_host_name: Host Name
|
||||||
setting_text_formatting: Textformatierung
|
setting_text_formatting: Textformatierung
|
||||||
setting_wiki_compression: Wiki Historie komprimieren
|
setting_wiki_compression: Wiki Historie komprimieren
|
||||||
setting_feeds_limit: Limit Feed Inhalt
|
setting_feeds_limit: Limit Feed Inhalt
|
||||||
|
setting_autofetch_changesets: Autofetch SVN commits
|
||||||
|
|
||||||
label_user: Benutzer
|
label_user: Benutzer
|
||||||
label_user_plural: Benutzer
|
label_user_plural: Benutzer
|
||||||
|
@ -315,6 +316,7 @@ label_added: hinzugefügt
|
||||||
label_modified: geändert
|
label_modified: geändert
|
||||||
label_deleted: gelöscht
|
label_deleted: gelöscht
|
||||||
label_latest_revision: Aktuelleste Revision
|
label_latest_revision: Aktuelleste Revision
|
||||||
|
label_latest_revision_plural: Aktuelleste Revisionen
|
||||||
label_view_revisions: Revisionen anzeigen
|
label_view_revisions: Revisionen anzeigen
|
||||||
label_max_size: Maximale Größe
|
label_max_size: Maximale Größe
|
||||||
label_on: von
|
label_on: von
|
||||||
|
|
|
@ -160,6 +160,7 @@ setting_host_name: Host name
|
||||||
setting_text_formatting: Text formatting
|
setting_text_formatting: Text formatting
|
||||||
setting_wiki_compression: Wiki history compression
|
setting_wiki_compression: Wiki history compression
|
||||||
setting_feeds_limit: Feed content limit
|
setting_feeds_limit: Feed content limit
|
||||||
|
setting_autofetch_changesets: Autofetch SVN commits
|
||||||
|
|
||||||
label_user: User
|
label_user: User
|
||||||
label_user_plural: Users
|
label_user_plural: Users
|
||||||
|
@ -315,6 +316,7 @@ label_added: added
|
||||||
label_modified: modified
|
label_modified: modified
|
||||||
label_deleted: deleted
|
label_deleted: deleted
|
||||||
label_latest_revision: Latest revision
|
label_latest_revision: Latest revision
|
||||||
|
label_latest_revision_plural: Latest revisions
|
||||||
label_view_revisions: View revisions
|
label_view_revisions: View revisions
|
||||||
label_max_size: Maximum size
|
label_max_size: Maximum size
|
||||||
label_on: 'on'
|
label_on: 'on'
|
||||||
|
|
|
@ -160,6 +160,7 @@ setting_host_name: Nombre de anfitrión
|
||||||
setting_text_formatting: Formato de texto
|
setting_text_formatting: Formato de texto
|
||||||
setting_wiki_compression: Compresión de la historia de Wiki
|
setting_wiki_compression: Compresión de la historia de Wiki
|
||||||
setting_feeds_limit: Feed content limit
|
setting_feeds_limit: Feed content limit
|
||||||
|
setting_autofetch_changesets: Autofetch SVN commits
|
||||||
|
|
||||||
label_user: Usuario
|
label_user: Usuario
|
||||||
label_user_plural: Usuarios
|
label_user_plural: Usuarios
|
||||||
|
@ -315,6 +316,7 @@ label_added: agregado
|
||||||
label_modified: modificado
|
label_modified: modificado
|
||||||
label_deleted: suprimido
|
label_deleted: suprimido
|
||||||
label_latest_revision: La revisión más última
|
label_latest_revision: La revisión más última
|
||||||
|
label_latest_revision_plural: Latest revisions
|
||||||
label_view_revisions: Ver las revisiones
|
label_view_revisions: Ver las revisiones
|
||||||
label_max_size: Tamaño máximo
|
label_max_size: Tamaño máximo
|
||||||
label_on: en
|
label_on: en
|
||||||
|
|
|
@ -160,6 +160,7 @@ setting_host_name: Nom d'hôte
|
||||||
setting_text_formatting: Formatage du texte
|
setting_text_formatting: Formatage du texte
|
||||||
setting_wiki_compression: Compression historique wiki
|
setting_wiki_compression: Compression historique wiki
|
||||||
setting_feeds_limit: Limite du contenu des flux RSS
|
setting_feeds_limit: Limite du contenu des flux RSS
|
||||||
|
setting_autofetch_changesets: Récupération auto. des commits SVN
|
||||||
|
|
||||||
label_user: Utilisateur
|
label_user: Utilisateur
|
||||||
label_user_plural: Utilisateurs
|
label_user_plural: Utilisateurs
|
||||||
|
@ -315,6 +316,7 @@ label_added: ajouté
|
||||||
label_modified: modifié
|
label_modified: modifié
|
||||||
label_deleted: supprimé
|
label_deleted: supprimé
|
||||||
label_latest_revision: Dernière révision
|
label_latest_revision: Dernière révision
|
||||||
|
label_latest_revision_plural: Dernières révisions
|
||||||
label_view_revisions: Voir les révisions
|
label_view_revisions: Voir les révisions
|
||||||
label_max_size: Taille maximale
|
label_max_size: Taille maximale
|
||||||
label_on: sur
|
label_on: sur
|
||||||
|
|
|
@ -160,6 +160,7 @@ setting_host_name: Nome host
|
||||||
setting_text_formatting: Formattazione testo
|
setting_text_formatting: Formattazione testo
|
||||||
setting_wiki_compression: Compressione di storia di Wiki
|
setting_wiki_compression: Compressione di storia di Wiki
|
||||||
setting_feeds_limit: Feed content limit
|
setting_feeds_limit: Feed content limit
|
||||||
|
setting_autofetch_changesets: Autofetch SVN commits
|
||||||
|
|
||||||
label_user: Utente
|
label_user: Utente
|
||||||
label_user_plural: Utenti
|
label_user_plural: Utenti
|
||||||
|
@ -315,6 +316,7 @@ label_added: aggiunto
|
||||||
label_modified: modificato
|
label_modified: modificato
|
||||||
label_deleted: eliminato
|
label_deleted: eliminato
|
||||||
label_latest_revision: Ultima versione
|
label_latest_revision: Ultima versione
|
||||||
|
label_latest_revision_plural: Latest revisions
|
||||||
label_view_revisions: Mostra versioni
|
label_view_revisions: Mostra versioni
|
||||||
label_max_size: Dimensione massima
|
label_max_size: Dimensione massima
|
||||||
label_on: 'on'
|
label_on: 'on'
|
||||||
|
|
|
@ -161,6 +161,7 @@ setting_host_name: ホスト名
|
||||||
setting_text_formatting: テキストの書式
|
setting_text_formatting: テキストの書式
|
||||||
setting_wiki_compression: Wiki history compression
|
setting_wiki_compression: Wiki history compression
|
||||||
setting_feeds_limit: Feed content limit
|
setting_feeds_limit: Feed content limit
|
||||||
|
setting_autofetch_changesets: Autofetch SVN commits
|
||||||
|
|
||||||
label_user: ユーザ
|
label_user: ユーザ
|
||||||
label_user_plural: ユーザ
|
label_user_plural: ユーザ
|
||||||
|
@ -316,6 +317,7 @@ label_added: 追加された
|
||||||
label_modified: 変更された
|
label_modified: 変更された
|
||||||
label_deleted: 削除された
|
label_deleted: 削除された
|
||||||
label_latest_revision: 最新リビジョン
|
label_latest_revision: 最新リビジョン
|
||||||
|
label_latest_revision_plural: Latest revisions
|
||||||
label_view_revisions: リビジョンを見る
|
label_view_revisions: リビジョンを見る
|
||||||
label_max_size: 最大サイズ
|
label_max_size: 最大サイズ
|
||||||
label_on: 他
|
label_on: 他
|
||||||
|
|
Loading…
Reference in New Issue