annotate app/models/repository/mercurial.rb @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 7c48bad7d85d
children de76cd3e8c8e b859cc0c4fa1 6056b3c5f8f2
rev   line source
Chris@0 1 # redMine - project management software
Chris@0 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 require 'redmine/scm/adapters/mercurial_adapter'
Chris@0 19
Chris@0 20 class Repository::Mercurial < Repository
Chris@0 21 attr_protected :root_url
Chris@0 22 validates_presence_of :url
Chris@0 23
Chris@3 24 FETCH_AT_ONCE = 100 # number of changesets to fetch at once
Chris@3 25
Chris@0 26 def scm_adapter
Chris@0 27 Redmine::Scm::Adapters::MercurialAdapter
Chris@0 28 end
Chris@0 29
Chris@0 30 def self.scm_name
Chris@0 31 'Mercurial'
Chris@0 32 end
Chris@0 33
Chris@0 34 def entries(path=nil, identifier=nil)
Chris@3 35 scm.entries(path, identifier)
Chris@3 36 end
Chris@3 37
Chris@3 38 def branches
Chris@3 39 bras = scm.branches
Chris@3 40 bras.sort unless bras == %w|default|
Chris@3 41 end
Chris@3 42
Chris@3 43 # Returns the latest changesets for +path+
Chris@3 44 def latest_changesets(path, rev, limit=10)
Chris@3 45 changesets.find(:all, :include => :user,
Chris@3 46 :conditions => latest_changesets_cond(path, rev, limit),
Chris@3 47 :limit => limit)
Chris@3 48 end
Chris@3 49
Chris@3 50 def latest_changesets_cond(path, rev, limit)
Chris@3 51 cond, args = [], []
Chris@3 52
Chris@3 53 if scm.branchmap.member? rev
Chris@3 54 # dirty hack to filter by branch. branch name should be in database.
Chris@3 55 cond << "#{Changeset.table_name}.scmid IN (?)"
Chris@3 56 args << scm.nodes_in_branch(rev, path, rev, 0, :limit => limit)
Chris@3 57 elsif last = rev ? find_changeset_by_name(scm.tagmap[rev] || rev) : nil
Chris@3 58 cond << "#{Changeset.table_name}.id <= ?"
Chris@3 59 args << last.id
Chris@3 60 end
Chris@3 61
Chris@3 62 unless path.blank?
Chris@3 63 # TODO: there must be a better way to build sub-query
Chris@3 64 cond << "EXISTS (SELECT * FROM #{Change.table_name}
Chris@3 65 WHERE #{Change.table_name}.changeset_id = #{Changeset.table_name}.id
Chris@3 66 AND (#{Change.table_name}.path = ? OR #{Change.table_name}.path LIKE ?))"
Chris@3 67 args << path.with_leading_slash << "#{path.with_leading_slash}/%"
Chris@3 68 end
Chris@3 69
Chris@3 70 [cond.join(' AND '), *args] unless cond.empty?
Chris@3 71 end
Chris@3 72 private :latest_changesets_cond
Chris@3 73
Chris@3 74 def fetch_changesets
Chris@3 75 scm_rev = scm.info.lastrev.revision.to_i
Chris@3 76 db_rev = latest_changeset ? latest_changeset.revision.to_i : -1
Chris@3 77 return unless db_rev < scm_rev # already up-to-date
Chris@3 78
Chris@3 79 logger.debug "Fetching changesets for repository #{url}" if logger
Chris@3 80 (db_rev + 1).step(scm_rev, FETCH_AT_ONCE) do |i|
Chris@3 81 transaction do
Chris@3 82 scm.each_revision('', i, [i + FETCH_AT_ONCE - 1, scm_rev].min) do |re|
Chris@3 83 cs = Changeset.create(:repository => self,
Chris@3 84 :revision => re.revision,
Chris@3 85 :scmid => re.scmid,
Chris@3 86 :committer => re.author,
Chris@3 87 :committed_on => re.time,
Chris@3 88 :comments => re.message)
Chris@3 89 re.paths.each { |e| cs.create_change(e) }
Chris@0 90 end
Chris@0 91 end
Chris@0 92 end
Chris@3 93 self
Chris@0 94 end
Chris@0 95 end