##// END OF EJS Templates
scm: git: insert revisions to database with reverse commit order (#7821, #5357)....
Toshi MARUYAMA -
r4953:6dc57e752dc4
parent child
Show More
@@ -1,130 +1,130
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
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 'redmine/scm/adapters/git_adapter'
18 require 'redmine/scm/adapters/git_adapter'
19
19
20 class Repository::Git < Repository
20 class Repository::Git < Repository
21 attr_protected :root_url
21 attr_protected :root_url
22 validates_presence_of :url
22 validates_presence_of :url
23
23
24 ATTRIBUTE_KEY_NAMES = {
24 ATTRIBUTE_KEY_NAMES = {
25 "url" => "Path to repository",
25 "url" => "Path to repository",
26 }
26 }
27 def self.human_attribute_name(attribute_key_name)
27 def self.human_attribute_name(attribute_key_name)
28 ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
28 ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
29 end
29 end
30
30
31 def self.scm_adapter_class
31 def self.scm_adapter_class
32 Redmine::Scm::Adapters::GitAdapter
32 Redmine::Scm::Adapters::GitAdapter
33 end
33 end
34
34
35 def self.scm_name
35 def self.scm_name
36 'Git'
36 'Git'
37 end
37 end
38
38
39 def repo_log_encoding
39 def repo_log_encoding
40 'UTF-8'
40 'UTF-8'
41 end
41 end
42
42
43 # Returns the identifier for the given git changeset
43 # Returns the identifier for the given git changeset
44 def self.changeset_identifier(changeset)
44 def self.changeset_identifier(changeset)
45 changeset.scmid
45 changeset.scmid
46 end
46 end
47
47
48 # Returns the readable identifier for the given git changeset
48 # Returns the readable identifier for the given git changeset
49 def self.format_changeset_identifier(changeset)
49 def self.format_changeset_identifier(changeset)
50 changeset.revision[0, 8]
50 changeset.revision[0, 8]
51 end
51 end
52
52
53 def branches
53 def branches
54 scm.branches
54 scm.branches
55 end
55 end
56
56
57 def tags
57 def tags
58 scm.tags
58 scm.tags
59 end
59 end
60
60
61 def find_changeset_by_name(name)
61 def find_changeset_by_name(name)
62 return nil if name.nil? || name.empty?
62 return nil if name.nil? || name.empty?
63 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
63 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
64 return e if e
64 return e if e
65 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
65 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
66 end
66 end
67
67
68 # With SCM's that have a sequential commit numbering, redmine is able to be
68 # With SCM's that have a sequential commit numbering, redmine is able to be
69 # clever and only fetch changesets going forward from the most recent one
69 # clever and only fetch changesets going forward from the most recent one
70 # it knows about. However, with git, you never know if people have merged
70 # it knows about. However, with git, you never know if people have merged
71 # commits into the middle of the repository history, so we should parse
71 # commits into the middle of the repository history, so we should parse
72 # the entire log. Since it's way too slow for large repositories, we only
72 # the entire log. Since it's way too slow for large repositories, we only
73 # parse 1 week before the last known commit.
73 # parse 1 week before the last known commit.
74 # The repository can still be fully reloaded by calling #clear_changesets
74 # The repository can still be fully reloaded by calling #clear_changesets
75 # before fetching changesets (eg. for offline resync)
75 # before fetching changesets (eg. for offline resync)
76 def fetch_changesets
76 def fetch_changesets
77 c = changesets.find(:first, :order => 'committed_on DESC')
77 c = changesets.find(:first, :order => 'committed_on DESC')
78 since = (c ? c.committed_on - 7.days : nil)
78 since = (c ? c.committed_on - 7.days : nil)
79
79
80 revisions = scm.revisions('', nil, nil, :all => true, :since => since)
80 revisions = scm.revisions('', nil, nil, {:all => true, :since => since, :reverse => true})
81 return if revisions.nil? || revisions.empty?
81 return if revisions.nil? || revisions.empty?
82
82
83 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
83 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
84
84
85 # Clean out revisions that are no longer in git
85 # Clean out revisions that are no longer in git
86 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
86 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
87
87
88 # Subtract revisions that redmine already knows about
88 # Subtract revisions that redmine already knows about
89 recent_revisions = recent_changesets.map{|c| c.scmid}
89 recent_revisions = recent_changesets.map{|c| c.scmid}
90 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
90 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
91
91
92 # Save the remaining ones to the database
92 # Save the remaining ones to the database
93 unless revisions.nil?
93 unless revisions.nil?
94 revisions.each do |rev|
94 revisions.each do |rev|
95 transaction do
95 transaction do
96 changeset = Changeset.new(
96 changeset = Changeset.new(
97 :repository => self,
97 :repository => self,
98 :revision => rev.identifier,
98 :revision => rev.identifier,
99 :scmid => rev.scmid,
99 :scmid => rev.scmid,
100 :committer => rev.author,
100 :committer => rev.author,
101 :committed_on => rev.time,
101 :committed_on => rev.time,
102 :comments => rev.message)
102 :comments => rev.message)
103
103
104 if changeset.save
104 if changeset.save
105 rev.paths.each do |file|
105 rev.paths.each do |file|
106 Change.create(
106 Change.create(
107 :changeset => changeset,
107 :changeset => changeset,
108 :action => file[:action],
108 :action => file[:action],
109 :path => file[:path])
109 :path => file[:path])
110 end
110 end
111 end
111 end
112 end
112 end
113 end
113 end
114 end
114 end
115 end
115 end
116
116
117 def latest_changesets(path,rev,limit=10)
117 def latest_changesets(path,rev,limit=10)
118 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
118 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
119 return [] if revisions.nil? || revisions.empty?
119 return [] if revisions.nil? || revisions.empty?
120
120
121 changesets.find(
121 changesets.find(
122 :all,
122 :all,
123 :conditions => [
123 :conditions => [
124 "scmid IN (?)",
124 "scmid IN (?)",
125 revisions.map!{|c| c.scmid}
125 revisions.map!{|c| c.scmid}
126 ],
126 ],
127 :order => 'committed_on DESC'
127 :order => 'committed_on DESC'
128 )
128 )
129 end
129 end
130 end
130 end
General Comments 0
You need to be logged in to leave comments. Login now