##// END OF EJS Templates
scm: git: process new git revisions all at once rather than per branch (#10470)...
Toshi MARUYAMA -
r9149:9b333e1c8772
parent child
Show More
@@ -1,265 +1,252
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
4 #
4 #
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
8 # of the License, or (at your option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
18
19 require 'redmine/scm/adapters/git_adapter'
19 require 'redmine/scm/adapters/git_adapter'
20
20
21 class Repository::Git < Repository
21 class Repository::Git < Repository
22 attr_protected :root_url
22 attr_protected :root_url
23 validates_presence_of :url
23 validates_presence_of :url
24
24
25 def self.human_attribute_name(attribute_key_name, *args)
25 def self.human_attribute_name(attribute_key_name, *args)
26 attr_name = attribute_key_name.to_s
26 attr_name = attribute_key_name.to_s
27 if attr_name == "url"
27 if attr_name == "url"
28 attr_name = "path_to_repository"
28 attr_name = "path_to_repository"
29 end
29 end
30 super(attr_name, *args)
30 super(attr_name, *args)
31 end
31 end
32
32
33 def self.scm_adapter_class
33 def self.scm_adapter_class
34 Redmine::Scm::Adapters::GitAdapter
34 Redmine::Scm::Adapters::GitAdapter
35 end
35 end
36
36
37 def self.scm_name
37 def self.scm_name
38 'Git'
38 'Git'
39 end
39 end
40
40
41 def report_last_commit
41 def report_last_commit
42 extra_report_last_commit
42 extra_report_last_commit
43 end
43 end
44
44
45 def extra_report_last_commit
45 def extra_report_last_commit
46 return false if extra_info.nil?
46 return false if extra_info.nil?
47 v = extra_info["extra_report_last_commit"]
47 v = extra_info["extra_report_last_commit"]
48 return false if v.nil?
48 return false if v.nil?
49 v.to_s != '0'
49 v.to_s != '0'
50 end
50 end
51
51
52 def supports_directory_revisions?
52 def supports_directory_revisions?
53 true
53 true
54 end
54 end
55
55
56 def supports_revision_graph?
56 def supports_revision_graph?
57 true
57 true
58 end
58 end
59
59
60 def repo_log_encoding
60 def repo_log_encoding
61 'UTF-8'
61 'UTF-8'
62 end
62 end
63
63
64 # Returns the identifier for the given git changeset
64 # Returns the identifier for the given git changeset
65 def self.changeset_identifier(changeset)
65 def self.changeset_identifier(changeset)
66 changeset.scmid
66 changeset.scmid
67 end
67 end
68
68
69 # Returns the readable identifier for the given git changeset
69 # Returns the readable identifier for the given git changeset
70 def self.format_changeset_identifier(changeset)
70 def self.format_changeset_identifier(changeset)
71 changeset.revision[0, 8]
71 changeset.revision[0, 8]
72 end
72 end
73
73
74 def branches
74 def branches
75 scm.branches
75 scm.branches
76 end
76 end
77
77
78 def tags
78 def tags
79 scm.tags
79 scm.tags
80 end
80 end
81
81
82 def default_branch
82 def default_branch
83 scm.default_branch
83 scm.default_branch
84 rescue Exception => e
84 rescue Exception => e
85 logger.error "git: error during get default branch: #{e.message}"
85 logger.error "git: error during get default branch: #{e.message}"
86 nil
86 nil
87 end
87 end
88
88
89 def find_changeset_by_name(name)
89 def find_changeset_by_name(name)
90 return nil if name.nil? || name.empty?
90 return nil if name.nil? || name.empty?
91 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
91 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
92 return e if e
92 return e if e
93 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
93 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
94 end
94 end
95
95
96 def entries(path=nil, identifier=nil)
96 def entries(path=nil, identifier=nil)
97 scm.entries(path,
97 scm.entries(path,
98 identifier,
98 identifier,
99 options = {:report_last_commit => extra_report_last_commit})
99 options = {:report_last_commit => extra_report_last_commit})
100 end
100 end
101
101
102 # With SCMs that have a sequential commit numbering,
102 # With SCMs that have a sequential commit numbering,
103 # such as Subversion and Mercurial,
103 # such as Subversion and Mercurial,
104 # Redmine is able to be clever and only fetch changesets
104 # Redmine is able to be clever and only fetch changesets
105 # going forward from the most recent one it knows about.
105 # going forward from the most recent one it knows about.
106 #
106 #
107 # However, Git does not have a sequential commit numbering.
107 # However, Git does not have a sequential commit numbering.
108 #
108 #
109 # In order to fetch only new adding revisions,
109 # In order to fetch only new adding revisions,
110 # Redmine needs to parse revisions per branch.
110 # Redmine needs to save "heads".
111 # Branch "last_scmid" is for this requirement.
112 #
111 #
113 # In Git and Mercurial, revisions are not in date order.
112 # In Git and Mercurial, revisions are not in date order.
114 # Redmine Mercurial fixed issues.
113 # Redmine Mercurial fixed issues.
115 # * Redmine Takes Too Long On Large Mercurial Repository
114 # * Redmine Takes Too Long On Large Mercurial Repository
116 # http://www.redmine.org/issues/3449
115 # http://www.redmine.org/issues/3449
117 # * Sorting for changesets might go wrong on Mercurial repos
116 # * Sorting for changesets might go wrong on Mercurial repos
118 # http://www.redmine.org/issues/3567
117 # http://www.redmine.org/issues/3567
119 #
118 #
120 # Database revision column is text, so Redmine can not sort by revision.
119 # Database revision column is text, so Redmine can not sort by revision.
121 # Mercurial has revision number, and revision number guarantees revision order.
120 # Mercurial has revision number, and revision number guarantees revision order.
122 # Redmine Mercurial model stored revisions ordered by database id to database.
121 # Redmine Mercurial model stored revisions ordered by database id to database.
123 # So, Redmine Mercurial model can use correct ordering revisions.
122 # So, Redmine Mercurial model can use correct ordering revisions.
124 #
123 #
125 # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10"
124 # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10"
126 # to get limited revisions from old to new.
125 # to get limited revisions from old to new.
127 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
126 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
128 #
127 #
129 # The repository can still be fully reloaded by calling #clear_changesets
128 # The repository can still be fully reloaded by calling #clear_changesets
130 # before fetching changesets (eg. for offline resync)
129 # before fetching changesets (eg. for offline resync)
131 def fetch_changesets
130 def fetch_changesets
132 scm_brs = branches
131 scm_brs = branches
133 return if scm_brs.nil? || scm_brs.empty?
132 return if scm_brs.nil? || scm_brs.empty?
133
134 h1 = extra_info || {}
134 h1 = extra_info || {}
135 h = h1.dup
135 h = h1.dup
136 h["branches"] ||= {}
136 repo_heads = scm_brs.map{ |br| br.scmid }
137 h["heads"] ||= []
138 prev_db_heads = h["heads"].dup
139 if prev_db_heads.empty?
140 prev_db_heads += heads_from_branches_hash
141 end
142 return if prev_db_heads.sort == repo_heads.sort
143
137 h["db_consistent"] ||= {}
144 h["db_consistent"] ||= {}
138 if changesets.count == 0
145 if changesets.count == 0
139 h["db_consistent"]["ordering"] = 1
146 h["db_consistent"]["ordering"] = 1
140 merge_extra_info(h)
147 merge_extra_info(h)
141 self.save
148 self.save
142 elsif ! h["db_consistent"].has_key?("ordering")
149 elsif ! h["db_consistent"].has_key?("ordering")
143 h["db_consistent"]["ordering"] = 0
150 h["db_consistent"]["ordering"] = 0
144 merge_extra_info(h)
151 merge_extra_info(h)
145 self.save
152 self.save
146 end
153 end
147 save_revisions(h, scm_brs)
154 save_revisions(prev_db_heads, repo_heads)
148 end
155 end
149
156
150 def save_revisions(h, scm_brs)
157 def save_revisions(prev_db_heads, repo_heads)
151 # Remember what revisions we already processed (in any branches)
158 h = {}
152 all_revisions = []
159 opts = {}
153 scm_brs.each do |br1|
160 opts[:reverse] = true
154 br = br1.to_s
161 opts[:excludes] = prev_db_heads
155 last_revision = nil
162 opts[:includes] = repo_heads
156 from_scmid = nil
157 from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
158 h["branches"][br] ||= {}
159
160 revisions = scm.revisions('', from_scmid, br, {:reverse => true})
161 next if revisions.blank?
162
163 # Remember the last commit id here, before we start removing revisions from the array.
164 # We'll do that for optimization, but it also means, that we may lose even all revisions.
165 last_revision = revisions.last
166
163
167 # remove revisions that we have already processed (possibly in other branches)
164 revisions = scm.revisions('', nil, nil, opts)
168 revisions.reject!{|r| all_revisions.include?(r.scmid)}
165 return if revisions.blank?
169 # add revisions that we are to parse now to 'all processed revisions'
170 # (this equals to a union, because we executed diff above)
171 all_revisions += revisions.map{|r| r.scmid}
172
166
173 # Make the search for existing revisions in the database in a more sufficient manner
167 # Make the search for existing revisions in the database in a more sufficient manner
174 # This is replacing the one-after-one queries.
168 # This is replacing the one-after-one queries.
175 # Find all revisions, that are in the database, and then remove them from the revision array.
169 # Find all revisions, that are in the database, and then remove them from the revision array.
176 # Then later we won't need any conditions for db existence.
170 # Then later we won't need any conditions for db existence.
177 # Query for several revisions at once, and remove them from the revisions array, if they are there.
171 # Query for several revisions at once, and remove them from the revisions array, if they are there.
178 # Do this in chunks, to avoid eventual memory problems (in case of tens of thousands of commits).
172 # Do this in chunks, to avoid eventual memory problems (in case of tens of thousands of commits).
179 # If there are no revisions (because the original code's algoritm filtered them),
173 # If there are no revisions (because the original code's algoritm filtered them),
180 # then this part will be stepped over.
174 # then this part will be stepped over.
181 # We make queries, just if there is any revision.
175 # We make queries, just if there is any revision.
182 limit = 100
176 limit = 100
183 offset = 0
177 offset = 0
184 revisions_copy = revisions.clone # revisions will change
178 revisions_copy = revisions.clone # revisions will change
185 while offset < revisions_copy.size
179 while offset < revisions_copy.size
186 recent_changesets_slice = changesets.find(
180 recent_changesets_slice = changesets.find(
187 :all,
181 :all,
188 :conditions => [
182 :conditions => [
189 'scmid IN (?)',
183 'scmid IN (?)',
190 revisions_copy.slice(offset, limit).map{|x| x.scmid}
184 revisions_copy.slice(offset, limit).map{|x| x.scmid}
191 ]
185 ]
192 )
186 )
193 # Subtract revisions that redmine already knows about
187 # Subtract revisions that redmine already knows about
194 recent_revisions = recent_changesets_slice.map{|c| c.scmid}
188 recent_revisions = recent_changesets_slice.map{|c| c.scmid}
195 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
189 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
196 offset += limit
190 offset += limit
197 end
191 end
198
192
199 revisions.each do |rev|
193 revisions.each do |rev|
200 transaction do
194 transaction do
201 # There is no search in the db for this revision, because above we ensured,
195 # There is no search in the db for this revision, because above we ensured,
202 # that it's not in the db.
196 # that it's not in the db.
203 db_saved_rev = save_revision(rev)
197 db_saved_rev = save_revision(rev)
204 parents = {}
198 parents = {}
205 parents[db_saved_rev] = rev.parents unless rev.parents.nil?
199 parents[db_saved_rev] = rev.parents unless rev.parents.nil?
206 parents.each do |ch, chparents|
200 parents.each do |ch, chparents|
207 ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact
201 ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact
208 end
202 end
209 # saving the last scmid was moved from here, because we won't come in here,
210 # if the revision was already added for another branch
211 end
203 end
212 end
204 end
213
205 h["heads"] = repo_heads.dup
214 # save the data about the last revision for this branch
206 merge_extra_info(h)
215 unless last_revision.nil?
207 self.save
216 h["branches"][br]["last_scmid"] = last_revision.scmid
217 merge_extra_info(h)
218 self.save
219 end
220 end
221 end
208 end
222 private :save_revisions
209 private :save_revisions
223
210
224 def save_revision(rev)
211 def save_revision(rev)
225 changeset = Changeset.new(
212 changeset = Changeset.new(
226 :repository => self,
213 :repository => self,
227 :revision => rev.identifier,
214 :revision => rev.identifier,
228 :scmid => rev.scmid,
215 :scmid => rev.scmid,
229 :committer => rev.author,
216 :committer => rev.author,
230 :committed_on => rev.time,
217 :committed_on => rev.time,
231 :comments => rev.message
218 :comments => rev.message
232 )
219 )
233 if changeset.save
220 if changeset.save
234 rev.paths.each do |file|
221 rev.paths.each do |file|
235 Change.create(
222 Change.create(
236 :changeset => changeset,
223 :changeset => changeset,
237 :action => file[:action],
224 :action => file[:action],
238 :path => file[:path])
225 :path => file[:path])
239 end
226 end
240 end
227 end
241 changeset
228 changeset
242 end
229 end
243 private :save_revision
230 private :save_revision
244
231
245 def heads_from_branches_hash
232 def heads_from_branches_hash
246 h1 = extra_info || {}
233 h1 = extra_info || {}
247 h = h1.dup
234 h = h1.dup
248 h["branches"] ||= {}
235 h["branches"] ||= {}
249 h['branches'].map{|br, hs| hs['last_scmid']}
236 h['branches'].map{|br, hs| hs['last_scmid']}
250 end
237 end
251
238
252 def latest_changesets(path,rev,limit=10)
239 def latest_changesets(path,rev,limit=10)
253 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
240 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
254 return [] if revisions.nil? || revisions.empty?
241 return [] if revisions.nil? || revisions.empty?
255
242
256 changesets.find(
243 changesets.find(
257 :all,
244 :all,
258 :conditions => [
245 :conditions => [
259 "scmid IN (?)",
246 "scmid IN (?)",
260 revisions.map!{|c| c.scmid}
247 revisions.map!{|c| c.scmid}
261 ],
248 ],
262 :order => 'committed_on DESC'
249 :order => 'committed_on DESC'
263 )
250 )
264 end
251 end
265 end
252 end
@@ -1,547 +1,555
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RepositoryGitTest < ActiveSupport::TestCase
20 class RepositoryGitTest < ActiveSupport::TestCase
21 fixtures :projects, :repositories, :enabled_modules, :users, :roles
21 fixtures :projects, :repositories, :enabled_modules, :users, :roles
22
22
23 include Redmine::I18n
23 include Redmine::I18n
24
24
25 REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
25 REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
26 REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
26 REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
27
27
28 NUM_REV = 28
28 NUM_REV = 28
29 NUM_HEAD = 6
29 NUM_HEAD = 6
30
30
31 FELIX_HEX = "Felix Sch\xC3\xA4fer"
31 FELIX_HEX = "Felix Sch\xC3\xA4fer"
32 CHAR_1_HEX = "\xc3\x9c"
32 CHAR_1_HEX = "\xc3\x9c"
33
33
34 ## Ruby uses ANSI api to fork a process on Windows.
34 ## Ruby uses ANSI api to fork a process on Windows.
35 ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
35 ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
36 ## and these are incompatible with ASCII.
36 ## and these are incompatible with ASCII.
37 # WINDOWS_PASS = Redmine::Platform.mswin?
37 # WINDOWS_PASS = Redmine::Platform.mswin?
38 WINDOWS_PASS = false
38 WINDOWS_PASS = false
39
39
40 ## Git, Mercurial and CVS path encodings are binary.
40 ## Git, Mercurial and CVS path encodings are binary.
41 ## Subversion supports URL encoding for path.
41 ## Subversion supports URL encoding for path.
42 ## Redmine Mercurial adapter and extension use URL encoding.
42 ## Redmine Mercurial adapter and extension use URL encoding.
43 ## Git accepts only binary path in command line parameter.
43 ## Git accepts only binary path in command line parameter.
44 ## So, there is no way to use binary command line parameter in JRuby.
44 ## So, there is no way to use binary command line parameter in JRuby.
45 JRUBY_SKIP = (RUBY_PLATFORM == 'java')
45 JRUBY_SKIP = (RUBY_PLATFORM == 'java')
46 JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
46 JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
47
47
48 def setup
48 def setup
49 @project = Project.find(3)
49 @project = Project.find(3)
50 @repository = Repository::Git.create(
50 @repository = Repository::Git.create(
51 :project => @project,
51 :project => @project,
52 :url => REPOSITORY_PATH,
52 :url => REPOSITORY_PATH,
53 :path_encoding => 'ISO-8859-1'
53 :path_encoding => 'ISO-8859-1'
54 )
54 )
55 assert @repository
55 assert @repository
56 @char_1 = CHAR_1_HEX.dup
56 @char_1 = CHAR_1_HEX.dup
57 if @char_1.respond_to?(:force_encoding)
57 if @char_1.respond_to?(:force_encoding)
58 @char_1.force_encoding('UTF-8')
58 @char_1.force_encoding('UTF-8')
59 end
59 end
60 end
60 end
61
61
62 def test_blank_path_to_repository_error_message
62 def test_blank_path_to_repository_error_message
63 set_language_if_valid 'en'
63 set_language_if_valid 'en'
64 repo = Repository::Git.new(
64 repo = Repository::Git.new(
65 :project => @project,
65 :project => @project,
66 :identifier => 'test'
66 :identifier => 'test'
67 )
67 )
68 assert !repo.save
68 assert !repo.save
69 assert_include "Path to repository can't be blank",
69 assert_include "Path to repository can't be blank",
70 repo.errors.full_messages
70 repo.errors.full_messages
71 end
71 end
72
72
73 def test_blank_path_to_repository_error_message_fr
73 def test_blank_path_to_repository_error_message_fr
74 set_language_if_valid 'fr'
74 set_language_if_valid 'fr'
75 str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
75 str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
76 str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
76 str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
77 repo = Repository::Git.new(
77 repo = Repository::Git.new(
78 :project => @project,
78 :project => @project,
79 :url => "",
79 :url => "",
80 :identifier => 'test',
80 :identifier => 'test',
81 :path_encoding => ''
81 :path_encoding => ''
82 )
82 )
83 assert !repo.save
83 assert !repo.save
84 assert_include str, repo.errors.full_messages
84 assert_include str, repo.errors.full_messages
85 end
85 end
86
86
87 if File.directory?(REPOSITORY_PATH)
87 if File.directory?(REPOSITORY_PATH)
88 def test_scm_available
88 def test_scm_available
89 klass = Repository::Git
89 klass = Repository::Git
90 assert_equal "Git", klass.scm_name
90 assert_equal "Git", klass.scm_name
91 assert klass.scm_adapter_class
91 assert klass.scm_adapter_class
92 assert_not_equal "", klass.scm_command
92 assert_not_equal "", klass.scm_command
93 assert_equal true, klass.scm_available
93 assert_equal true, klass.scm_available
94 end
94 end
95
95
96 def test_fetch_changesets_from_scratch
96 def test_fetch_changesets_from_scratch
97 assert_nil @repository.extra_info
97 assert_nil @repository.extra_info
98
98
99 assert_equal 0, @repository.changesets.count
99 assert_equal 0, @repository.changesets.count
100 @repository.fetch_changesets
100 @repository.fetch_changesets
101 @project.reload
101 @project.reload
102
102
103 assert_equal NUM_REV, @repository.changesets.count
103 assert_equal NUM_REV, @repository.changesets.count
104 assert_equal 39, @repository.changes.count
104 assert_equal 39, @repository.changes.count
105
105
106 commit = @repository.changesets.find_by_revision("7234cb2750b63f47bff735edc50a1c0a433c2518")
106 commit = @repository.changesets.find_by_revision("7234cb2750b63f47bff735edc50a1c0a433c2518")
107 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.scmid
107 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.scmid
108 assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
108 assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
109 assert_equal "jsmith <jsmith@foo.bar>", commit.committer
109 assert_equal "jsmith <jsmith@foo.bar>", commit.committer
110 assert_equal User.find_by_login('jsmith'), commit.user
110 assert_equal User.find_by_login('jsmith'), commit.user
111 # TODO: add a commit with commit time <> author time to the test repository
111 # TODO: add a commit with commit time <> author time to the test repository
112 assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
112 assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
113 assert_equal "2007-12-14".to_date, commit.commit_date
113 assert_equal "2007-12-14".to_date, commit.commit_date
114 assert_equal 3, commit.changes.count
114 assert_equal 3, commit.changes.count
115 change = commit.changes.sort_by(&:path).first
115 change = commit.changes.sort_by(&:path).first
116 assert_equal "README", change.path
116 assert_equal "README", change.path
117 assert_equal "A", change.action
117 assert_equal "A", change.action
118
118
119 assert_equal NUM_HEAD, @repository.extra_info["branches"].size
119 assert_equal NUM_HEAD, @repository.extra_info["heads"].size
120 end
120 end
121
121
122 def test_fetch_changesets_incremental
122 def test_fetch_changesets_incremental
123 assert_equal 0, @repository.changesets.count
123 assert_equal 0, @repository.changesets.count
124 @repository.fetch_changesets
124 @repository.fetch_changesets
125 @project.reload
125 @project.reload
126 assert_equal NUM_REV, @repository.changesets.count
126 assert_equal NUM_REV, @repository.changesets.count
127 extra_info_db = @repository.extra_info["branches"]
127 extra_info_heads = @repository.extra_info["heads"].dup
128 assert_equal "1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127",
128 assert_equal NUM_HEAD, extra_info_heads.size
129 extra_info_db["latin-1-path-encoding"]["last_scmid"]
129 extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
130 assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
130 assert_equal 4, extra_info_heads.size
131 extra_info_db["master"]["last_scmid"]
131
132 del_revs = [
132 del_revs = [
133 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
133 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
134 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
134 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
135 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
135 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
136 "deff712f05a90d96edbd70facc47d944be5897e3",
136 "deff712f05a90d96edbd70facc47d944be5897e3",
137 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
137 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
138 "7e61ac704deecde634b51e59daa8110435dcb3da",
138 "7e61ac704deecde634b51e59daa8110435dcb3da",
139 ]
139 ]
140 @repository.changesets.each do |rev|
140 @repository.changesets.each do |rev|
141 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
141 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
142 end
142 end
143 @project.reload
143 @project.reload
144 cs1 = @repository.changesets
144 cs1 = @repository.changesets
145 assert_equal 22, cs1.count
145 assert_equal NUM_REV - 6, cs1.count
146 h = @repository.extra_info.dup
146 extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
147 h["branches"]["master"]["last_scmid"] =
147 h = {}
148 "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
148 h["heads"] = extra_info_heads
149 @repository.merge_extra_info(h)
149 @repository.merge_extra_info(h)
150 @repository.save
150 @repository.save
151 @project.reload
151 @project.reload
152 extra_info_db_1 = @repository.extra_info["branches"]
152 assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
153 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
154 extra_info_db_1["master"]["last_scmid"]
155
156 @repository.fetch_changesets
153 @repository.fetch_changesets
157 @project.reload
154 @project.reload
158 assert_equal NUM_REV, @repository.changesets.count
155 assert_equal NUM_REV, @repository.changesets.count
156 assert_equal NUM_HEAD, @repository.extra_info["heads"].size
157 assert @repository.extra_info["heads"].index("83ca5fd546063a3c7dc2e568ba3355661a9e2b2c")
159 end
158 end
160
159
161 def test_fetch_changesets_history_editing
160 def test_fetch_changesets_history_editing
162 assert_equal 0, @repository.changesets.count
161 assert_equal 0, @repository.changesets.count
163 @repository.fetch_changesets
162 @repository.fetch_changesets
164 @project.reload
163 @project.reload
165 assert_equal NUM_REV, @repository.changesets.count
164 assert_equal NUM_REV, @repository.changesets.count
166 assert_equal NUM_HEAD, @repository.extra_info["branches"].size
165 extra_info_heads = @repository.extra_info["heads"].dup
167 assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
166 assert_equal NUM_HEAD, extra_info_heads.size
168 @repository.extra_info["branches"]["master"]["last_scmid"]
167 extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
168 assert_equal 4, extra_info_heads.size
169
169 del_revs = [
170 del_revs = [
170 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
171 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
171 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
172 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
172 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
173 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
173 "deff712f05a90d96edbd70facc47d944be5897e3",
174 "deff712f05a90d96edbd70facc47d944be5897e3",
174 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
175 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
175 "7e61ac704deecde634b51e59daa8110435dcb3da",
176 "7e61ac704deecde634b51e59daa8110435dcb3da",
176 ]
177 ]
177 @repository.changesets.each do |rev|
178 @repository.changesets.each do |rev|
178 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
179 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
179 end
180 end
180 @project.reload
181 @project.reload
181 assert_equal NUM_REV - 6, @repository.changesets.count
182 assert_equal NUM_REV - 6, @repository.changesets.count
182
183
183 c = Changeset.new(:repository => @repository,
184 c = Changeset.new(:repository => @repository,
184 :committed_on => Time.now,
185 :committed_on => Time.now,
185 :revision => "abcd1234efgh",
186 :revision => "abcd1234efgh",
186 :scmid => "abcd1234efgh",
187 :scmid => "abcd1234efgh",
187 :comments => 'test')
188 :comments => 'test')
188 assert c.save
189 assert c.save
189 @project.reload
190 @project.reload
190 assert_equal NUM_REV - 5, @repository.changesets.count
191 assert_equal NUM_REV - 5, @repository.changesets.count
191
192
192 h = @repository.extra_info.dup
193 extra_info_heads << "abcd1234efgh"
193 h["branches"]["master"]["last_scmid"] = "abcd1234efgh"
194 h = {}
195 h["heads"] = extra_info_heads
194 @repository.merge_extra_info(h)
196 @repository.merge_extra_info(h)
195 @repository.save
197 @repository.save
196 @project.reload
198 @project.reload
197 assert_equal "abcd1234efgh",
199 h1 = @repository.extra_info["heads"].dup
198 @repository.extra_info["branches"]["master"]["last_scmid"]
200 assert h1.index("abcd1234efgh")
201 assert_equal 5, h1.size
199
202
200 @repository.fetch_changesets
203 @repository.fetch_changesets
201 @project.reload
204 @project.reload
202 assert_equal NUM_REV - 5, @repository.changesets.count
205 assert_equal NUM_REV - 5, @repository.changesets.count
206 h2 = @repository.extra_info["heads"].dup
207 assert_equal h1, h2
203 end
208 end
204
209
205 def test_parents
210 def test_parents
206 assert_equal 0, @repository.changesets.count
211 assert_equal 0, @repository.changesets.count
207 @repository.fetch_changesets
212 @repository.fetch_changesets
208 @project.reload
213 @project.reload
209 assert_equal NUM_REV, @repository.changesets.count
214 assert_equal NUM_REV, @repository.changesets.count
210 r1 = @repository.find_changeset_by_name("7234cb2750b63")
215 r1 = @repository.find_changeset_by_name("7234cb2750b63")
211 assert_equal [], r1.parents
216 assert_equal [], r1.parents
212 r2 = @repository.find_changeset_by_name("899a15dba03a3")
217 r2 = @repository.find_changeset_by_name("899a15dba03a3")
213 assert_equal 1, r2.parents.length
218 assert_equal 1, r2.parents.length
214 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
219 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
215 r2.parents[0].identifier
220 r2.parents[0].identifier
216 r3 = @repository.find_changeset_by_name("32ae898b720c2")
221 r3 = @repository.find_changeset_by_name("32ae898b720c2")
217 assert_equal 2, r3.parents.length
222 assert_equal 2, r3.parents.length
218 r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
223 r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
219 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", r4[0]
224 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", r4[0]
220 assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", r4[1]
225 assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", r4[1]
221 end
226 end
222
227
223 def test_db_consistent_ordering_init
228 def test_db_consistent_ordering_init
224 assert_nil @repository.extra_info
229 assert_nil @repository.extra_info
225 assert_equal 0, @repository.changesets.count
230 assert_equal 0, @repository.changesets.count
226 @repository.fetch_changesets
231 @repository.fetch_changesets
227 @project.reload
232 @project.reload
228 assert_equal 1, @repository.extra_info["db_consistent"]["ordering"]
233 assert_equal 1, @repository.extra_info["db_consistent"]["ordering"]
229 end
234 end
230
235
231 def test_db_consistent_ordering_before_1_2
236 def test_db_consistent_ordering_before_1_2
232 assert_nil @repository.extra_info
237 assert_nil @repository.extra_info
233 assert_equal 0, @repository.changesets.count
238 assert_equal 0, @repository.changesets.count
234 @repository.fetch_changesets
239 @repository.fetch_changesets
235 @project.reload
240 @project.reload
236 assert_equal NUM_REV, @repository.changesets.count
241 assert_equal NUM_REV, @repository.changesets.count
237 assert_not_nil @repository.extra_info
242 assert_not_nil @repository.extra_info
238 h = {}
243 h = {}
239 h["heads"] = []
244 h["heads"] = []
240 h["branches"] = {}
245 h["branches"] = {}
241 h["db_consistent"] = {}
246 h["db_consistent"] = {}
242 @repository.merge_extra_info(h)
247 @repository.merge_extra_info(h)
243 @repository.save
248 @repository.save
244 assert_equal NUM_REV, @repository.changesets.count
249 assert_equal NUM_REV, @repository.changesets.count
245 @repository.fetch_changesets
250 @repository.fetch_changesets
246 @project.reload
251 @project.reload
247 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
252 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
248
253
254 extra_info_heads = @repository.extra_info["heads"].dup
255 extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
249 del_revs = [
256 del_revs = [
250 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
257 "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
251 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
258 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
252 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
259 "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
253 "deff712f05a90d96edbd70facc47d944be5897e3",
260 "deff712f05a90d96edbd70facc47d944be5897e3",
254 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
261 "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
255 "7e61ac704deecde634b51e59daa8110435dcb3da",
262 "7e61ac704deecde634b51e59daa8110435dcb3da",
256 ]
263 ]
257 @repository.changesets.each do |rev|
264 @repository.changesets.each do |rev|
258 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
265 rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
259 end
266 end
260 @project.reload
267 @project.reload
261 cs1 = @repository.changesets
268 cs1 = @repository.changesets
262 assert_equal NUM_REV - 6, cs1.count
269 assert_equal NUM_REV - 6, cs1.count
263 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
270 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
264 h = @repository.extra_info.dup
271
265 h["branches"]["master"]["last_scmid"] =
272 extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
266 "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
273 h = {}
274 h["heads"] = extra_info_heads
267 @repository.merge_extra_info(h)
275 @repository.merge_extra_info(h)
268 @repository.save
276 @repository.save
269 @project.reload
277 @project.reload
270 extra_info_db_1 = @repository.extra_info["branches"]
278 assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
271 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
272 extra_info_db_1["master"]["last_scmid"]
273
274 @repository.fetch_changesets
279 @repository.fetch_changesets
280 @project.reload
275 assert_equal NUM_REV, @repository.changesets.count
281 assert_equal NUM_REV, @repository.changesets.count
282 assert_equal NUM_HEAD, @repository.extra_info["heads"].size
283
276 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
284 assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
277 end
285 end
278
286
279 def test_heads_from_branches_hash
287 def test_heads_from_branches_hash
280 assert_nil @repository.extra_info
288 assert_nil @repository.extra_info
281 assert_equal 0, @repository.changesets.count
289 assert_equal 0, @repository.changesets.count
282 assert_equal [], @repository.heads_from_branches_hash
290 assert_equal [], @repository.heads_from_branches_hash
283 h = {}
291 h = {}
284 h["branches"] = {}
292 h["branches"] = {}
285 h["branches"]["test1"] = {}
293 h["branches"]["test1"] = {}
286 h["branches"]["test1"]["last_scmid"] = "1234abcd"
294 h["branches"]["test1"]["last_scmid"] = "1234abcd"
287 h["branches"]["test2"] = {}
295 h["branches"]["test2"] = {}
288 h["branches"]["test2"]["last_scmid"] = "abcd1234"
296 h["branches"]["test2"]["last_scmid"] = "abcd1234"
289 @repository.merge_extra_info(h)
297 @repository.merge_extra_info(h)
290 @repository.save
298 @repository.save
291 @project.reload
299 @project.reload
292 assert_equal ["1234abcd", "abcd1234"], @repository.heads_from_branches_hash.sort
300 assert_equal ["1234abcd", "abcd1234"], @repository.heads_from_branches_hash.sort
293 end
301 end
294
302
295 def test_latest_changesets
303 def test_latest_changesets
296 assert_equal 0, @repository.changesets.count
304 assert_equal 0, @repository.changesets.count
297 @repository.fetch_changesets
305 @repository.fetch_changesets
298 @project.reload
306 @project.reload
299 assert_equal NUM_REV, @repository.changesets.count
307 assert_equal NUM_REV, @repository.changesets.count
300 # with limit
308 # with limit
301 changesets = @repository.latest_changesets('', 'master', 2)
309 changesets = @repository.latest_changesets('', 'master', 2)
302 assert_equal 2, changesets.size
310 assert_equal 2, changesets.size
303
311
304 # with path
312 # with path
305 changesets = @repository.latest_changesets('images', 'master')
313 changesets = @repository.latest_changesets('images', 'master')
306 assert_equal [
314 assert_equal [
307 'deff712f05a90d96edbd70facc47d944be5897e3',
315 'deff712f05a90d96edbd70facc47d944be5897e3',
308 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
316 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
309 '7234cb2750b63f47bff735edc50a1c0a433c2518',
317 '7234cb2750b63f47bff735edc50a1c0a433c2518',
310 ], changesets.collect(&:revision)
318 ], changesets.collect(&:revision)
311
319
312 changesets = @repository.latest_changesets('README', nil)
320 changesets = @repository.latest_changesets('README', nil)
313 assert_equal [
321 assert_equal [
314 '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf',
322 '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf',
315 '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8',
323 '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8',
316 '713f4944648826f558cf548222f813dabe7cbb04',
324 '713f4944648826f558cf548222f813dabe7cbb04',
317 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
325 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
318 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
326 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
319 '7234cb2750b63f47bff735edc50a1c0a433c2518',
327 '7234cb2750b63f47bff735edc50a1c0a433c2518',
320 ], changesets.collect(&:revision)
328 ], changesets.collect(&:revision)
321
329
322 # with path, revision and limit
330 # with path, revision and limit
323 changesets = @repository.latest_changesets('images', '899a15dba')
331 changesets = @repository.latest_changesets('images', '899a15dba')
324 assert_equal [
332 assert_equal [
325 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
333 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
326 '7234cb2750b63f47bff735edc50a1c0a433c2518',
334 '7234cb2750b63f47bff735edc50a1c0a433c2518',
327 ], changesets.collect(&:revision)
335 ], changesets.collect(&:revision)
328
336
329 changesets = @repository.latest_changesets('images', '899a15dba', 1)
337 changesets = @repository.latest_changesets('images', '899a15dba', 1)
330 assert_equal [
338 assert_equal [
331 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
339 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
332 ], changesets.collect(&:revision)
340 ], changesets.collect(&:revision)
333
341
334 changesets = @repository.latest_changesets('README', '899a15dba')
342 changesets = @repository.latest_changesets('README', '899a15dba')
335 assert_equal [
343 assert_equal [
336 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
344 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
337 '7234cb2750b63f47bff735edc50a1c0a433c2518',
345 '7234cb2750b63f47bff735edc50a1c0a433c2518',
338 ], changesets.collect(&:revision)
346 ], changesets.collect(&:revision)
339
347
340 changesets = @repository.latest_changesets('README', '899a15dba', 1)
348 changesets = @repository.latest_changesets('README', '899a15dba', 1)
341 assert_equal [
349 assert_equal [
342 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
350 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
343 ], changesets.collect(&:revision)
351 ], changesets.collect(&:revision)
344
352
345 # with path, tag and limit
353 # with path, tag and limit
346 changesets = @repository.latest_changesets('images', 'tag01.annotated')
354 changesets = @repository.latest_changesets('images', 'tag01.annotated')
347 assert_equal [
355 assert_equal [
348 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
356 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
349 '7234cb2750b63f47bff735edc50a1c0a433c2518',
357 '7234cb2750b63f47bff735edc50a1c0a433c2518',
350 ], changesets.collect(&:revision)
358 ], changesets.collect(&:revision)
351
359
352 changesets = @repository.latest_changesets('images', 'tag01.annotated', 1)
360 changesets = @repository.latest_changesets('images', 'tag01.annotated', 1)
353 assert_equal [
361 assert_equal [
354 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
362 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
355 ], changesets.collect(&:revision)
363 ], changesets.collect(&:revision)
356
364
357 changesets = @repository.latest_changesets('README', 'tag01.annotated')
365 changesets = @repository.latest_changesets('README', 'tag01.annotated')
358 assert_equal [
366 assert_equal [
359 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
367 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
360 '7234cb2750b63f47bff735edc50a1c0a433c2518',
368 '7234cb2750b63f47bff735edc50a1c0a433c2518',
361 ], changesets.collect(&:revision)
369 ], changesets.collect(&:revision)
362
370
363 changesets = @repository.latest_changesets('README', 'tag01.annotated', 1)
371 changesets = @repository.latest_changesets('README', 'tag01.annotated', 1)
364 assert_equal [
372 assert_equal [
365 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
373 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
366 ], changesets.collect(&:revision)
374 ], changesets.collect(&:revision)
367
375
368 # with path, branch and limit
376 # with path, branch and limit
369 changesets = @repository.latest_changesets('images', 'test_branch')
377 changesets = @repository.latest_changesets('images', 'test_branch')
370 assert_equal [
378 assert_equal [
371 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
379 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
372 '7234cb2750b63f47bff735edc50a1c0a433c2518',
380 '7234cb2750b63f47bff735edc50a1c0a433c2518',
373 ], changesets.collect(&:revision)
381 ], changesets.collect(&:revision)
374
382
375 changesets = @repository.latest_changesets('images', 'test_branch', 1)
383 changesets = @repository.latest_changesets('images', 'test_branch', 1)
376 assert_equal [
384 assert_equal [
377 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
385 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
378 ], changesets.collect(&:revision)
386 ], changesets.collect(&:revision)
379
387
380 changesets = @repository.latest_changesets('README', 'test_branch')
388 changesets = @repository.latest_changesets('README', 'test_branch')
381 assert_equal [
389 assert_equal [
382 '713f4944648826f558cf548222f813dabe7cbb04',
390 '713f4944648826f558cf548222f813dabe7cbb04',
383 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
391 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
384 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
392 '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
385 '7234cb2750b63f47bff735edc50a1c0a433c2518',
393 '7234cb2750b63f47bff735edc50a1c0a433c2518',
386 ], changesets.collect(&:revision)
394 ], changesets.collect(&:revision)
387
395
388 changesets = @repository.latest_changesets('README', 'test_branch', 2)
396 changesets = @repository.latest_changesets('README', 'test_branch', 2)
389 assert_equal [
397 assert_equal [
390 '713f4944648826f558cf548222f813dabe7cbb04',
398 '713f4944648826f558cf548222f813dabe7cbb04',
391 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
399 '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
392 ], changesets.collect(&:revision)
400 ], changesets.collect(&:revision)
393
401
394 if JRUBY_SKIP
402 if JRUBY_SKIP
395 puts JRUBY_SKIP_STR
403 puts JRUBY_SKIP_STR
396 else
404 else
397 # latin-1 encoding path
405 # latin-1 encoding path
398 changesets = @repository.latest_changesets(
406 changesets = @repository.latest_changesets(
399 "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89')
407 "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89')
400 assert_equal [
408 assert_equal [
401 '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
409 '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
402 '4fc55c43bf3d3dc2efb66145365ddc17639ce81e',
410 '4fc55c43bf3d3dc2efb66145365ddc17639ce81e',
403 ], changesets.collect(&:revision)
411 ], changesets.collect(&:revision)
404
412
405 changesets = @repository.latest_changesets(
413 changesets = @repository.latest_changesets(
406 "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1)
414 "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1)
407 assert_equal [
415 assert_equal [
408 '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
416 '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
409 ], changesets.collect(&:revision)
417 ], changesets.collect(&:revision)
410 end
418 end
411 end
419 end
412
420
413 def test_latest_changesets_latin_1_dir
421 def test_latest_changesets_latin_1_dir
414 if WINDOWS_PASS
422 if WINDOWS_PASS
415 #
423 #
416 elsif JRUBY_SKIP
424 elsif JRUBY_SKIP
417 puts JRUBY_SKIP_STR
425 puts JRUBY_SKIP_STR
418 else
426 else
419 assert_equal 0, @repository.changesets.count
427 assert_equal 0, @repository.changesets.count
420 @repository.fetch_changesets
428 @repository.fetch_changesets
421 @project.reload
429 @project.reload
422 assert_equal NUM_REV, @repository.changesets.count
430 assert_equal NUM_REV, @repository.changesets.count
423 changesets = @repository.latest_changesets(
431 changesets = @repository.latest_changesets(
424 "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed')
432 "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed')
425 assert_equal [
433 assert_equal [
426 '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127',
434 '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127',
427 ], changesets.collect(&:revision)
435 ], changesets.collect(&:revision)
428 end
436 end
429 end
437 end
430
438
431 def test_find_changeset_by_name
439 def test_find_changeset_by_name
432 assert_equal 0, @repository.changesets.count
440 assert_equal 0, @repository.changesets.count
433 @repository.fetch_changesets
441 @repository.fetch_changesets
434 @project.reload
442 @project.reload
435 assert_equal NUM_REV, @repository.changesets.count
443 assert_equal NUM_REV, @repository.changesets.count
436 ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r|
444 ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r|
437 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518',
445 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518',
438 @repository.find_changeset_by_name(r).revision
446 @repository.find_changeset_by_name(r).revision
439 end
447 end
440 end
448 end
441
449
442 def test_find_changeset_by_empty_name
450 def test_find_changeset_by_empty_name
443 assert_equal 0, @repository.changesets.count
451 assert_equal 0, @repository.changesets.count
444 @repository.fetch_changesets
452 @repository.fetch_changesets
445 @project.reload
453 @project.reload
446 assert_equal NUM_REV, @repository.changesets.count
454 assert_equal NUM_REV, @repository.changesets.count
447 ['', ' ', nil].each do |r|
455 ['', ' ', nil].each do |r|
448 assert_nil @repository.find_changeset_by_name(r)
456 assert_nil @repository.find_changeset_by_name(r)
449 end
457 end
450 end
458 end
451
459
452 def test_identifier
460 def test_identifier
453 assert_equal 0, @repository.changesets.count
461 assert_equal 0, @repository.changesets.count
454 @repository.fetch_changesets
462 @repository.fetch_changesets
455 @project.reload
463 @project.reload
456 assert_equal NUM_REV, @repository.changesets.count
464 assert_equal NUM_REV, @repository.changesets.count
457 c = @repository.changesets.find_by_revision(
465 c = @repository.changesets.find_by_revision(
458 '7234cb2750b63f47bff735edc50a1c0a433c2518')
466 '7234cb2750b63f47bff735edc50a1c0a433c2518')
459 assert_equal c.scmid, c.identifier
467 assert_equal c.scmid, c.identifier
460 end
468 end
461
469
462 def test_format_identifier
470 def test_format_identifier
463 assert_equal 0, @repository.changesets.count
471 assert_equal 0, @repository.changesets.count
464 @repository.fetch_changesets
472 @repository.fetch_changesets
465 @project.reload
473 @project.reload
466 assert_equal NUM_REV, @repository.changesets.count
474 assert_equal NUM_REV, @repository.changesets.count
467 c = @repository.changesets.find_by_revision(
475 c = @repository.changesets.find_by_revision(
468 '7234cb2750b63f47bff735edc50a1c0a433c2518')
476 '7234cb2750b63f47bff735edc50a1c0a433c2518')
469 assert_equal '7234cb27', c.format_identifier
477 assert_equal '7234cb27', c.format_identifier
470 end
478 end
471
479
472 def test_activities
480 def test_activities
473 c = Changeset.new(:repository => @repository,
481 c = Changeset.new(:repository => @repository,
474 :committed_on => Time.now,
482 :committed_on => Time.now,
475 :revision => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
483 :revision => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
476 :scmid => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
484 :scmid => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
477 :comments => 'test')
485 :comments => 'test')
478 assert c.event_title.include?('abc7234c:')
486 assert c.event_title.include?('abc7234c:')
479 assert_equal 'abc7234cb2750b63f47bff735edc50a1c0a433c2', c.event_url[:rev]
487 assert_equal 'abc7234cb2750b63f47bff735edc50a1c0a433c2', c.event_url[:rev]
480 end
488 end
481
489
482 def test_log_utf8
490 def test_log_utf8
483 assert_equal 0, @repository.changesets.count
491 assert_equal 0, @repository.changesets.count
484 @repository.fetch_changesets
492 @repository.fetch_changesets
485 @project.reload
493 @project.reload
486 assert_equal NUM_REV, @repository.changesets.count
494 assert_equal NUM_REV, @repository.changesets.count
487 str_felix_hex = FELIX_HEX.dup
495 str_felix_hex = FELIX_HEX.dup
488 if str_felix_hex.respond_to?(:force_encoding)
496 if str_felix_hex.respond_to?(:force_encoding)
489 str_felix_hex.force_encoding('UTF-8')
497 str_felix_hex.force_encoding('UTF-8')
490 end
498 end
491 c = @repository.changesets.find_by_revision(
499 c = @repository.changesets.find_by_revision(
492 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b')
500 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b')
493 assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer
501 assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer
494 end
502 end
495
503
496 def test_previous
504 def test_previous
497 assert_equal 0, @repository.changesets.count
505 assert_equal 0, @repository.changesets.count
498 @repository.fetch_changesets
506 @repository.fetch_changesets
499 @project.reload
507 @project.reload
500 assert_equal NUM_REV, @repository.changesets.count
508 assert_equal NUM_REV, @repository.changesets.count
501 %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
509 %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
502 changeset = @repository.find_changeset_by_name(r1)
510 changeset = @repository.find_changeset_by_name(r1)
503 %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
511 %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
504 assert_equal @repository.find_changeset_by_name(r2), changeset.previous
512 assert_equal @repository.find_changeset_by_name(r2), changeset.previous
505 end
513 end
506 end
514 end
507 end
515 end
508
516
509 def test_previous_nil
517 def test_previous_nil
510 assert_equal 0, @repository.changesets.count
518 assert_equal 0, @repository.changesets.count
511 @repository.fetch_changesets
519 @repository.fetch_changesets
512 @project.reload
520 @project.reload
513 assert_equal NUM_REV, @repository.changesets.count
521 assert_equal NUM_REV, @repository.changesets.count
514 %w|95488a44bc25f7d1f97d775a31359539ff333a63 95488a44b|.each do |r1|
522 %w|7234cb2750b63f47bff735edc50a1c0a433c2518 7234cb275|.each do |r1|
515 changeset = @repository.find_changeset_by_name(r1)
523 changeset = @repository.find_changeset_by_name(r1)
516 assert_nil changeset.previous
524 assert_nil changeset.previous
517 end
525 end
518 end
526 end
519
527
520 def test_next
528 def test_next
521 assert_equal 0, @repository.changesets.count
529 assert_equal 0, @repository.changesets.count
522 @repository.fetch_changesets
530 @repository.fetch_changesets
523 @project.reload
531 @project.reload
524 assert_equal NUM_REV, @repository.changesets.count
532 assert_equal NUM_REV, @repository.changesets.count
525 %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
533 %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
526 changeset = @repository.find_changeset_by_name(r2)
534 changeset = @repository.find_changeset_by_name(r2)
527 %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
535 %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
528 assert_equal @repository.find_changeset_by_name(r1), changeset.next
536 assert_equal @repository.find_changeset_by_name(r1), changeset.next
529 end
537 end
530 end
538 end
531 end
539 end
532
540
533 def test_next_nil
541 def test_next_nil
534 assert_equal 0, @repository.changesets.count
542 assert_equal 0, @repository.changesets.count
535 @repository.fetch_changesets
543 @repository.fetch_changesets
536 @project.reload
544 @project.reload
537 assert_equal NUM_REV, @repository.changesets.count
545 assert_equal NUM_REV, @repository.changesets.count
538 %w|67e7792ce20ccae2e4bb73eed09bb397819c8834 67e7792ce20cca|.each do |r1|
546 %w|2a682156a3b6e77a8bf9cd4590e8db757f3c6c78 2a682156a3b6e77a|.each do |r1|
539 changeset = @repository.find_changeset_by_name(r1)
547 changeset = @repository.find_changeset_by_name(r1)
540 assert_nil changeset.next
548 assert_nil changeset.next
541 end
549 end
542 end
550 end
543 else
551 else
544 puts "Git test repository NOT FOUND. Skipping unit tests !!!"
552 puts "Git test repository NOT FOUND. Skipping unit tests !!!"
545 def test_fake; assert true end
553 def test_fake; assert true end
546 end
554 end
547 end
555 end
General Comments 0
You need to be logged in to leave comments. Login now