summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2008-03-12 20:28:49 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2008-03-12 20:28:49 +0000
commit3a9b0988c7515371531e47f9eef9f8e60ce352aa (patch)
tree2a2deaedbd321dcf838c631dfed357f3c1110dbe /app
parent6fcc512cb77a0851ab8c3c693fd178b564a600dd (diff)
downloadredmine-3a9b0988c7515371531e47f9eef9f8e60ce352aa.tar.gz
redmine-3a9b0988c7515371531e47f9eef9f8e60ce352aa.zip
Merged Git support branch (r1200 to r1226).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1236 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/repositories_controller.rb4
-rw-r--r--app/helpers/application_helper.rb7
-rw-r--r--app/helpers/repositories_helper.rb8
-rw-r--r--app/models/changeset.rb11
-rw-r--r--app/models/repository.rb4
-rw-r--r--app/models/repository/bazaar.rb2
-rw-r--r--app/models/repository/cvs.rb40
-rw-r--r--app/models/repository/darcs.rb9
-rw-r--r--app/models/repository/git.rb70
-rw-r--r--app/models/repository/subversion.rb2
-rw-r--r--app/views/repositories/_dir_list_content.rhtml2
-rw-r--r--app/views/repositories/_revisions.rhtml2
-rw-r--r--app/views/repositories/annotate.rhtml2
-rw-r--r--app/views/repositories/diff.rhtml10
-rw-r--r--app/views/repositories/revision.rhtml2
15 files changed, 129 insertions, 46 deletions
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 13d3eaa32..bce5f66a9 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -134,7 +134,7 @@ class RepositoriesController < ApplicationController
end
def diff
- @rev_to = params[:rev_to] ? params[:rev_to].to_i : (@rev - 1)
+ @rev_to = params[:rev_to]
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
@@ -185,7 +185,7 @@ private
render_404 and return false unless @repository
@path = params[:path].join('/') unless params[:path].nil?
@path ||= ''
- @rev = params[:rev].to_i if params[:rev]
+ @rev = params[:rev]
rescue ActiveRecord::RecordNotFound
render_404
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index f21b43a23..be0b808d2 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -270,6 +270,7 @@ module ApplicationHelper
# #52 -> Link to issue #52
# Changesets:
# r52 -> Link to revision 52
+ # commit:a85130f -> Link to scmid starting with a85130f
# Documents:
# document#17 -> Link to document with id 17
# document:Greetings -> Link to the document with title "Greetings"
@@ -280,7 +281,7 @@ module ApplicationHelper
# version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
# Attachments:
# attachment:file.zip -> Link to the attachment of the current object named file.zip
- text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
+ text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version|commit)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
link = nil
if esc.nil?
@@ -325,6 +326,10 @@ module ApplicationHelper
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
:class => 'version'
end
+ when 'commit'
+ if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
+ link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project.id, :rev => changeset.revision}, :class => 'changeset', :title => truncate(changeset.comments, 100)
+ end
when 'attachment'
if attachments && attachment = attachments.detect {|a| a.filename == name }
link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
index d7d7f4349..31daf1bd8 100644
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -25,6 +25,10 @@ module RepositoriesHelper
type ? CodeRay.scan(content, type).html : h(content)
end
+ def format_revision(txt)
+ txt.to_s[0,8]
+ end
+
def to_utf8(str)
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
@@ -76,6 +80,10 @@ module RepositoriesHelper
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
end
+ def git_field_tags(form, repository)
+ content_tag('p', form.text_field(:url, :label => 'Path to .git directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
+ end
+
def cvs_field_tags(form, repository)
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
diff --git a/app/models/changeset.rb b/app/models/changeset.rb
index dbe06935d..ce9ea28ca 100644
--- a/app/models/changeset.rb
+++ b/app/models/changeset.rb
@@ -32,7 +32,6 @@ class Changeset < ActiveRecord::Base
:date_column => 'committed_on'
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
- validates_numericality_of :revision, :only_integer => true
validates_uniqueness_of :revision, :scope => :repository_id
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
@@ -89,7 +88,11 @@ class Changeset < ActiveRecord::Base
# don't change the status is the issue is closed
next if issue.status.is_closed?
user = committer_user || User.anonymous
- journal = issue.init_journal(user, l(:text_status_changed_by_changeset, "r#{self.revision}"))
+ csettext = "r#{self.revision}"
+ if self.scmid && (! (csettext =~ /^r[0-9]+$/))
+ csettext = "commit:\"#{self.scmid}\""
+ end
+ journal = issue.init_journal(user, l(:text_status_changed_by_changeset, csettext))
issue.status = fix_status
issue.done_ratio = done_ratio if done_ratio
issue.save
@@ -114,11 +117,11 @@ class Changeset < ActiveRecord::Base
# Returns the previous changeset
def previous
- @previous ||= Changeset.find(:first, :conditions => ['revision < ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision DESC')
+ @previous ||= Changeset.find(:first, :conditions => ['id < ? AND repository_id = ?', self.id, self.repository_id], :order => 'id DESC')
end
# Returns the next changeset
def next
- @next ||= Changeset.find(:first, :conditions => ['revision > ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision ASC')
+ @next ||= Changeset.find(:first, :conditions => ['id > ? AND repository_id = ?', self.id, self.repository_id], :order => 'id ASC')
end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index be31ac2e5..229c8dae4 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -17,7 +17,7 @@
class Repository < ActiveRecord::Base
belongs_to :project
- has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.revision DESC"
+ has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
has_many :changes, :through => :changesets
def scm
@@ -51,7 +51,7 @@ class Repository < ActiveRecord::Base
path = "/#{path}" unless path.starts_with?('/')
Change.find(:all, :include => :changeset,
:conditions => ["repository_id = ? AND path = ?", id, path],
- :order => "committed_on DESC, #{Changeset.table_name}.revision DESC").collect(&:changeset)
+ :order => "committed_on DESC, #{Changeset.table_name}.id DESC").collect(&:changeset)
end
def latest_changeset
diff --git a/app/models/repository/bazaar.rb b/app/models/repository/bazaar.rb
index 6e387f957..1b75066c2 100644
--- a/app/models/repository/bazaar.rb
+++ b/app/models/repository/bazaar.rb
@@ -51,7 +51,7 @@ class Repository::Bazaar < Repository
scm_info = scm.info
if scm_info
# latest revision found in database
- db_revision = latest_changeset ? latest_changeset.revision : 0
+ db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
# latest revision in the repository
scm_revision = scm_info.lastrev.identifier.to_i
if db_revision < scm_revision
diff --git a/app/models/repository/cvs.rb b/app/models/repository/cvs.rb
index 16d906316..a78b60806 100644
--- a/app/models/repository/cvs.rb
+++ b/app/models/repository/cvs.rb
@@ -82,9 +82,6 @@ class Repository::Cvs < Repository
end
def fetch_changesets
- #not the preferred way with CVS. maybe we should introduce always a cron-job for this
- last_commit = changesets.maximum(:committed_on)
-
# some nifty bits to introduce a commit-id with cvs
# natively cvs doesn't provide any kind of changesets, there is only a revision per file.
# we now take a guess using the author, the commitlog and the commit-date.
@@ -94,8 +91,10 @@ class Repository::Cvs < Repository
# we use a small delta here, to merge all changes belonging to _one_ changeset
time_delta=10.seconds
+ fetch_since = latest_changeset ? latest_changeset.committed_on : nil
transaction do
- scm.revisions('', last_commit, nil, :with_paths => true) do |revision|
+ tmp_rev_num = 1
+ scm.revisions('', fetch_since, nil, :with_paths => true) do |revision|
# only add the change to the database, if it doen't exists. the cvs log
# is not exclusive at all.
unless changes.find_by_path_and_revision(scm.with_leading_slash(revision.paths[0][:path]), revision.paths[0][:revision])
@@ -107,18 +106,16 @@ class Repository::Cvs < Repository
})
# create a new changeset....
- unless cs
- # we use a negative changeset-number here (just for inserting)
+ unless cs
+ # we use a temporaray revision number here (just for inserting)
# later on, we calculate a continous positive number
- next_rev = changesets.minimum(:revision)
- next_rev = 0 if next_rev.nil? or next_rev > 0
- next_rev = next_rev - 1
-
- cs=Changeset.create(:repository => self,
- :revision => next_rev,
- :committer => revision.author,
- :committed_on => revision.time,
- :comments => revision.message)
+ latest = changesets.find(:first, :order => 'id DESC')
+ cs = Changeset.create(:repository => self,
+ :revision => "_#{tmp_rev_num}",
+ :committer => revision.author,
+ :committed_on => revision.time,
+ :comments => revision.message)
+ tmp_rev_num += 1
end
#convert CVS-File-States to internal Action-abbrevations
@@ -139,12 +136,13 @@ class Repository::Cvs < Repository
end
end
- next_rev = [changesets.maximum(:revision) || 0, 0].max
- changesets.find(:all, :conditions=>["revision < 0"], :order=>"committed_on ASC").each() do |changeset|
- next_rev = next_rev + 1
- changeset.revision = next_rev
- changeset.save!
+ # Renumber new changesets in chronological order
+ c = changesets.find(:first, :order => 'committed_on DESC, id DESC', :conditions => "revision NOT LIKE '_%'")
+ next_rev = c.nil? ? 1 : (c.revision.to_i + 1)
+ changesets.find(:all, :order => 'committed_on ASC, id ASC', :conditions => "revision LIKE '_%'").each do |changeset|
+ changeset.update_attribute :revision, next_rev
+ next_rev += 1
end
- end
+ end # transaction
end
end
diff --git a/app/models/repository/darcs.rb b/app/models/repository/darcs.rb
index 48cc246fb..cc608d370 100644
--- a/app/models/repository/darcs.rb
+++ b/app/models/repository/darcs.rb
@@ -47,18 +47,19 @@ class Repository::Darcs < Repository
def diff(path, rev, rev_to, type)
patch_from = changesets.find_by_revision(rev)
+ return nil if patch_from.nil?
patch_to = changesets.find_by_revision(rev_to) if rev_to
if path.blank?
path = patch_from.changes.collect{|change| change.path}.join(' ')
end
- scm.diff(path, patch_from.scmid, patch_to.scmid, type)
+ patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil, type) : nil
end
def fetch_changesets
scm_info = scm.info
if scm_info
db_last_id = latest_changeset ? latest_changeset.scmid : nil
- next_rev = latest_changeset ? latest_changeset.revision + 1 : 1
+ next_rev = latest_changeset ? latest_changeset.revision.to_i + 1 : 1
# latest revision in the repository
scm_revision = scm_info.lastrev.scmid
unless changesets.find_by_scmid(scm_revision)
@@ -71,9 +72,7 @@ class Repository::Darcs < Repository
:committer => revision.author,
:committed_on => revision.time,
:comments => revision.message)
-
- next if changeset.new_record?
-
+
revision.paths.each do |change|
Change.create(:changeset => changeset,
:action => change[:action],
diff --git a/app/models/repository/git.rb b/app/models/repository/git.rb
new file mode 100644
index 000000000..7213588ac
--- /dev/null
+++ b/app/models/repository/git.rb
@@ -0,0 +1,70 @@
+# redMine - project management software
+# Copyright (C) 2006-2007 Jean-Philippe Lang
+# Copyright (C) 2007 Patrick Aljord patcito@Ĺ‹mail.com
+# 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.
+
+require 'redmine/scm/adapters/git_adapter'
+
+class Repository::Git < Repository
+ attr_protected :root_url
+ validates_presence_of :url
+
+ def scm_adapter
+ Redmine::Scm::Adapters::GitAdapter
+ end
+
+ def self.scm_name
+ 'Git'
+ end
+
+ def changesets_for_path(path)
+ Change.find(:all, :include => :changeset,
+ :conditions => ["repository_id = ? AND path = ?", id, path],
+ :order => "committed_on DESC, #{Changeset.table_name}.revision DESC").collect(&:changeset)
+ end
+
+ def fetch_changesets
+ scm_info = scm.info
+ if scm_info
+ # latest revision found in database
+ db_revision = latest_changeset ? latest_changeset.revision : nil
+ # latest revision in the repository
+ scm_revision = scm_info.lastrev.scmid
+
+ unless changesets.find_by_scmid(scm_revision)
+
+ revisions = scm.revisions('', db_revision, nil)
+ transaction do
+ revisions.reverse_each do |revision|
+ changeset = Changeset.create(:repository => self,
+ :revision => revision.identifier,
+ :scmid => revision.scmid,
+ :committer => revision.author,
+ :committed_on => revision.time,
+ :comments => 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
+ end
+ end
+ end
+end
diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb
index a0485608d..0c2239c43 100644
--- a/app/models/repository/subversion.rb
+++ b/app/models/repository/subversion.rb
@@ -39,7 +39,7 @@ class Repository::Subversion < Repository
scm_info = scm.info
if scm_info
# latest revision found in database
- db_revision = latest_changeset ? latest_changeset.revision : 0
+ db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
# latest revision in the repository
scm_revision = scm_info.lastrev.identifier.to_i
if db_revision < scm_revision
diff --git a/app/views/repositories/_dir_list_content.rhtml b/app/views/repositories/_dir_list_content.rhtml
index a7b83e817..3564e52ab 100644
--- a/app/views/repositories/_dir_list_content.rhtml
+++ b/app/views/repositories/_dir_list_content.rhtml
@@ -23,7 +23,7 @@ else
end %>
</td>
<td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
-<td class="revision"><%= link_to(entry.lastrev.name, :action => 'revision', :id => @project, :rev => entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %></td>
+<td class="revision"><%= link_to(format_revision(entry.lastrev.name), :action => 'revision', :id => @project, :rev => entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %></td>
<td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
<td class="author"><%=h(entry.lastrev.author.to_s.split('<').first) if entry.lastrev %></td>
<% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev %>
diff --git a/app/views/repositories/_revisions.rhtml b/app/views/repositories/_revisions.rhtml
index 52992bb89..1bcf0208c 100644
--- a/app/views/repositories/_revisions.rhtml
+++ b/app/views/repositories/_revisions.rhtml
@@ -13,7 +13,7 @@
<% line_num = 1 %>
<% revisions.each do |changeset| %>
<tr class="changeset <%= cycle 'odd', 'even' %>">
-<td class="id"><%= link_to changeset.revision, :action => 'revision', :id => project, :rev => changeset.revision %></td>
+<td class="id"><%= link_to format_revision(changeset.revision), :action => 'revision', :id => project, :rev => changeset.revision %></td>
<td class="checkbox"><%= radio_button_tag('rev', changeset.revision, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
<td class="checkbox"><%= radio_button_tag('rev_to', changeset.revision, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
<td class="committed_on"><%= format_time(changeset.committed_on) %></td>
diff --git a/app/views/repositories/annotate.rhtml b/app/views/repositories/annotate.rhtml
index 28d99a393..b5669ef76 100644
--- a/app/views/repositories/annotate.rhtml
+++ b/app/views/repositories/annotate.rhtml
@@ -11,7 +11,7 @@
<tr class="bloc-<%= revision.nil? ? 0 : colors[revision.identifier || revision.revision] %>">
<th class="line-num"><%= line_num %></th>
<td class="revision">
- <%= (revision.identifier ? link_to(revision.identifier, :action => 'revision', :id => @project, :rev => revision.identifier) : revision.revision) if revision %></td>
+ <%= (revision.identifier ? link_to(format_revision(revision.identifier), :action => 'revision', :id => @project, :rev => revision.identifier) : format_revision(revision.revision)) if revision %></td>
<td class="author"><%= h(revision.author.to_s.split('<').first) if revision %></td>
<td class="line-code"><pre><%= line %></pre></td>
</tr>
diff --git a/app/views/repositories/diff.rhtml b/app/views/repositories/diff.rhtml
index 88c5f17a0..eaef1abf5 100644
--- a/app/views/repositories/diff.rhtml
+++ b/app/views/repositories/diff.rhtml
@@ -1,4 +1,4 @@
-<h2><%= l(:label_revision) %> <%= @rev %>: <%= @path.gsub(/^.*\//, '') %></h2>
+<h2><%= l(:label_revision) %> <%= format_revision(@rev) %> <%= @path.gsub(/^.*\//, '') %></h2>
<!-- Choose view type -->
<% form_tag({ :controller => 'repositories', :action => 'diff'}, :method => 'get') do %>
@@ -23,8 +23,8 @@
</th>
</tr>
<tr>
- <th colspan="2">@<%= @rev %></th>
- <th colspan="2">@<%= @rev_to %></th>
+ <th colspan="2">@<%= format_revision @rev %></th>
+ <th colspan="2">@<%= format_revision @rev_to %></th>
</tr>
</thead>
<tbody>
@@ -56,8 +56,8 @@
</th>
</tr>
<tr>
- <th>@<%= @rev %></th>
- <th>@<%= @rev_to %></th>
+ <th>@<%= format_revision @rev %></th>
+ <th>@<%= format_revision @rev_to %></th>
<th></th>
</tr>
</thead>
diff --git a/app/views/repositories/revision.rhtml b/app/views/repositories/revision.rhtml
index d60c0b0b7..5a7ef1fd5 100644
--- a/app/views/repositories/revision.rhtml
+++ b/app/views/repositories/revision.rhtml
@@ -19,7 +19,7 @@
<% end %>
</div>
-<h2><%= l(:label_revision) %> <%= @changeset.revision %></h2>
+<h2><%= l(:label_revision) %> <%= format_revision(@changeset.revision) %></h2>
<p><% if @changeset.scmid %>ID: <%= @changeset.scmid %><br /><% end %>
<em><%= @changeset.committer.to_s.split('<').first %>, <%= format_time(@changeset.committed_on) %></em></p>