##// END OF EJS Templates
Merged r3394, r3466, r3467, r3468 and r3471 from trunk....
Jean-Philippe Lang -
r3387:17f60af49005
parent child
Show More
@@ -0,0 +1,9
1 class AddIndexOnChangesetsScmid < ActiveRecord::Migration
2 def self.up
3 add_index :changesets, [:repository_id, :scmid], :name => :changesets_repos_scmid
4 end
5
6 def self.down
7 remove_index :changesets, :name => :changesets_repos_scmid
8 end
9 end
@@ -0,0 +1,1
1 Texte encod� en ISO-8859-1. No newline at end of file
@@ -1,5 +1,5
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
@@ -57,6 +57,10 class Changeset < ActiveRecord::Base
57 super
57 super
58 end
58 end
59
59
60 def committer=(arg)
61 write_attribute(:committer, self.class.to_utf8(arg.to_s))
62 end
63
60 def project
64 def project
61 repository.project
65 repository.project
62 end
66 end
@@ -171,11 +175,12 class Changeset < ActiveRecord::Base
171 encoding = Setting.commit_logs_encoding.to_s.strip
175 encoding = Setting.commit_logs_encoding.to_s.strip
172 unless encoding.blank? || encoding == 'UTF-8'
176 unless encoding.blank? || encoding == 'UTF-8'
173 begin
177 begin
174 return Iconv.conv('UTF-8', encoding, str)
178 str = Iconv.conv('UTF-8', encoding, str)
175 rescue Iconv::Failure
179 rescue Iconv::Failure
176 # do nothing here
180 # do nothing here
177 end
181 end
178 end
182 end
179 str
183 # removes invalid UTF8 sequences
184 Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3]
180 end
185 end
181 end
186 end
@@ -40,23 +40,26 class Repository::Git < Repository
40 # With SCM's that have a sequential commit numbering, redmine is able to be
40 # With SCM's that have a sequential commit numbering, redmine is able to be
41 # clever and only fetch changesets going forward from the most recent one
41 # clever and only fetch changesets going forward from the most recent one
42 # it knows about. However, with git, you never know if people have merged
42 # it knows about. However, with git, you never know if people have merged
43 # commits into the middle of the repository history, so we always have to
43 # commits into the middle of the repository history, so we should parse
44 # parse the entire log.
44 # the entire log. Since it's way too slow for large repositories, we only
45 # parse 1 week before the last known commit.
46 # The repository can still be fully reloaded by calling #clear_changesets
47 # before fetching changesets (eg. for offline resync)
45 def fetch_changesets
48 def fetch_changesets
46 # Save ourselves an expensive operation if we're already up to date
49 c = changesets.find(:first, :order => 'committed_on DESC')
47 return if scm.num_revisions == changesets.count
50 since = (c ? c.committed_on - 7.days : nil)
48
51
49 revisions = scm.revisions('', nil, nil, :all => true)
52 revisions = scm.revisions('', nil, nil, :all => true, :since => since)
50 return if revisions.nil? || revisions.empty?
53 return if revisions.nil? || revisions.empty?
51
54
52 # Find revisions that redmine knows about already
55 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
53 existing_revisions = changesets.find(:all).map!{|c| c.scmid}
54
56
55 # Clean out revisions that are no longer in git
57 # Clean out revisions that are no longer in git
56 Changeset.delete_all(["scmid NOT IN (?) AND repository_id = (?)", revisions.map{|r| r.scmid}, self.id])
58 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
57
59
58 # Subtract revisions that redmine already knows about
60 # Subtract revisions that redmine already knows about
59 revisions.reject!{|r| existing_revisions.include?(r.scmid)}
61 recent_revisions = recent_changesets.map{|c| c.scmid}
62 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
60
63
61 # Save the remaining ones to the database
64 # Save the remaining ones to the database
62 revisions.each{|r| r.save(self)} unless revisions.nil?
65 revisions.each{|r| r.save(self)} unless revisions.nil?
@@ -33,21 +33,22 module Redmine
33 end
33 end
34
34
35 def branches
35 def branches
36 branches = []
36 return @branches if @branches
37 @branches = []
37 cmd = "#{GIT_BIN} --git-dir #{target('')} branch"
38 cmd = "#{GIT_BIN} --git-dir #{target('')} branch"
38 shellout(cmd) do |io|
39 shellout(cmd) do |io|
39 io.each_line do |line|
40 io.each_line do |line|
40 branches << line.match('\s*\*?\s*(.*)$')[1]
41 @branches << line.match('\s*\*?\s*(.*)$')[1]
41 end
42 end
42 end
43 end
43 branches.sort!
44 @branches.sort!
44 end
45 end
45
46
46 def tags
47 def tags
47 tags = []
48 return @tags if @tags
48 cmd = "#{GIT_BIN} --git-dir #{target('')} tag"
49 cmd = "#{GIT_BIN} --git-dir #{target('')} tag"
49 shellout(cmd) do |io|
50 shellout(cmd) do |io|
50 io.readlines.sort!.map{|t| t.strip}
51 @tags = io.readlines.sort!.map{|t| t.strip}
51 end
52 end
52 end
53 end
53
54
@@ -110,20 +111,16 module Redmine
110 end
111 end
111 end
112 end
112
113
113 def num_revisions
114 cmd = "#{GIT_BIN} --git-dir #{target('')} log --all --pretty=format:'' | wc -l"
115 shellout(cmd) {|io| io.gets.chomp.to_i + 1}
116 end
117
118 def revisions(path, identifier_from, identifier_to, options={})
114 def revisions(path, identifier_from, identifier_to, options={})
119 revisions = Revisions.new
115 revisions = Revisions.new
120
116
121 cmd = "#{GIT_BIN} --git-dir #{target('')} log --find-copies-harder --raw --date=iso --pretty=fuller"
117 cmd = "#{GIT_BIN} --git-dir #{target('')} log --raw --date=iso --pretty=fuller"
122 cmd << " --reverse" if options[:reverse]
118 cmd << " --reverse" if options[:reverse]
123 cmd << " --all" if options[:all]
119 cmd << " --all" if options[:all]
124 cmd << " -n #{options[:limit]} " if options[:limit]
120 cmd << " -n #{options[:limit]} " if options[:limit]
125 cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from
121 cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from
126 cmd << " #{shell_quote identifier_to} " if identifier_to
122 cmd << " #{shell_quote identifier_to} " if identifier_to
123 cmd << " --since=#{shell_quote(options[:since].strftime("%Y-%m-%d %H:%M:%S"))}" if options[:since]
127 cmd << " -- #{path}" if path && !path.empty?
124 cmd << " -- #{path}" if path && !path.empty?
128
125
129 shellout(cmd) do |io|
126 shellout(cmd) do |io|
@@ -1,5 +1,7
1 # redMine - project management software
1 # encoding: utf-8
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 #
3 # Redmine - project management software
4 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 #
5 #
4 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
@@ -117,4 +119,18 class ChangesetTest < ActiveSupport::TestCase
117 changeset = Changeset.find_by_revision('10')
119 changeset = Changeset.find_by_revision('10')
118 assert_nil changeset.next
120 assert_nil changeset.next
119 end
121 end
122
123 def test_comments_should_be_converted_to_utf8
124 with_settings :commit_logs_encoding => 'ISO-8859-1' do
125 c = Changeset.new
126 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
127 assert_equal "Texte encodé en ISO-8859-1.", c.comments
128 end
129 end
130
131 def test_invalid_utf8_sequences_in_comments_should_be_stripped
132 c = Changeset.new
133 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
134 assert_equal "Texte encod en ISO-8859-1.", c.comments
135 end
120 end
136 end
@@ -35,7 +35,7 class RepositoryGitTest < ActiveSupport::TestCase
35 @repository.reload
35 @repository.reload
36
36
37 assert_equal 12, @repository.changesets.count
37 assert_equal 12, @repository.changesets.count
38 assert_equal 20, @repository.changes.count
38 assert_equal 21, @repository.changes.count
39
39
40 commit = @repository.changesets.find(:first, :order => 'committed_on ASC')
40 commit = @repository.changesets.find(:first, :order => 'committed_on ASC')
41 assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
41 assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
General Comments 0
You need to be logged in to leave comments. Login now