##// END OF EJS Templates
scm: git: use hash#dup for extra_info in model fetch_changesets()....
Toshi MARUYAMA -
r5736:fe7e8fa59071
parent child
Show More
@@ -1,174 +1,175
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 # 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)
25 def self.human_attribute_name(attribute_key_name)
26 attr_name = attribute_key_name
26 attr_name = attribute_key_name
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)
30 super(attr_name)
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 repo_log_encoding
56 def repo_log_encoding
57 'UTF-8'
57 'UTF-8'
58 end
58 end
59
59
60 # Returns the identifier for the given git changeset
60 # Returns the identifier for the given git changeset
61 def self.changeset_identifier(changeset)
61 def self.changeset_identifier(changeset)
62 changeset.scmid
62 changeset.scmid
63 end
63 end
64
64
65 # Returns the readable identifier for the given git changeset
65 # Returns the readable identifier for the given git changeset
66 def self.format_changeset_identifier(changeset)
66 def self.format_changeset_identifier(changeset)
67 changeset.revision[0, 8]
67 changeset.revision[0, 8]
68 end
68 end
69
69
70 def branches
70 def branches
71 scm.branches
71 scm.branches
72 end
72 end
73
73
74 def tags
74 def tags
75 scm.tags
75 scm.tags
76 end
76 end
77
77
78 def find_changeset_by_name(name)
78 def find_changeset_by_name(name)
79 return nil if name.nil? || name.empty?
79 return nil if name.nil? || name.empty?
80 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
80 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
81 return e if e
81 return e if e
82 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
82 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
83 end
83 end
84
84
85 def entries(path=nil, identifier=nil)
85 def entries(path=nil, identifier=nil)
86 scm.entries(path,
86 scm.entries(path,
87 identifier,
87 identifier,
88 options = {:report_last_commit => extra_report_last_commit})
88 options = {:report_last_commit => extra_report_last_commit})
89 end
89 end
90
90
91 # In Git and Mercurial, revisions are not in date order.
91 # In Git and Mercurial, revisions are not in date order.
92 # Mercurial fixed issues.
92 # Mercurial fixed issues.
93 # * Redmine Takes Too Long On Large Mercurial Repository
93 # * Redmine Takes Too Long On Large Mercurial Repository
94 # http://www.redmine.org/issues/3449
94 # http://www.redmine.org/issues/3449
95 # * Sorting for changesets might go wrong on Mercurial repos
95 # * Sorting for changesets might go wrong on Mercurial repos
96 # http://www.redmine.org/issues/3567
96 # http://www.redmine.org/issues/3567
97 # Database revision column is text, so Redmine can not sort by revision.
97 # Database revision column is text, so Redmine can not sort by revision.
98 # Mercurial has revision number, and revision number guarantees revision order.
98 # Mercurial has revision number, and revision number guarantees revision order.
99 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
99 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
100 # to get limited revisions from old to new.
100 # to get limited revisions from old to new.
101 # And Mercurial model stored revisions ordered by database id in database.
101 # And Mercurial model stored revisions ordered by database id in database.
102 # So, Mercurial can use correct order revisions.
102 # So, Mercurial can use correct order revisions.
103 #
103 #
104 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
104 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
105 #
105 #
106 # The repository can still be fully reloaded by calling #clear_changesets
106 # The repository can still be fully reloaded by calling #clear_changesets
107 # before fetching changesets (eg. for offline resync)
107 # before fetching changesets (eg. for offline resync)
108 def fetch_changesets
108 def fetch_changesets
109 scm_brs = branches
109 scm_brs = branches
110 return if scm_brs.nil? || scm_brs.empty?
110 return if scm_brs.nil? || scm_brs.empty?
111 h = extra_info || {}
111 h1 = extra_info || {}
112 h = h1.dup
112 h["branches"] ||= {}
113 h["branches"] ||= {}
113 h["db_consistent"] ||= {}
114 h["db_consistent"] ||= {}
114 if changesets.count == 0
115 if changesets.count == 0
115 h["db_consistent"]["ordering"] = 1
116 h["db_consistent"]["ordering"] = 1
116 merge_extra_info(h)
117 merge_extra_info(h)
117 self.save
118 self.save
118 elsif ! h["db_consistent"].has_key?("ordering")
119 elsif ! h["db_consistent"].has_key?("ordering")
119 h["db_consistent"]["ordering"] = 0
120 h["db_consistent"]["ordering"] = 0
120 merge_extra_info(h)
121 merge_extra_info(h)
121 self.save
122 self.save
122 end
123 end
123 scm_brs.each do |br|
124 scm_brs.each do |br|
124 from_scmid = nil
125 from_scmid = nil
125 from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
126 from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
126 h["branches"][br] ||= {}
127 h["branches"][br] ||= {}
127 scm.revisions('', from_scmid, br, {:reverse => true}) do |rev|
128 scm.revisions('', from_scmid, br, {:reverse => true}) do |rev|
128 db_rev = find_changeset_by_name(rev.revision)
129 db_rev = find_changeset_by_name(rev.revision)
129 transaction do
130 transaction do
130 if db_rev.nil?
131 if db_rev.nil?
131 save_revision(rev)
132 save_revision(rev)
132 end
133 end
133 h["branches"][br]["last_scmid"] = rev.scmid
134 h["branches"][br]["last_scmid"] = rev.scmid
134 merge_extra_info(h)
135 merge_extra_info(h)
135 self.save
136 self.save
136 end
137 end
137 end
138 end
138 end
139 end
139 end
140 end
140
141
141 def save_revision(rev)
142 def save_revision(rev)
142 changeset = Changeset.new(
143 changeset = Changeset.new(
143 :repository => self,
144 :repository => self,
144 :revision => rev.identifier,
145 :revision => rev.identifier,
145 :scmid => rev.scmid,
146 :scmid => rev.scmid,
146 :committer => rev.author,
147 :committer => rev.author,
147 :committed_on => rev.time,
148 :committed_on => rev.time,
148 :comments => rev.message
149 :comments => rev.message
149 )
150 )
150 if changeset.save
151 if changeset.save
151 rev.paths.each do |file|
152 rev.paths.each do |file|
152 Change.create(
153 Change.create(
153 :changeset => changeset,
154 :changeset => changeset,
154 :action => file[:action],
155 :action => file[:action],
155 :path => file[:path])
156 :path => file[:path])
156 end
157 end
157 end
158 end
158 end
159 end
159 private :save_revision
160 private :save_revision
160
161
161 def latest_changesets(path,rev,limit=10)
162 def latest_changesets(path,rev,limit=10)
162 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
163 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
163 return [] if revisions.nil? || revisions.empty?
164 return [] if revisions.nil? || revisions.empty?
164
165
165 changesets.find(
166 changesets.find(
166 :all,
167 :all,
167 :conditions => [
168 :conditions => [
168 "scmid IN (?)",
169 "scmid IN (?)",
169 revisions.map!{|c| c.scmid}
170 revisions.map!{|c| c.scmid}
170 ],
171 ],
171 :order => 'committed_on DESC'
172 :order => 'committed_on DESC'
172 )
173 )
173 end
174 end
174 end
175 end
General Comments 0
You need to be logged in to leave comments. Login now