From 06f078a8137a532e638274abc89d5a06654865e1 Mon Sep 17 00:00:00 2001 From: Toshi MARUYAMA Date: Mon, 28 Feb 2011 12:09:32 +0000 Subject: [PATCH] scm: ignore log encoding setting in Subversion and Mercurial (#7597). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4962 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/changeset.rb | 33 +++++++++++-------------- app/models/repository.rb | 7 +++++- app/models/repository/cvs.rb | 3 ++- app/models/repository/mercurial.rb | 4 +++ app/models/repository/subversion.rb | 4 +++ test/unit/repository_subversion_test.rb | 22 +++++++++++++++++ 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 5e1ee19ba..c4f1f3fc1 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -56,10 +56,6 @@ class Changeset < ActiveRecord::Base revision.to_s end end - - def comments=(comment) - write_attribute(:comments, Changeset.normalize_comments(comment)) - end def committed_on=(date) self.commit_date = date @@ -75,10 +71,6 @@ class Changeset < ActiveRecord::Base end end - def committer=(arg) - write_attribute(:committer, self.class.to_utf8(arg.to_s)) - end - def project repository.project end @@ -88,9 +80,11 @@ class Changeset < ActiveRecord::Base end def before_create - self.user = repository.find_committer_user(committer) + self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding) + self.comments = self.class.normalize_comments(self.comments, repository.repo_log_encoding) + self.user = repository.find_committer_user(self.committer) end - + def after_create scan_comment_for_issue_ids end @@ -163,11 +157,6 @@ class Changeset < ActiveRecord::Base @next ||= Changeset.find(:first, :conditions => ['id > ? AND repository_id = ?', self.id, self.repository_id], :order => 'id ASC') end - # Strips and reencodes a commit log before insertion into the database - def self.normalize_comments(str) - to_utf8(str.to_s.strip) - end - # Creates a new Change from it's common parameters def create_change(change) Change.create(:changeset => self, @@ -176,7 +165,7 @@ class Changeset < ActiveRecord::Base :from_path => change[:from_path], :from_revision => change[:from_revision]) end - + private # Finds an issue that can be referenced by the commit message @@ -246,9 +235,17 @@ class Changeset < ActiveRecord::Base return @short_comments, @long_comments end - def self.to_utf8(str) + public + + # Strips and reencodes a commit log before insertion into the database + def self.normalize_comments(str, encoding) + Changeset.to_utf8(str.to_s.strip, encoding) + end + + private + + def self.to_utf8(str, encoding) return str if str.blank? - encoding = Setting.commit_logs_encoding.to_s.strip unless encoding.blank? || encoding == 'UTF-8' begin str = Iconv.conv('UTF-8', encoding, str) diff --git a/app/models/repository.rb b/app/models/repository.rb index 075ecbe34..bddbbbec4 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -190,6 +190,11 @@ class Repository < ActiveRecord::Base end end + def repo_log_encoding + encoding = Setting.commit_logs_encoding.to_s.strip + encoding.blank? ? 'UTF-8' : encoding + end + # Fetches new changesets for all repositories of active projects # Can be called periodically by an external script # eg. ruby script/runner "Repository.fetch_changesets" @@ -217,7 +222,7 @@ class Repository < ActiveRecord::Base def self.available_scm subclasses.collect {|klass| [klass.scm_name, klass.name]} end - + def self.factory(klass_name, *args) klass = "Repository::#{klass_name}".constantize klass.new(*args) diff --git a/app/models/repository/cvs.rb b/app/models/repository/cvs.rb index c0cac5cdc..1c479d1bb 100644 --- a/app/models/repository/cvs.rb +++ b/app/models/repository/cvs.rb @@ -107,10 +107,11 @@ class Repository::Cvs < Repository 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) cs = changesets.find(:first, :conditions=>{ :committed_on=>tmp_time - time_delta .. tmp_time + time_delta, :committer=>revision.author, - :comments=>Changeset.normalize_comments(revision.message) + :comments=>cmt }) # create a new changeset.... diff --git a/app/models/repository/mercurial.rb b/app/models/repository/mercurial.rb index 010e3ab66..98575a56b 100644 --- a/app/models/repository/mercurial.rb +++ b/app/models/repository/mercurial.rb @@ -34,6 +34,10 @@ class Repository::Mercurial < Repository 'Mercurial' end + def repo_log_encoding + 'UTF-8' + end + # Returns the readable identifier for the given mercurial changeset def self.format_changeset_identifier(changeset) "#{changeset.revision}:#{changeset.scmid}" diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb index 059369298..b126d8d1e 100644 --- a/app/models/repository/subversion.rb +++ b/app/models/repository/subversion.rb @@ -30,6 +30,10 @@ class Repository::Subversion < Repository 'Subversion' end + def repo_log_encoding + 'UTF-8' + end + def latest_changesets(path, rev, limit=10) revisions = scm.revisions(path, rev, nil, :limit => limit) revisions ? changesets.find_all_by_revision(revisions.collect(&:identifier), :order => "committed_on DESC", :include => :user) : [] diff --git a/test/unit/repository_subversion_test.rb b/test/unit/repository_subversion_test.rb index 5e0b07183..158f17c55 100644 --- a/test/unit/repository_subversion_test.rb +++ b/test/unit/repository_subversion_test.rb @@ -137,6 +137,28 @@ class RepositorySubversionTest < ActiveSupport::TestCase assert c.event_title.include?('123456789:') assert_equal '123456789', c.event_url[:rev] end + + def test_log_encoding_ignore_setting + with_settings :commit_logs_encoding => 'windows-1252' do + s1 = "\xC2\x80" + s2 = "\xc3\x82\xc2\x80" + if s1.respond_to?(:force_encoding) + s3 = s1 + s4 = s2 + s1.force_encoding('ASCII-8BIT') + s2.force_encoding('ASCII-8BIT') + s3.force_encoding('ISO-8859-1') + s4.force_encoding('UTF-8') + assert_equal s3.encode('UTF-8'), s4 + end + c = Changeset.new(:repository => @repository, + :comments=>s2, + :revision=>'123', + :committed_on => Time.now) + assert c.save + assert_equal s2, c.comments + end + end else puts "Subversion test repository NOT FOUND. Skipping unit tests !!!" def test_fake; assert true end -- 2.39.5