##// END OF EJS Templates
Do not parse the entire git log to fetch new commits (takes several minutes for a few thousands commits), but only 1 week before the last known commit (#4547, #4716)....
Jean-Philippe Lang -
r3280:3c20a9b0acd5
parent child
Show More
@@ -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?
@@ -110,11 +110,6 module Redmine
110 end
110 end
111 end
111 end
112
112
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={})
113 def revisions(path, identifier_from, identifier_to, options={})
119 revisions = Revisions.new
114 revisions = Revisions.new
120
115
@@ -124,6 +119,7 module Redmine
124 cmd << " -n #{options[:limit]} " if options[:limit]
119 cmd << " -n #{options[:limit]} " if options[:limit]
125 cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from
120 cmd << " #{shell_quote(identifier_from + '..')} " if identifier_from
126 cmd << " #{shell_quote identifier_to} " if identifier_to
121 cmd << " #{shell_quote identifier_to} " if identifier_to
122 cmd << " --since=#{shell_quote(options[:since].strftime("%Y-%m-%d %H:%M:%S"))}" if options[:since]
127 cmd << " -- #{path}" if path && !path.empty?
123 cmd << " -- #{path}" if path && !path.empty?
128
124
129 shellout(cmd) do |io|
125 shellout(cmd) do |io|
General Comments 0
You need to be logged in to leave comments. Login now