##// 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 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
4 4 #
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; either version 2
8 8 # of the License, or (at your option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 18
19 19 require 'redmine/scm/adapters/git_adapter'
20 20
21 21 class Repository::Git < Repository
22 22 attr_protected :root_url
23 23 validates_presence_of :url
24 24
25 25 def self.human_attribute_name(attribute_key_name)
26 26 attr_name = attribute_key_name
27 27 if attr_name == "url"
28 28 attr_name = "path_to_repository"
29 29 end
30 30 super(attr_name)
31 31 end
32 32
33 33 def self.scm_adapter_class
34 34 Redmine::Scm::Adapters::GitAdapter
35 35 end
36 36
37 37 def self.scm_name
38 38 'Git'
39 39 end
40 40
41 41 def report_last_commit
42 42 extra_report_last_commit
43 43 end
44 44
45 45 def extra_report_last_commit
46 46 return false if extra_info.nil?
47 47 v = extra_info["extra_report_last_commit"]
48 48 return false if v.nil?
49 49 v.to_s != '0'
50 50 end
51 51
52 52 def supports_directory_revisions?
53 53 true
54 54 end
55 55
56 56 def repo_log_encoding
57 57 'UTF-8'
58 58 end
59 59
60 60 # Returns the identifier for the given git changeset
61 61 def self.changeset_identifier(changeset)
62 62 changeset.scmid
63 63 end
64 64
65 65 # Returns the readable identifier for the given git changeset
66 66 def self.format_changeset_identifier(changeset)
67 67 changeset.revision[0, 8]
68 68 end
69 69
70 70 def branches
71 71 scm.branches
72 72 end
73 73
74 74 def tags
75 75 scm.tags
76 76 end
77 77
78 78 def find_changeset_by_name(name)
79 79 return nil if name.nil? || name.empty?
80 80 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
81 81 return e if e
82 82 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
83 83 end
84 84
85 85 def entries(path=nil, identifier=nil)
86 86 scm.entries(path,
87 87 identifier,
88 88 options = {:report_last_commit => extra_report_last_commit})
89 89 end
90 90
91 91 # In Git and Mercurial, revisions are not in date order.
92 92 # Mercurial fixed issues.
93 93 # * Redmine Takes Too Long On Large Mercurial Repository
94 94 # http://www.redmine.org/issues/3449
95 95 # * Sorting for changesets might go wrong on Mercurial repos
96 96 # http://www.redmine.org/issues/3567
97 97 # Database revision column is text, so Redmine can not sort by revision.
98 98 # Mercurial has revision number, and revision number guarantees revision order.
99 99 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
100 100 # to get limited revisions from old to new.
101 101 # And Mercurial model stored revisions ordered by database id in database.
102 102 # So, Mercurial can use correct order revisions.
103 103 #
104 104 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
105 105 #
106 106 # The repository can still be fully reloaded by calling #clear_changesets
107 107 # before fetching changesets (eg. for offline resync)
108 108 def fetch_changesets
109 109 scm_brs = branches
110 110 return if scm_brs.nil? || scm_brs.empty?
111 h = extra_info || {}
111 h1 = extra_info || {}
112 h = h1.dup
112 113 h["branches"] ||= {}
113 114 h["db_consistent"] ||= {}
114 115 if changesets.count == 0
115 116 h["db_consistent"]["ordering"] = 1
116 117 merge_extra_info(h)
117 118 self.save
118 119 elsif ! h["db_consistent"].has_key?("ordering")
119 120 h["db_consistent"]["ordering"] = 0
120 121 merge_extra_info(h)
121 122 self.save
122 123 end
123 124 scm_brs.each do |br|
124 125 from_scmid = nil
125 126 from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
126 127 h["branches"][br] ||= {}
127 128 scm.revisions('', from_scmid, br, {:reverse => true}) do |rev|
128 129 db_rev = find_changeset_by_name(rev.revision)
129 130 transaction do
130 131 if db_rev.nil?
131 132 save_revision(rev)
132 133 end
133 134 h["branches"][br]["last_scmid"] = rev.scmid
134 135 merge_extra_info(h)
135 136 self.save
136 137 end
137 138 end
138 139 end
139 140 end
140 141
141 142 def save_revision(rev)
142 143 changeset = Changeset.new(
143 144 :repository => self,
144 145 :revision => rev.identifier,
145 146 :scmid => rev.scmid,
146 147 :committer => rev.author,
147 148 :committed_on => rev.time,
148 149 :comments => rev.message
149 150 )
150 151 if changeset.save
151 152 rev.paths.each do |file|
152 153 Change.create(
153 154 :changeset => changeset,
154 155 :action => file[:action],
155 156 :path => file[:path])
156 157 end
157 158 end
158 159 end
159 160 private :save_revision
160 161
161 162 def latest_changesets(path,rev,limit=10)
162 163 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
163 164 return [] if revisions.nil? || revisions.empty?
164 165
165 166 changesets.find(
166 167 :all,
167 168 :conditions => [
168 169 "scmid IN (?)",
169 170 revisions.map!{|c| c.scmid}
170 171 ],
171 172 :order => 'committed_on DESC'
172 173 )
173 174 end
174 175 end
General Comments 0
You need to be logged in to leave comments. Login now