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