From: Toshi MARUYAMA Date: Mon, 14 Mar 2011 10:36:34 +0000 (+0000) Subject: scm: mercurial: latest changesets improvement and supporting tag (#1981). X-Git-Tag: 1.2.0~720 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c8ce22c2751a0dc5e7604c0c4e793f5d47faafac;p=redmine.git scm: mercurial: latest changesets improvement and supporting tag (#1981). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5123 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb index 49fba82cf..6ea61b0c7 100644 --- a/app/models/repository/mercurial.rb +++ b/app/models/repository/mercurial.rb @@ -80,7 +80,6 @@ class Repository::Mercurial < Repository end # Returns the latest changesets for +path+; sorted by revision number - # Default behavior is to search in cached changesets # # Because :order => 'id DESC' is defined at 'has_many', # there is no need to set 'order'. @@ -88,18 +87,31 @@ class Repository::Mercurial < Repository # Sqlite3 and PostgreSQL pass. # Is this MySQL bug? def latest_changesets(path, rev, limit=10) - if path.blank? - changesets.find(:all, :include => :user, :limit => limit, :order => 'id DESC') - else - changesets.find(:all, :select => "DISTINCT #{Changeset.table_name}.*", - :joins => :changes, - :conditions => ["#{Change.table_name}.path = ? OR #{Change.table_name}.path LIKE ? ESCAPE ?", - path.with_leading_slash, - "#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%", '\\'], - :include => :user, :limit => limit, - :order => "#{Changeset.table_name}.id DESC" ) + changesets.find(:all, :include => :user, + :conditions => latest_changesets_cond(path, rev, limit), + :limit => limit, :order => "#{Changeset.table_name}.id DESC") + end + + def latest_changesets_cond(path, rev, limit) + cond, args = [], [] + + if last = rev ? find_changeset_by_name(scm.tagmap[rev] || rev) : nil + cond << "#{Changeset.table_name}.id <= ?" + args << last.id end + + unless path.blank? + cond << "EXISTS (SELECT * FROM #{Change.table_name} + WHERE #{Change.table_name}.changeset_id = #{Changeset.table_name}.id + AND (#{Change.table_name}.path = ? + OR #{Change.table_name}.path LIKE ? ESCAPE ?))" + args << path.with_leading_slash + args << "#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%" << '\\' + end + + [cond.join(' AND '), *args] unless cond.empty? end + private :latest_changesets_cond def fetch_changesets scm_rev = scm.info.lastrev.revision.to_i diff --git a/test/functional/repositories_mercurial_controller_test.rb b/test/functional/repositories_mercurial_controller_test.rb index 6a1750ae8..b8bc7c2f7 100644 --- a/test/functional/repositories_mercurial_controller_test.rb +++ b/test/functional/repositories_mercurial_controller_test.rb @@ -147,7 +147,7 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase "test-#{@char_1}.txt"], assigns(:entries).collect(&:name) changesets = assigns(:changesets) assert_not_nil changesets - assert_equal %w(27 21 20 19 18 17), changesets.collect(&:revision) + assert_equal %w(21 20 19 18 17), changesets.collect(&:revision) end end