@@ -148,42 +148,74 class Repository::Git < Repository | |||
|
148 | 148 | end |
|
149 | 149 | |
|
150 | 150 | def save_revisions(h, scm_brs) |
|
151 | # Remember what revisions we already processed (in any branches) | |
|
152 | all_revisions = [] | |
|
151 | 153 | scm_brs.each do |br1| |
|
152 | 154 | br = br1.to_s |
|
155 | last_revision = nil | |
|
153 | 156 | from_scmid = nil |
|
154 | 157 | from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br] |
|
155 | 158 | h["branches"][br] ||= {} |
|
156 | begin | |
|
157 | cnt = 0 | |
|
158 | last_rev_scmid = nil | |
|
159 | scm.revisions('', from_scmid, br, {:reverse => true}) do |rev| | |
|
160 | cnt += 1 | |
|
161 | db_rev = find_changeset_by_name(rev.revision) | |
|
162 | if db_rev.nil? | |
|
163 | transaction do | |
|
164 | db_saved_rev = save_revision(rev) | |
|
165 | parents = {} | |
|
166 | parents[db_saved_rev] = rev.parents unless rev.parents.nil? | |
|
167 | parents.each do |ch, chparents| | |
|
168 | ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact | |
|
169 | end | |
|
170 | end | |
|
171 | end | |
|
172 | last_rev_scmid = rev.scmid | |
|
173 | if cnt > 100 | |
|
174 | cnt = 0 | |
|
175 | h["branches"][br]["last_scmid"] = last_rev_scmid | |
|
176 | merge_extra_info(h) | |
|
177 | self.save | |
|
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 | ||
|
167 | # remove revisions that we have already processed (possibly in other branches) | |
|
168 | revisions.reject!{|r| all_revisions.include?(r.scmid)} | |
|
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 | ||
|
173 | # Make the search for existing revisions in the database in a more sufficient manner | |
|
174 | # 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. | |
|
176 | # 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. | |
|
178 | # 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), | |
|
180 | # then this part will be stepped over. | |
|
181 | # We make queries, just if there is any revision. | |
|
182 | limit = 100 | |
|
183 | offset = 0 | |
|
184 | revisions_copy = revisions.clone # revisions will change | |
|
185 | while offset < revisions_copy.size | |
|
186 | recent_changesets_slice = changesets.find( | |
|
187 | :all, | |
|
188 | :conditions => [ | |
|
189 | 'scmid IN (?)', | |
|
190 | revisions_copy.slice(offset, limit).map{|x| x.scmid} | |
|
191 | ] | |
|
192 | ) | |
|
193 | # Subtract revisions that redmine already knows about | |
|
194 | recent_revisions = recent_changesets_slice.map{|c| c.scmid} | |
|
195 | revisions.reject!{|r| recent_revisions.include?(r.scmid)} | |
|
196 | offset += limit | |
|
197 | end | |
|
198 | ||
|
199 | revisions.each do |rev| | |
|
200 | transaction do | |
|
201 | # There is no search in the db for this revision, because above we ensured, | |
|
202 | # that it's not in the db. | |
|
203 | db_saved_rev = save_revision(rev) | |
|
204 | parents = {} | |
|
205 | parents[db_saved_rev] = rev.parents unless rev.parents.nil? | |
|
206 | parents.each do |ch, chparents| | |
|
207 | ch.parents = chparents.collect{|rp| find_changeset_by_name(rp)}.compact | |
|
178 | 208 | 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 | |
|
179 | 211 | end |
|
180 | unless last_rev_scmid.nil? | |
|
181 | h["branches"][br]["last_scmid"] = last_rev_scmid | |
|
182 | merge_extra_info(h) | |
|
183 | self.save | |
|
184 | end | |
|
185 | rescue Redmine::Scm::Adapters::CommandFailed => e | |
|
186 | logger.error("save revisions error: #{e.message}") | |
|
212 | end | |
|
213 | ||
|
214 | # save the data about the last revision for this branch | |
|
215 | unless last_revision.nil? | |
|
216 | h["branches"][br]["last_scmid"] = last_revision.scmid | |
|
217 | merge_extra_info(h) | |
|
218 | self.save | |
|
187 | 219 | end |
|
188 | 220 | end |
|
189 | 221 | end |
General Comments 0
You need to be logged in to leave comments.
Login now