##// END OF EJS Templates
Fixed: repository: mercurial: sort changesets by revision (#3449, #3567)....
Toshi MARUYAMA -
r4491:2ae2d3ef834c
parent child
Show More
@@ -1,90 +1,105
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'redmine/scm/adapters/mercurial_adapter'
19 19
20 20 class Repository::Mercurial < Repository
21 # sort changesets by revision number
22 has_many :changesets, :order => "#{Changeset.table_name}.id DESC", :foreign_key => 'repository_id'
23
21 24 attr_protected :root_url
22 25 validates_presence_of :url
23 26
24 27 def scm_adapter
25 28 Redmine::Scm::Adapters::MercurialAdapter
26 29 end
27 30
28 31 def self.scm_name
29 32 'Mercurial'
30 33 end
31 34
32 35 def entries(path=nil, identifier=nil)
33 36 entries=scm.entries(path, identifier)
34 37 if entries
35 38 entries.each do |entry|
36 39 next unless entry.is_file?
37 40 # Set the filesize unless browsing a specific revision
38 41 if identifier.nil?
39 42 full_path = File.join(root_url, entry.path)
40 43 entry.size = File.stat(full_path).size if File.file?(full_path)
41 44 end
42 45 # Search the DB for the entry's last change
43 46 change = changes.find(:first, :conditions => ["path = ?", scm.with_leading_slash(entry.path)], :order => "#{Changeset.table_name}.committed_on DESC")
44 47 if change
45 48 entry.lastrev.identifier = change.changeset.revision
46 49 entry.lastrev.name = change.changeset.revision
47 50 entry.lastrev.author = change.changeset.committer
48 51 entry.lastrev.revision = change.revision
49 52 end
50 53 end
51 54 end
52 55 entries
53 56 end
54 57
58 # Returns the latest changesets for +path+; sorted by revision number
59 def latest_changesets(path, rev, limit=10)
60 if path.blank?
61 changesets.find(:all, :include => :user, :limit => limit)
62 else
63 changes.find(:all, :include => {:changeset => :user},
64 :conditions => ["path = ?", path.with_leading_slash],
65 :order => "#{Changeset.table_name}.id DESC",
66 :limit => limit).collect(&:changeset)
67 end
68 end
69
55 70 def fetch_changesets
56 71 scm_info = scm.info
57 72 if scm_info
58 73 # latest revision found in database
59 74 db_revision = latest_changeset ? latest_changeset.revision.to_i : -1
60 75 # latest revision in the repository
61 76 latest_revision = scm_info.lastrev
62 77 return if latest_revision.nil?
63 78 scm_revision = latest_revision.identifier.to_i
64 79 if db_revision < scm_revision
65 80 logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
66 81 identifier_from = db_revision + 1
67 82 while (identifier_from <= scm_revision)
68 83 # loads changesets by batches of 100
69 84 identifier_to = [identifier_from + 99, scm_revision].min
70 85 revisions = scm.revisions('', identifier_from, identifier_to, :with_paths => true)
71 86 transaction do
72 87 revisions.each do |revision|
73 88 changeset = Changeset.create(:repository => self,
74 89 :revision => revision.identifier,
75 90 :scmid => revision.scmid,
76 91 :committer => revision.author,
77 92 :committed_on => revision.time,
78 93 :comments => revision.message)
79 94
80 95 revision.paths.each do |change|
81 96 changeset.create_change(change)
82 97 end
83 98 end
84 99 end unless revisions.nil?
85 100 identifier_from = identifier_to + 1
86 101 end
87 102 end
88 103 end
89 104 end
90 105 end
1 NO CONTENT: modified file, binary diff hidden
@@ -1,83 +1,94
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class RepositoryMercurialTest < ActiveSupport::TestCase
21 21 fixtures :projects
22 22
23 23 # No '..' in the repository path
24 24 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository'
25 25
26 26 def setup
27 27 @project = Project.find(1)
28 28 assert @repository = Repository::Mercurial.create(:project => @project, :url => REPOSITORY_PATH)
29 29 end
30 30
31 31 if File.directory?(REPOSITORY_PATH)
32 32 def test_fetch_changesets_from_scratch
33 33 @repository.fetch_changesets
34 34 @repository.reload
35 35
36 36 assert_equal 6, @repository.changesets.count
37 37 assert_equal 11, @repository.changes.count
38 38 assert_equal "Initial import.\nThe repository contains 3 files.", @repository.changesets.find_by_revision('0').comments
39 39 end
40 40
41 41 def test_fetch_changesets_incremental
42 42 @repository.fetch_changesets
43 43 # Remove changesets with revision > 2
44 44 @repository.changesets.find(:all).each {|c| c.destroy if c.revision.to_i > 2}
45 45 @repository.reload
46 46 assert_equal 3, @repository.changesets.count
47 47
48 48 @repository.fetch_changesets
49 49 assert_equal 6, @repository.changesets.count
50 50 end
51 51
52 52 def test_entries
53 53 assert_equal 2, @repository.entries("sources", 2).size
54 54 assert_equal 1, @repository.entries("sources", 3).size
55 55 end
56 56
57 57 def test_locate_on_outdated_repository
58 58 # Change the working dir state
59 59 %x{hg -R #{REPOSITORY_PATH} up -r 0}
60 60 assert_equal 1, @repository.entries("images", 0).size
61 61 assert_equal 2, @repository.entries("images").size
62 62 assert_equal 2, @repository.entries("images", 2).size
63 63 end
64 64
65 65 def test_cat
66 66 assert @repository.scm.cat("sources/welcome_controller.rb", 2)
67 67 assert_nil @repository.scm.cat("sources/welcome_controller.rb")
68 68 end
69 69
70 70 def test_isodatesec
71 71 # Template keyword 'isodatesec' supported in Mercurial 1.0 and higher
72 72 if @repository.scm.class.client_version_above?([1, 0])
73 73 @repository.fetch_changesets
74 74 @repository.reload
75 75 rev0_committed_on = Time.gm(2007, 12, 14, 9, 22, 52)
76 76 assert_equal @repository.changesets.find_by_revision('0').committed_on, rev0_committed_on
77 77 end
78 78 end
79
80 def test_changeset_order_by_revision
81 @repository.fetch_changesets
82 @repository.reload
83
84 c0 = @repository.latest_changeset
85 c1 = @repository.changesets.find_by_revision('0')
86 # sorted by revision (id), not by date
87 assert c0.revision.to_i > c1.revision.to_i
88 assert c0.committed_on < c1.committed_on
89 end
79 90 else
80 91 puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
81 92 def test_fake; assert true end
82 93 end
83 94 end
General Comments 0
You need to be logged in to leave comments. Login now