Mercurial > hg > soundsoftware-site
view app/models/repository/cvs.rb @ 1082:997f6d7738f7 bug_531
In repo controller entry action, show the page for the file even if it's binary (so user still has access to history etc links). This makes it possible to use the entry action as the default when a file is clicked on
author | Chris Cannam <chris.cannam@soundsoftware.ac.uk> |
---|---|
date | Thu, 22 Nov 2012 18:04:17 +0000 |
parents | cbce1fd3b1b7 |
children | 433d4f72a19b |
line wrap: on
line source
# Redmine - project management software # Copyright (C) 2006-2011 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. require 'redmine/scm/adapters/cvs_adapter' require 'digest/sha1' class Repository::Cvs < Repository validates_presence_of :url, :root_url, :log_encoding def self.human_attribute_name(attribute_key_name) attr_name = attribute_key_name if attr_name == "root_url" attr_name = "cvsroot" elsif attr_name == "url" attr_name = "cvs_module" end super(attr_name) end def self.scm_adapter_class Redmine::Scm::Adapters::CvsAdapter end def self.scm_name 'CVS' end def entry(path=nil, identifier=nil) rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) scm.entry(path, rev.nil? ? nil : rev.committed_on) end def entries(path=nil, identifier=nil) rev = nil if ! identifier.nil? rev = changesets.find_by_revision(identifier) return nil if rev.nil? end entries = scm.entries(path, rev.nil? ? nil : rev.committed_on) if entries entries.each() do |entry| if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? ) change=changes.find_by_revision_and_path( entry.lastrev.revision, scm.with_leading_slash(entry.path) ) if change entry.lastrev.identifier = change.changeset.revision entry.lastrev.revision = change.changeset.revision entry.lastrev.author = change.changeset.committer # entry.lastrev.branch = change.branch end end end end entries end def cat(path, identifier=nil) rev = nil if ! identifier.nil? rev = changesets.find_by_revision(identifier) return nil if rev.nil? end scm.cat(path, rev.nil? ? nil : rev.committed_on) end def annotate(path, identifier=nil) rev = nil if ! identifier.nil? rev = changesets.find_by_revision(identifier) return nil if rev.nil? end scm.annotate(path, rev.nil? ? nil : rev.committed_on) end def diff(path, rev, rev_to) # convert rev to revision. CVS can't handle changesets here diff=[] changeset_from = changesets.find_by_revision(rev) if rev_to.to_i > 0 changeset_to = changesets.find_by_revision(rev_to) end changeset_from.changes.each() do |change_from| revision_from = nil revision_to = nil if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) revision_from = change_from.revision end if revision_from if changeset_to changeset_to.changes.each() do |change_to| revision_to = change_to.revision if change_to.path == change_from.path end end unless revision_to revision_to = scm.get_previous_revision(revision_from) end file_diff = scm.diff(change_from.path, revision_from, revision_to) diff = diff + file_diff unless file_diff.nil? end end return diff end def fetch_changesets # 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. # last one is the next step to take. the commit-date is not equal for all # commits in one changeset. cvs update the commit-date when the *,v file was touched. so # 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 tmp_rev_num = 1 scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision| # only add the change to the database, if it doen't exists. the cvs log # is not exclusive at all. tmp_time = revision.time.clone unless changes.find_by_path_and_revision( scm.with_leading_slash(revision.paths[0][:path]), revision.paths[0][:revision] ) cmt = Changeset.normalize_comments(revision.message, repo_log_encoding) author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding) cs = changesets.find( :first, :conditions => { :committed_on => tmp_time - time_delta .. tmp_time + time_delta, :committer => author_utf8, :comments => cmt } ) # create a new changeset.... unless cs # we use a temporaray revision number here (just for inserting) # later on, we calculate a continous positive number tmp_time2 = tmp_time.clone.gmtime branch = revision.paths[0][:branch] scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S") cs = Changeset.create(:repository => self, :revision => "tmp#{tmp_rev_num}", :scmid => scmid, :committer => revision.author, :committed_on => tmp_time, :comments => revision.message) tmp_rev_num += 1 end # convert CVS-File-States to internal Action-abbrevations # default action is (M)odified action = "M" if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1" action = "A" # add-action always at first revision (= 1.1) elsif revision.paths[0][:action] == "dead" action = "D" # dead-state is similar to Delete end Change.create( :changeset => cs, :action => action, :path => scm.with_leading_slash(revision.paths[0][:path]), :revision => revision.paths[0][:revision], :branch => revision.paths[0][:branch] ) end end # Renumber new changesets in chronological order changesets.find( :all, :order => 'committed_on ASC, id ASC', :conditions => "revision LIKE 'tmp%'" ).each do |changeset| changeset.update_attribute :revision, next_revision_number end end # transaction @current_revision_number = nil end private # Returns the next revision number to assign to a CVS changeset def next_revision_number # Need to retrieve existing revision numbers to sort them as integers sql = "SELECT revision FROM #{Changeset.table_name} " sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'" @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0) @current_revision_number += 1 end end