##// END OF EJS Templates
scm: cvs: set client available if cvs version above 1.12....
Toshi MARUYAMA -
r4715:0d5d93343e94
parent child
Show More
@@ -1,400 +1,400
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'redmine/scm/adapters/abstract_adapter'
18 require 'redmine/scm/adapters/abstract_adapter'
19
19
20 module Redmine
20 module Redmine
21 module Scm
21 module Scm
22 module Adapters
22 module Adapters
23 class CvsAdapter < AbstractAdapter
23 class CvsAdapter < AbstractAdapter
24
24
25 # CVS executable name
25 # CVS executable name
26 CVS_BIN = Redmine::Configuration['scm_cvs_command'] || "cvs"
26 CVS_BIN = Redmine::Configuration['scm_cvs_command'] || "cvs"
27
27
28 class << self
28 class << self
29 def client_command
29 def client_command
30 @@bin ||= CVS_BIN
30 @@bin ||= CVS_BIN
31 end
31 end
32
32
33 def sq_bin
33 def sq_bin
34 @@sq_bin ||= shell_quote(CVS_BIN)
34 @@sq_bin ||= shell_quote(CVS_BIN)
35 end
35 end
36
36
37 def client_version
37 def client_version
38 @@client_version ||= (scm_command_version || [])
38 @@client_version ||= (scm_command_version || [])
39 end
39 end
40
40
41 def client_available
41 def client_available
42 !client_version.empty?
42 client_version_above?([1, 12])
43 end
43 end
44
44
45 def scm_command_version
45 def scm_command_version
46 scm_version = scm_version_from_command_line
46 scm_version = scm_version_from_command_line
47 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}m)
47 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)}m)
48 m[2].scan(%r{\d+}).collect(&:to_i)
48 m[2].scan(%r{\d+}).collect(&:to_i)
49 end
49 end
50 end
50 end
51
51
52 def scm_version_from_command_line
52 def scm_version_from_command_line
53 shellout("#{sq_bin} --version") { |io| io.read }.to_s
53 shellout("#{sq_bin} --version") { |io| io.read }.to_s
54 end
54 end
55 end
55 end
56
56
57 # Guidelines for the input:
57 # Guidelines for the input:
58 # url -> the project-path, relative to the cvsroot (eg. module name)
58 # url -> the project-path, relative to the cvsroot (eg. module name)
59 # root_url -> the good old, sometimes damned, CVSROOT
59 # root_url -> the good old, sometimes damned, CVSROOT
60 # login -> unnecessary
60 # login -> unnecessary
61 # password -> unnecessary too
61 # password -> unnecessary too
62 def initialize(url, root_url=nil, login=nil, password=nil)
62 def initialize(url, root_url=nil, login=nil, password=nil)
63 @url = url
63 @url = url
64 @login = login if login && !login.empty?
64 @login = login if login && !login.empty?
65 @password = (password || "") if @login
65 @password = (password || "") if @login
66 #TODO: better Exception here (IllegalArgumentException)
66 #TODO: better Exception here (IllegalArgumentException)
67 raise CommandFailed if root_url.blank?
67 raise CommandFailed if root_url.blank?
68 @root_url = root_url
68 @root_url = root_url
69 end
69 end
70
70
71 def root_url
71 def root_url
72 @root_url
72 @root_url
73 end
73 end
74
74
75 def url
75 def url
76 @url
76 @url
77 end
77 end
78
78
79 def info
79 def info
80 logger.debug "<cvs> info"
80 logger.debug "<cvs> info"
81 Info.new({:root_url => @root_url, :lastrev => nil})
81 Info.new({:root_url => @root_url, :lastrev => nil})
82 end
82 end
83
83
84 def get_previous_revision(revision)
84 def get_previous_revision(revision)
85 CvsRevisionHelper.new(revision).prevRev
85 CvsRevisionHelper.new(revision).prevRev
86 end
86 end
87
87
88 # Returns an Entries collection
88 # Returns an Entries collection
89 # or nil if the given path doesn't exist in the repository
89 # or nil if the given path doesn't exist in the repository
90 # this method is used by the repository-browser (aka LIST)
90 # this method is used by the repository-browser (aka LIST)
91 def entries(path=nil, identifier=nil)
91 def entries(path=nil, identifier=nil)
92 logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
92 logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
93 path_with_project="#{url}#{with_leading_slash(path)}"
93 path_with_project="#{url}#{with_leading_slash(path)}"
94 entries = Entries.new
94 entries = Entries.new
95 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rls -e"
95 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rls -e"
96 cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
96 cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
97 cmd << " #{shell_quote path_with_project}"
97 cmd << " #{shell_quote path_with_project}"
98 shellout(cmd) do |io|
98 shellout(cmd) do |io|
99 io.each_line(){|line|
99 io.each_line(){|line|
100 fields=line.chop.split('/',-1)
100 fields=line.chop.split('/',-1)
101 logger.debug(">>InspectLine #{fields.inspect}")
101 logger.debug(">>InspectLine #{fields.inspect}")
102
102
103 if fields[0]!="D"
103 if fields[0]!="D"
104 entries << Entry.new({:name => fields[-5],
104 entries << Entry.new({:name => fields[-5],
105 #:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
105 #:path => fields[-4].include?(path)?fields[-4]:(path + "/"+ fields[-4]),
106 :path => "#{path}/#{fields[-5]}",
106 :path => "#{path}/#{fields[-5]}",
107 :kind => 'file',
107 :kind => 'file',
108 :size => nil,
108 :size => nil,
109 :lastrev => Revision.new({
109 :lastrev => Revision.new({
110 :revision => fields[-4],
110 :revision => fields[-4],
111 :name => fields[-4],
111 :name => fields[-4],
112 :time => Time.parse(fields[-3]),
112 :time => Time.parse(fields[-3]),
113 :author => ''
113 :author => ''
114 })
114 })
115 })
115 })
116 else
116 else
117 entries << Entry.new({:name => fields[1],
117 entries << Entry.new({:name => fields[1],
118 :path => "#{path}/#{fields[1]}",
118 :path => "#{path}/#{fields[1]}",
119 :kind => 'dir',
119 :kind => 'dir',
120 :size => nil,
120 :size => nil,
121 :lastrev => nil
121 :lastrev => nil
122 })
122 })
123 end
123 end
124 }
124 }
125 end
125 end
126 return nil if $? && $?.exitstatus != 0
126 return nil if $? && $?.exitstatus != 0
127 entries.sort_by_name
127 entries.sort_by_name
128 end
128 end
129
129
130 STARTLOG="----------------------------"
130 STARTLOG="----------------------------"
131 ENDLOG ="============================================================================="
131 ENDLOG ="============================================================================="
132
132
133 # Returns all revisions found between identifier_from and identifier_to
133 # Returns all revisions found between identifier_from and identifier_to
134 # in the repository. both identifier have to be dates or nil.
134 # in the repository. both identifier have to be dates or nil.
135 # these method returns nothing but yield every result in block
135 # these method returns nothing but yield every result in block
136 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}, &block)
136 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}, &block)
137 logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
137 logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
138
138
139 path_with_project="#{url}#{with_leading_slash(path)}"
139 path_with_project="#{url}#{with_leading_slash(path)}"
140 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rlog"
140 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rlog"
141 cmd << " -d\">#{time_to_cvstime_rlog(identifier_from)}\"" if identifier_from
141 cmd << " -d\">#{time_to_cvstime_rlog(identifier_from)}\"" if identifier_from
142 cmd << " #{shell_quote path_with_project}"
142 cmd << " #{shell_quote path_with_project}"
143 shellout(cmd) do |io|
143 shellout(cmd) do |io|
144 state="entry_start"
144 state="entry_start"
145
145
146 commit_log=String.new
146 commit_log=String.new
147 revision=nil
147 revision=nil
148 date=nil
148 date=nil
149 author=nil
149 author=nil
150 entry_path=nil
150 entry_path=nil
151 entry_name=nil
151 entry_name=nil
152 file_state=nil
152 file_state=nil
153 branch_map=nil
153 branch_map=nil
154
154
155 io.each_line() do |line|
155 io.each_line() do |line|
156
156
157 if state!="revision" && /^#{ENDLOG}/ =~ line
157 if state!="revision" && /^#{ENDLOG}/ =~ line
158 commit_log=String.new
158 commit_log=String.new
159 revision=nil
159 revision=nil
160 state="entry_start"
160 state="entry_start"
161 end
161 end
162
162
163 if state=="entry_start"
163 if state=="entry_start"
164 branch_map=Hash.new
164 branch_map=Hash.new
165 if /^RCS file: #{Regexp.escape(root_url_path)}\/#{Regexp.escape(path_with_project)}(.+),v$/ =~ line
165 if /^RCS file: #{Regexp.escape(root_url_path)}\/#{Regexp.escape(path_with_project)}(.+),v$/ =~ line
166 entry_path = normalize_cvs_path($1)
166 entry_path = normalize_cvs_path($1)
167 entry_name = normalize_path(File.basename($1))
167 entry_name = normalize_path(File.basename($1))
168 logger.debug("Path #{entry_path} <=> Name #{entry_name}")
168 logger.debug("Path #{entry_path} <=> Name #{entry_name}")
169 elsif /^head: (.+)$/ =~ line
169 elsif /^head: (.+)$/ =~ line
170 entry_headRev = $1 #unless entry.nil?
170 entry_headRev = $1 #unless entry.nil?
171 elsif /^symbolic names:/ =~ line
171 elsif /^symbolic names:/ =~ line
172 state="symbolic" #unless entry.nil?
172 state="symbolic" #unless entry.nil?
173 elsif /^#{STARTLOG}/ =~ line
173 elsif /^#{STARTLOG}/ =~ line
174 commit_log=String.new
174 commit_log=String.new
175 state="revision"
175 state="revision"
176 end
176 end
177 next
177 next
178 elsif state=="symbolic"
178 elsif state=="symbolic"
179 if /^(.*):\s(.*)/ =~ (line.strip)
179 if /^(.*):\s(.*)/ =~ (line.strip)
180 branch_map[$1]=$2
180 branch_map[$1]=$2
181 else
181 else
182 state="tags"
182 state="tags"
183 next
183 next
184 end
184 end
185 elsif state=="tags"
185 elsif state=="tags"
186 if /^#{STARTLOG}/ =~ line
186 if /^#{STARTLOG}/ =~ line
187 commit_log = ""
187 commit_log = ""
188 state="revision"
188 state="revision"
189 elsif /^#{ENDLOG}/ =~ line
189 elsif /^#{ENDLOG}/ =~ line
190 state="head"
190 state="head"
191 end
191 end
192 next
192 next
193 elsif state=="revision"
193 elsif state=="revision"
194 if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line
194 if /^#{ENDLOG}/ =~ line || /^#{STARTLOG}/ =~ line
195 if revision
195 if revision
196
196
197 revHelper=CvsRevisionHelper.new(revision)
197 revHelper=CvsRevisionHelper.new(revision)
198 revBranch="HEAD"
198 revBranch="HEAD"
199
199
200 branch_map.each() do |branch_name,branch_point|
200 branch_map.each() do |branch_name,branch_point|
201 if revHelper.is_in_branch_with_symbol(branch_point)
201 if revHelper.is_in_branch_with_symbol(branch_point)
202 revBranch=branch_name
202 revBranch=branch_name
203 end
203 end
204 end
204 end
205
205
206 logger.debug("********** YIELD Revision #{revision}::#{revBranch}")
206 logger.debug("********** YIELD Revision #{revision}::#{revBranch}")
207
207
208 yield Revision.new({
208 yield Revision.new({
209 :time => date,
209 :time => date,
210 :author => author,
210 :author => author,
211 :message=>commit_log.chomp,
211 :message=>commit_log.chomp,
212 :paths => [{
212 :paths => [{
213 :revision => revision,
213 :revision => revision,
214 :branch=> revBranch,
214 :branch=> revBranch,
215 :path=>entry_path,
215 :path=>entry_path,
216 :name=>entry_name,
216 :name=>entry_name,
217 :kind=>'file',
217 :kind=>'file',
218 :action=>file_state
218 :action=>file_state
219 }]
219 }]
220 })
220 })
221 end
221 end
222
222
223 commit_log=String.new
223 commit_log=String.new
224 revision=nil
224 revision=nil
225
225
226 if /^#{ENDLOG}/ =~ line
226 if /^#{ENDLOG}/ =~ line
227 state="entry_start"
227 state="entry_start"
228 end
228 end
229 next
229 next
230 end
230 end
231
231
232 if /^branches: (.+)$/ =~ line
232 if /^branches: (.+)$/ =~ line
233 #TODO: version.branch = $1
233 #TODO: version.branch = $1
234 elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line
234 elsif /^revision (\d+(?:\.\d+)+).*$/ =~ line
235 revision = $1
235 revision = $1
236 elsif /^date:\s+(\d+.\d+.\d+\s+\d+:\d+:\d+)/ =~ line
236 elsif /^date:\s+(\d+.\d+.\d+\s+\d+:\d+:\d+)/ =~ line
237 date = Time.parse($1)
237 date = Time.parse($1)
238 author = /author: ([^;]+)/.match(line)[1]
238 author = /author: ([^;]+)/.match(line)[1]
239 file_state = /state: ([^;]+)/.match(line)[1]
239 file_state = /state: ([^;]+)/.match(line)[1]
240 #TODO: linechanges only available in CVS.... maybe a feature our SVN implementation. i'm sure, they are
240 #TODO: linechanges only available in CVS.... maybe a feature our SVN implementation. i'm sure, they are
241 # useful for stats or something else
241 # useful for stats or something else
242 # linechanges =/lines: \+(\d+) -(\d+)/.match(line)
242 # linechanges =/lines: \+(\d+) -(\d+)/.match(line)
243 # unless linechanges.nil?
243 # unless linechanges.nil?
244 # version.line_plus = linechanges[1]
244 # version.line_plus = linechanges[1]
245 # version.line_minus = linechanges[2]
245 # version.line_minus = linechanges[2]
246 # else
246 # else
247 # version.line_plus = 0
247 # version.line_plus = 0
248 # version.line_minus = 0
248 # version.line_minus = 0
249 # end
249 # end
250 else
250 else
251 commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/
251 commit_log << line unless line =~ /^\*\*\* empty log message \*\*\*/
252 end
252 end
253 end
253 end
254 end
254 end
255 end
255 end
256 end
256 end
257
257
258 def diff(path, identifier_from, identifier_to=nil)
258 def diff(path, identifier_from, identifier_to=nil)
259 logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
259 logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
260 path_with_project="#{url}#{with_leading_slash(path)}"
260 path_with_project="#{url}#{with_leading_slash(path)}"
261 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}"
261 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}"
262 diff = []
262 diff = []
263 shellout(cmd) do |io|
263 shellout(cmd) do |io|
264 io.each_line do |line|
264 io.each_line do |line|
265 diff << line
265 diff << line
266 end
266 end
267 end
267 end
268 return nil if $? && $?.exitstatus != 0
268 return nil if $? && $?.exitstatus != 0
269 diff
269 diff
270 end
270 end
271
271
272 def cat(path, identifier=nil)
272 def cat(path, identifier=nil)
273 identifier = (identifier) ? identifier : "HEAD"
273 identifier = (identifier) ? identifier : "HEAD"
274 logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
274 logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
275 path_with_project="#{url}#{with_leading_slash(path)}"
275 path_with_project="#{url}#{with_leading_slash(path)}"
276 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} co"
276 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} co"
277 cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
277 cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
278 cmd << " -p #{shell_quote path_with_project}"
278 cmd << " -p #{shell_quote path_with_project}"
279 cat = nil
279 cat = nil
280 shellout(cmd) do |io|
280 shellout(cmd) do |io|
281 io.binmode
281 io.binmode
282 cat = io.read
282 cat = io.read
283 end
283 end
284 return nil if $? && $?.exitstatus != 0
284 return nil if $? && $?.exitstatus != 0
285 cat
285 cat
286 end
286 end
287
287
288 def annotate(path, identifier=nil)
288 def annotate(path, identifier=nil)
289 identifier = (identifier) ? identifier.to_i : "HEAD"
289 identifier = (identifier) ? identifier.to_i : "HEAD"
290 logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
290 logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
291 path_with_project="#{url}#{with_leading_slash(path)}"
291 path_with_project="#{url}#{with_leading_slash(path)}"
292 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rannotate -r#{identifier} #{shell_quote path_with_project}"
292 cmd = "#{self.class.sq_bin} -d #{shell_quote root_url} rannotate -r#{identifier} #{shell_quote path_with_project}"
293 blame = Annotate.new
293 blame = Annotate.new
294 shellout(cmd) do |io|
294 shellout(cmd) do |io|
295 io.each_line do |line|
295 io.each_line do |line|
296 next unless line =~ %r{^([\d\.]+)\s+\(([^\)]+)\s+[^\)]+\):\s(.*)$}
296 next unless line =~ %r{^([\d\.]+)\s+\(([^\)]+)\s+[^\)]+\):\s(.*)$}
297 blame.add_line($3.rstrip, Revision.new(:revision => $1, :author => $2.strip))
297 blame.add_line($3.rstrip, Revision.new(:revision => $1, :author => $2.strip))
298 end
298 end
299 end
299 end
300 return nil if $? && $?.exitstatus != 0
300 return nil if $? && $?.exitstatus != 0
301 blame
301 blame
302 end
302 end
303
303
304 private
304 private
305
305
306 # Returns the root url without the connexion string
306 # Returns the root url without the connexion string
307 # :pserver:anonymous@foo.bar:/path => /path
307 # :pserver:anonymous@foo.bar:/path => /path
308 # :ext:cvsservername:/path => /path
308 # :ext:cvsservername:/path => /path
309 def root_url_path
309 def root_url_path
310 root_url.to_s.gsub(/^:.+:\d*/, '')
310 root_url.to_s.gsub(/^:.+:\d*/, '')
311 end
311 end
312
312
313 # convert a date/time into the CVS-format
313 # convert a date/time into the CVS-format
314 def time_to_cvstime(time)
314 def time_to_cvstime(time)
315 return nil if time.nil?
315 return nil if time.nil?
316 return Time.now if time == 'HEAD'
316 return Time.now if time == 'HEAD'
317
317
318 unless time.kind_of? Time
318 unless time.kind_of? Time
319 time = Time.parse(time)
319 time = Time.parse(time)
320 end
320 end
321 return time.strftime("%Y-%m-%d %H:%M:%S")
321 return time.strftime("%Y-%m-%d %H:%M:%S")
322 end
322 end
323
323
324 def time_to_cvstime_rlog(time)
324 def time_to_cvstime_rlog(time)
325 return nil if time.nil?
325 return nil if time.nil?
326 t1 = time.clone.localtime
326 t1 = time.clone.localtime
327 return t1.strftime("%Y-%m-%d %H:%M:%S")
327 return t1.strftime("%Y-%m-%d %H:%M:%S")
328 end
328 end
329
329
330 def normalize_cvs_path(path)
330 def normalize_cvs_path(path)
331 normalize_path(path.gsub(/Attic\//,''))
331 normalize_path(path.gsub(/Attic\//,''))
332 end
332 end
333
333
334 def normalize_path(path)
334 def normalize_path(path)
335 path.sub(/^(\/)*(.*)/,'\2').sub(/(.*)(,v)+/,'\1')
335 path.sub(/^(\/)*(.*)/,'\2').sub(/(.*)(,v)+/,'\1')
336 end
336 end
337 end
337 end
338
338
339 class CvsRevisionHelper
339 class CvsRevisionHelper
340 attr_accessor :complete_rev, :revision, :base, :branchid
340 attr_accessor :complete_rev, :revision, :base, :branchid
341
341
342 def initialize(complete_rev)
342 def initialize(complete_rev)
343 @complete_rev = complete_rev
343 @complete_rev = complete_rev
344 parseRevision()
344 parseRevision()
345 end
345 end
346
346
347 def branchPoint
347 def branchPoint
348 return @base
348 return @base
349 end
349 end
350
350
351 def branchVersion
351 def branchVersion
352 if isBranchRevision
352 if isBranchRevision
353 return @base+"."+@branchid
353 return @base+"."+@branchid
354 end
354 end
355 return @base
355 return @base
356 end
356 end
357
357
358 def isBranchRevision
358 def isBranchRevision
359 !@branchid.nil?
359 !@branchid.nil?
360 end
360 end
361
361
362 def prevRev
362 def prevRev
363 unless @revision==0
363 unless @revision==0
364 return buildRevision(@revision-1)
364 return buildRevision(@revision-1)
365 end
365 end
366 return buildRevision(@revision)
366 return buildRevision(@revision)
367 end
367 end
368
368
369 def is_in_branch_with_symbol(branch_symbol)
369 def is_in_branch_with_symbol(branch_symbol)
370 bpieces=branch_symbol.split(".")
370 bpieces=branch_symbol.split(".")
371 branch_start="#{bpieces[0..-3].join(".")}.#{bpieces[-1]}"
371 branch_start="#{bpieces[0..-3].join(".")}.#{bpieces[-1]}"
372 return (branchVersion==branch_start)
372 return (branchVersion==branch_start)
373 end
373 end
374
374
375 private
375 private
376 def buildRevision(rev)
376 def buildRevision(rev)
377 if rev== 0
377 if rev== 0
378 @base
378 @base
379 elsif @branchid.nil?
379 elsif @branchid.nil?
380 @base+"."+rev.to_s
380 @base+"."+rev.to_s
381 else
381 else
382 @base+"."+@branchid+"."+rev.to_s
382 @base+"."+@branchid+"."+rev.to_s
383 end
383 end
384 end
384 end
385
385
386 # Interpretiert die cvs revisionsnummern wie z.b. 1.14 oder 1.3.0.15
386 # Interpretiert die cvs revisionsnummern wie z.b. 1.14 oder 1.3.0.15
387 def parseRevision()
387 def parseRevision()
388 pieces=@complete_rev.split(".")
388 pieces=@complete_rev.split(".")
389 @revision=pieces.last.to_i
389 @revision=pieces.last.to_i
390 baseSize=1
390 baseSize=1
391 baseSize+=(pieces.size/2)
391 baseSize+=(pieces.size/2)
392 @base=pieces[0..-baseSize].join(".")
392 @base=pieces[0..-baseSize].join(".")
393 if baseSize > 2
393 if baseSize > 2
394 @branchid=pieces[-2]
394 @branchid=pieces[-2]
395 end
395 end
396 end
396 end
397 end
397 end
398 end
398 end
399 end
399 end
400 end
400 end
General Comments 0
You need to be logged in to leave comments. Login now