Mercurial > hg > soundsoftware-site
comparison .svn/pristine/a5/a50c8a4fc61822f00307fa81cf3630d9ac86b4c0.svn-base @ 1296:038ba2d95de8 redmine-2.2
Fix redmine-2.2 branch update (add missing svn files)
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:05:06 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1294:3e4c3460b6ca | 1296:038ba2d95de8 |
---|---|
1 # Redmine - project management software | |
2 # Copyright (C) 2006-2012 Jean-Philippe Lang | |
3 # | |
4 # This program is free software; you can redistribute it and/or | |
5 # modify it under the terms of the GNU General Public License | |
6 # as published by the Free Software Foundation; either version 2 | |
7 # of the License, or (at your option) any later version. | |
8 # | |
9 # This program is distributed in the hope that it will be useful, | |
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 # GNU General Public License for more details. | |
13 # | |
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 | |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
17 | |
18 require 'redmine/scm/adapters/cvs_adapter' | |
19 require 'digest/sha1' | |
20 | |
21 class Repository::Cvs < Repository | |
22 validates_presence_of :url, :root_url, :log_encoding | |
23 | |
24 safe_attributes 'root_url', | |
25 :if => lambda {|repository, user| repository.new_record?} | |
26 | |
27 def self.human_attribute_name(attribute_key_name, *args) | |
28 attr_name = attribute_key_name.to_s | |
29 if attr_name == "root_url" | |
30 attr_name = "cvsroot" | |
31 elsif attr_name == "url" | |
32 attr_name = "cvs_module" | |
33 end | |
34 super(attr_name, *args) | |
35 end | |
36 | |
37 def self.scm_adapter_class | |
38 Redmine::Scm::Adapters::CvsAdapter | |
39 end | |
40 | |
41 def self.scm_name | |
42 'CVS' | |
43 end | |
44 | |
45 def entry(path=nil, identifier=nil) | |
46 rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) | |
47 scm.entry(path, rev.nil? ? nil : rev.committed_on) | |
48 end | |
49 | |
50 def entries(path=nil, identifier=nil) | |
51 rev = nil | |
52 if ! identifier.nil? | |
53 rev = changesets.find_by_revision(identifier) | |
54 return nil if rev.nil? | |
55 end | |
56 entries = scm.entries(path, rev.nil? ? nil : rev.committed_on) | |
57 if entries | |
58 entries.each() do |entry| | |
59 if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? ) | |
60 change = filechanges.find_by_revision_and_path( | |
61 entry.lastrev.revision, | |
62 scm.with_leading_slash(entry.path) ) | |
63 if change | |
64 entry.lastrev.identifier = change.changeset.revision | |
65 entry.lastrev.revision = change.changeset.revision | |
66 entry.lastrev.author = change.changeset.committer | |
67 # entry.lastrev.branch = change.branch | |
68 end | |
69 end | |
70 end | |
71 end | |
72 load_entries_changesets(entries) | |
73 entries | |
74 end | |
75 | |
76 def cat(path, identifier=nil) | |
77 rev = nil | |
78 if ! identifier.nil? | |
79 rev = changesets.find_by_revision(identifier) | |
80 return nil if rev.nil? | |
81 end | |
82 scm.cat(path, rev.nil? ? nil : rev.committed_on) | |
83 end | |
84 | |
85 def annotate(path, identifier=nil) | |
86 rev = nil | |
87 if ! identifier.nil? | |
88 rev = changesets.find_by_revision(identifier) | |
89 return nil if rev.nil? | |
90 end | |
91 scm.annotate(path, rev.nil? ? nil : rev.committed_on) | |
92 end | |
93 | |
94 def diff(path, rev, rev_to) | |
95 # convert rev to revision. CVS can't handle changesets here | |
96 diff=[] | |
97 changeset_from = changesets.find_by_revision(rev) | |
98 if rev_to.to_i > 0 | |
99 changeset_to = changesets.find_by_revision(rev_to) | |
100 end | |
101 changeset_from.filechanges.each() do |change_from| | |
102 revision_from = nil | |
103 revision_to = nil | |
104 if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) | |
105 revision_from = change_from.revision | |
106 end | |
107 if revision_from | |
108 if changeset_to | |
109 changeset_to.filechanges.each() do |change_to| | |
110 revision_to = change_to.revision if change_to.path == change_from.path | |
111 end | |
112 end | |
113 unless revision_to | |
114 revision_to = scm.get_previous_revision(revision_from) | |
115 end | |
116 file_diff = scm.diff(change_from.path, revision_from, revision_to) | |
117 diff = diff + file_diff unless file_diff.nil? | |
118 end | |
119 end | |
120 return diff | |
121 end | |
122 | |
123 def fetch_changesets | |
124 # some nifty bits to introduce a commit-id with cvs | |
125 # natively cvs doesn't provide any kind of changesets, | |
126 # there is only a revision per file. | |
127 # we now take a guess using the author, the commitlog and the commit-date. | |
128 | |
129 # last one is the next step to take. the commit-date is not equal for all | |
130 # commits in one changeset. cvs update the commit-date when the *,v file was touched. so | |
131 # we use a small delta here, to merge all changes belonging to _one_ changeset | |
132 time_delta = 10.seconds | |
133 fetch_since = latest_changeset ? latest_changeset.committed_on : nil | |
134 transaction do | |
135 tmp_rev_num = 1 | |
136 scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision| | |
137 # only add the change to the database, if it doen't exists. the cvs log | |
138 # is not exclusive at all. | |
139 tmp_time = revision.time.clone | |
140 unless filechanges.find_by_path_and_revision( | |
141 scm.with_leading_slash(revision.paths[0][:path]), | |
142 revision.paths[0][:revision] | |
143 ) | |
144 cmt = Changeset.normalize_comments(revision.message, repo_log_encoding) | |
145 author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding) | |
146 cs = changesets.find( | |
147 :first, | |
148 :conditions => { | |
149 :committed_on => tmp_time - time_delta .. tmp_time + time_delta, | |
150 :committer => author_utf8, | |
151 :comments => cmt | |
152 } | |
153 ) | |
154 # create a new changeset.... | |
155 unless cs | |
156 # we use a temporaray revision number here (just for inserting) | |
157 # later on, we calculate a continous positive number | |
158 tmp_time2 = tmp_time.clone.gmtime | |
159 branch = revision.paths[0][:branch] | |
160 scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S") | |
161 cs = Changeset.create(:repository => self, | |
162 :revision => "tmp#{tmp_rev_num}", | |
163 :scmid => scmid, | |
164 :committer => revision.author, | |
165 :committed_on => tmp_time, | |
166 :comments => revision.message) | |
167 tmp_rev_num += 1 | |
168 end | |
169 # convert CVS-File-States to internal Action-abbrevations | |
170 # default action is (M)odified | |
171 action = "M" | |
172 if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1" | |
173 action = "A" # add-action always at first revision (= 1.1) | |
174 elsif revision.paths[0][:action] == "dead" | |
175 action = "D" # dead-state is similar to Delete | |
176 end | |
177 Change.create( | |
178 :changeset => cs, | |
179 :action => action, | |
180 :path => scm.with_leading_slash(revision.paths[0][:path]), | |
181 :revision => revision.paths[0][:revision], | |
182 :branch => revision.paths[0][:branch] | |
183 ) | |
184 end | |
185 end | |
186 | |
187 # Renumber new changesets in chronological order | |
188 Changeset.all( | |
189 :order => 'committed_on ASC, id ASC', | |
190 :conditions => ["repository_id = ? AND revision LIKE 'tmp%'", id] | |
191 ).each do |changeset| | |
192 changeset.update_attribute :revision, next_revision_number | |
193 end | |
194 end # transaction | |
195 @current_revision_number = nil | |
196 end | |
197 | |
198 private | |
199 | |
200 # Returns the next revision number to assign to a CVS changeset | |
201 def next_revision_number | |
202 # Need to retrieve existing revision numbers to sort them as integers | |
203 sql = "SELECT revision FROM #{Changeset.table_name} " | |
204 sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'" | |
205 @current_revision_number ||= (connection.select_values(sql).collect(&:to_i).max || 0) | |
206 @current_revision_number += 1 | |
207 end | |
208 end |