##// END OF EJS Templates
Merged r7660 from trunk...
Toshi MARUYAMA -
r7541:5e5843456792
parent child
Show More
@@ -1,191 +1,191
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 default_branch
79 79 scm.default_branch
80 80 end
81 81
82 82 def find_changeset_by_name(name)
83 83 return nil if name.nil? || name.empty?
84 84 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
85 85 return e if e
86 86 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
87 87 end
88 88
89 89 def entries(path=nil, identifier=nil)
90 90 scm.entries(path,
91 91 identifier,
92 92 options = {:report_last_commit => extra_report_last_commit})
93 93 end
94 94
95 95 # With SCMs that have a sequential commit numbering,
96 96 # such as Subversion and Mercurial,
97 97 # Redmine is able to be clever and only fetch changesets
98 98 # going forward from the most recent one it knows about.
99 99 #
100 100 # However, Git does not have a sequential commit numbering.
101 101 #
102 102 # In order to fetch only new adding revisions,
103 # Redmine need to parse revisions per branch.
103 # Redmine needs to parse revisions per branch.
104 104 # Branch "last_scmid" is for this requirement.
105 105 #
106 106 # In Git and Mercurial, revisions are not in date order.
107 107 # Redmine Mercurial fixed issues.
108 108 # * Redmine Takes Too Long On Large Mercurial Repository
109 109 # http://www.redmine.org/issues/3449
110 110 # * Sorting for changesets might go wrong on Mercurial repos
111 111 # http://www.redmine.org/issues/3567
112 112 #
113 113 # Database revision column is text, so Redmine can not sort by revision.
114 114 # Mercurial has revision number, and revision number guarantees revision order.
115 115 # Redmine Mercurial model stored revisions ordered by database id to database.
116 116 # So, Redmine Mercurial model can use correct ordering revisions.
117 117 #
118 118 # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10"
119 119 # to get limited revisions from old to new.
120 120 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
121 121 #
122 122 # The repository can still be fully reloaded by calling #clear_changesets
123 123 # before fetching changesets (eg. for offline resync)
124 124 def fetch_changesets
125 125 scm_brs = branches
126 126 return if scm_brs.nil? || scm_brs.empty?
127 127 h1 = extra_info || {}
128 128 h = h1.dup
129 129 h["branches"] ||= {}
130 130 h["db_consistent"] ||= {}
131 131 if changesets.count == 0
132 132 h["db_consistent"]["ordering"] = 1
133 133 merge_extra_info(h)
134 134 self.save
135 135 elsif ! h["db_consistent"].has_key?("ordering")
136 136 h["db_consistent"]["ordering"] = 0
137 137 merge_extra_info(h)
138 138 self.save
139 139 end
140 140 scm_brs.each do |br|
141 141 from_scmid = nil
142 142 from_scmid = h["branches"][br]["last_scmid"] if h["branches"][br]
143 143 h["branches"][br] ||= {}
144 144 scm.revisions('', from_scmid, br, {:reverse => true}) do |rev|
145 145 db_rev = find_changeset_by_name(rev.revision)
146 146 transaction do
147 147 if db_rev.nil?
148 148 save_revision(rev)
149 149 end
150 150 h["branches"][br]["last_scmid"] = rev.scmid
151 151 merge_extra_info(h)
152 152 self.save
153 153 end
154 154 end
155 155 end
156 156 end
157 157
158 158 def save_revision(rev)
159 159 changeset = Changeset.new(
160 160 :repository => self,
161 161 :revision => rev.identifier,
162 162 :scmid => rev.scmid,
163 163 :committer => rev.author,
164 164 :committed_on => rev.time,
165 165 :comments => rev.message
166 166 )
167 167 if changeset.save
168 168 rev.paths.each do |file|
169 169 Change.create(
170 170 :changeset => changeset,
171 171 :action => file[:action],
172 172 :path => file[:path])
173 173 end
174 174 end
175 175 end
176 176 private :save_revision
177 177
178 178 def latest_changesets(path,rev,limit=10)
179 179 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
180 180 return [] if revisions.nil? || revisions.empty?
181 181
182 182 changesets.find(
183 183 :all,
184 184 :conditions => [
185 185 "scmid IN (?)",
186 186 revisions.map!{|c| c.scmid}
187 187 ],
188 188 :order => 'committed_on DESC'
189 189 )
190 190 end
191 191 end
General Comments 0
You need to be logged in to leave comments. Login now