##// END OF EJS Templates
scm: bazaar: use log encoding as path encoding (#11834)...
Toshi MARUYAMA -
r10237:f9208d7c5c81
parent child
Show More
@@ -1,106 +1,128
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 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/bazaar_adapter'
18 require 'redmine/scm/adapters/bazaar_adapter'
19
19
20 class Repository::Bazaar < Repository
20 class Repository::Bazaar < Repository
21 attr_protected :root_url
21 attr_protected :root_url
22 validates_presence_of :url, :log_encoding
22 validates_presence_of :url, :log_encoding
23
23
24 def self.human_attribute_name(attribute_key_name, *args)
24 def self.human_attribute_name(attribute_key_name, *args)
25 attr_name = attribute_key_name.to_s
25 attr_name = attribute_key_name.to_s
26 if attr_name == "url"
26 if attr_name == "url"
27 attr_name = "path_to_repository"
27 attr_name = "path_to_repository"
28 end
28 end
29 super(attr_name, *args)
29 super(attr_name, *args)
30 end
30 end
31
31
32 def self.scm_adapter_class
32 def self.scm_adapter_class
33 Redmine::Scm::Adapters::BazaarAdapter
33 Redmine::Scm::Adapters::BazaarAdapter
34 end
34 end
35
35
36 def self.scm_name
36 def self.scm_name
37 'Bazaar'
37 'Bazaar'
38 end
38 end
39
39
40 def entry(path=nil, identifier=nil)
41 scm.bzr_path_encodig = log_encoding
42 scm.entry(path, identifier)
43 end
44
45 def cat(path, identifier=nil)
46 scm.bzr_path_encodig = log_encoding
47 scm.cat(path, identifier)
48 end
49
50 def annotate(path, identifier=nil)
51 scm.bzr_path_encodig = log_encoding
52 scm.annotate(path, identifier)
53 end
54
55 def diff(path, rev, rev_to)
56 scm.bzr_path_encodig = log_encoding
57 scm.diff(path, rev, rev_to)
58 end
59
40 def entries(path=nil, identifier=nil)
60 def entries(path=nil, identifier=nil)
61 scm.bzr_path_encodig = log_encoding
41 entries = scm.entries(path, identifier)
62 entries = scm.entries(path, identifier)
42 if entries
63 if entries
43 entries.each do |e|
64 entries.each do |e|
44 next if e.lastrev.revision.blank?
65 next if e.lastrev.revision.blank?
45 # Set the filesize unless browsing a specific revision
66 # Set the filesize unless browsing a specific revision
46 if identifier.nil? && e.is_file?
67 if identifier.nil? && e.is_file?
47 full_path = File.join(root_url, e.path)
68 full_path = File.join(root_url, e.path)
48 e.size = File.stat(full_path).size if File.file?(full_path)
69 e.size = File.stat(full_path).size if File.file?(full_path)
49 end
70 end
50 c = Change.find(
71 c = Change.find(
51 :first,
72 :first,
52 :include => :changeset,
73 :include => :changeset,
53 :conditions => [
74 :conditions => [
54 "#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
75 "#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
55 e.lastrev.revision,
76 e.lastrev.revision,
56 id
77 id
57 ],
78 ],
58 :order => "#{Changeset.table_name}.revision DESC")
79 :order => "#{Changeset.table_name}.revision DESC")
59 if c
80 if c
60 e.lastrev.identifier = c.changeset.revision
81 e.lastrev.identifier = c.changeset.revision
61 e.lastrev.name = c.changeset.revision
82 e.lastrev.name = c.changeset.revision
62 e.lastrev.author = c.changeset.committer
83 e.lastrev.author = c.changeset.committer
63 end
84 end
64 end
85 end
65 end
86 end
66 load_entries_changesets(entries)
87 load_entries_changesets(entries)
67 entries
88 entries
68 end
89 end
69
90
70 def fetch_changesets
91 def fetch_changesets
92 scm.bzr_path_encodig = log_encoding
71 scm_info = scm.info
93 scm_info = scm.info
72 if scm_info
94 if scm_info
73 # latest revision found in database
95 # latest revision found in database
74 db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
96 db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
75 # latest revision in the repository
97 # latest revision in the repository
76 scm_revision = scm_info.lastrev.identifier.to_i
98 scm_revision = scm_info.lastrev.identifier.to_i
77 if db_revision < scm_revision
99 if db_revision < scm_revision
78 logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
100 logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
79 identifier_from = db_revision + 1
101 identifier_from = db_revision + 1
80 while (identifier_from <= scm_revision)
102 while (identifier_from <= scm_revision)
81 # loads changesets by batches of 200
103 # loads changesets by batches of 200
82 identifier_to = [identifier_from + 199, scm_revision].min
104 identifier_to = [identifier_from + 199, scm_revision].min
83 revisions = scm.revisions('', identifier_to, identifier_from)
105 revisions = scm.revisions('', identifier_to, identifier_from)
84 transaction do
106 transaction do
85 revisions.reverse_each do |revision|
107 revisions.reverse_each do |revision|
86 changeset = Changeset.create(:repository => self,
108 changeset = Changeset.create(:repository => self,
87 :revision => revision.identifier,
109 :revision => revision.identifier,
88 :committer => revision.author,
110 :committer => revision.author,
89 :committed_on => revision.time,
111 :committed_on => revision.time,
90 :scmid => revision.scmid,
112 :scmid => revision.scmid,
91 :comments => revision.message)
113 :comments => revision.message)
92
114
93 revision.paths.each do |change|
115 revision.paths.each do |change|
94 Change.create(:changeset => changeset,
116 Change.create(:changeset => changeset,
95 :action => change[:action],
117 :action => change[:action],
96 :path => change[:path],
118 :path => change[:path],
97 :revision => change[:revision])
119 :revision => change[:revision])
98 end
120 end
99 end
121 end
100 end unless revisions.nil?
122 end unless revisions.nil?
101 identifier_from = identifier_to + 1
123 identifier_from = identifier_to + 1
102 end
124 end
103 end
125 end
104 end
126 end
105 end
127 end
106 end
128 end
@@ -1,335 +1,339
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 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 BazaarAdapter < AbstractAdapter
23 class BazaarAdapter < AbstractAdapter
24
24
25 # Bazaar executable name
25 # Bazaar executable name
26 BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
26 BZR_BIN = Redmine::Configuration['scm_bazaar_command'] || "bzr"
27
27
28 class << self
28 class << self
29 def client_command
29 def client_command
30 @@bin ||= BZR_BIN
30 @@bin ||= BZR_BIN
31 end
31 end
32
32
33 def sq_bin
33 def sq_bin
34 @@sq_bin ||= shell_quote_command
34 @@sq_bin ||= shell_quote_command
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.empty?
43 end
43 end
44
44
45 def scm_command_version
45 def scm_command_version
46 scm_version = scm_version_from_command_line.dup
46 scm_version = scm_version_from_command_line.dup
47 if scm_version.respond_to?(:force_encoding)
47 if scm_version.respond_to?(:force_encoding)
48 scm_version.force_encoding('ASCII-8BIT')
48 scm_version.force_encoding('ASCII-8BIT')
49 end
49 end
50 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
50 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
51 m[2].scan(%r{\d+}).collect(&:to_i)
51 m[2].scan(%r{\d+}).collect(&:to_i)
52 end
52 end
53 end
53 end
54
54
55 def scm_version_from_command_line
55 def scm_version_from_command_line
56 shellout("#{sq_bin} --version") { |io| io.read }.to_s
56 shellout("#{sq_bin} --version") { |io| io.read }.to_s
57 end
57 end
58 end
58 end
59
59
60 def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
60 def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
61 @path_encoding = 'UTF-8'
61 @path_encoding = 'UTF-8'
62 super
62 super
63 end
63 end
64
64
65 def bzr_path_encodig=(encoding)
66 @path_encoding = encoding
67 end
68
65 # Get info about the repository
69 # Get info about the repository
66 def info
70 def info
67 cmd_args = %w|revno|
71 cmd_args = %w|revno|
68 cmd_args << bzr_target('')
72 cmd_args << bzr_target('')
69 info = nil
73 info = nil
70 scm_cmd(*cmd_args) do |io|
74 scm_cmd(*cmd_args) do |io|
71 if io.read =~ %r{^(\d+)\r?$}
75 if io.read =~ %r{^(\d+)\r?$}
72 info = Info.new({:root_url => url,
76 info = Info.new({:root_url => url,
73 :lastrev => Revision.new({
77 :lastrev => Revision.new({
74 :identifier => $1
78 :identifier => $1
75 })
79 })
76 })
80 })
77 end
81 end
78 end
82 end
79 info
83 info
80 rescue ScmCommandAborted
84 rescue ScmCommandAborted
81 return nil
85 return nil
82 end
86 end
83
87
84 # Returns an Entries collection
88 # Returns an Entries collection
85 # 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
86 def entries(path=nil, identifier=nil, options={})
90 def entries(path=nil, identifier=nil, options={})
87 path ||= ''
91 path ||= ''
88 entries = Entries.new
92 entries = Entries.new
89 identifier = -1 unless identifier && identifier.to_i > 0
93 identifier = -1 unless identifier && identifier.to_i > 0
90 cmd_args = %w|ls -v --show-ids|
94 cmd_args = %w|ls -v --show-ids|
91 cmd_args << "-r#{identifier.to_i}"
95 cmd_args << "-r#{identifier.to_i}"
92 cmd_args << bzr_target(path)
96 cmd_args << bzr_target(path)
93 scm_cmd(*cmd_args) do |io|
97 scm_cmd(*cmd_args) do |io|
94 prefix_utf8 = "#{url}/#{path}".gsub('\\', '/')
98 prefix_utf8 = "#{url}/#{path}".gsub('\\', '/')
95 logger.debug "PREFIX: #{prefix_utf8}"
99 logger.debug "PREFIX: #{prefix_utf8}"
96 prefix = scm_iconv(@path_encoding, 'UTF-8', prefix_utf8)
100 prefix = scm_iconv(@path_encoding, 'UTF-8', prefix_utf8)
97 prefix.force_encoding('ASCII-8BIT') if prefix.respond_to?(:force_encoding)
101 prefix.force_encoding('ASCII-8BIT') if prefix.respond_to?(:force_encoding)
98 re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$}
102 re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)\r?$}
99 io.each_line do |line|
103 io.each_line do |line|
100 next unless line =~ re
104 next unless line =~ re
101 name_locale = $3.strip
105 name_locale = $3.strip
102 name = scm_iconv('UTF-8', @path_encoding, name_locale)
106 name = scm_iconv('UTF-8', @path_encoding, name_locale)
103 entries << Entry.new({:name => name,
107 entries << Entry.new({:name => name,
104 :path => ((path.empty? ? "" : "#{path}/") + name),
108 :path => ((path.empty? ? "" : "#{path}/") + name),
105 :kind => ($4.blank? ? 'file' : 'dir'),
109 :kind => ($4.blank? ? 'file' : 'dir'),
106 :size => nil,
110 :size => nil,
107 :lastrev => Revision.new(:revision => $5.strip)
111 :lastrev => Revision.new(:revision => $5.strip)
108 })
112 })
109 end
113 end
110 end
114 end
111 if logger && logger.debug?
115 if logger && logger.debug?
112 logger.debug("Found #{entries.size} entries in the repository for #{target(path)}")
116 logger.debug("Found #{entries.size} entries in the repository for #{target(path)}")
113 end
117 end
114 entries.sort_by_name
118 entries.sort_by_name
115 rescue ScmCommandAborted
119 rescue ScmCommandAborted
116 return nil
120 return nil
117 end
121 end
118
122
119 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
123 def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
120 path ||= ''
124 path ||= ''
121 identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
125 identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
122 identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
126 identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
123 revisions = Revisions.new
127 revisions = Revisions.new
124 cmd_args = %w|log -v --show-ids|
128 cmd_args = %w|log -v --show-ids|
125 cmd_args << "-r#{identifier_to}..#{identifier_from}"
129 cmd_args << "-r#{identifier_to}..#{identifier_from}"
126 cmd_args << bzr_target(path)
130 cmd_args << bzr_target(path)
127 scm_cmd(*cmd_args) do |io|
131 scm_cmd(*cmd_args) do |io|
128 revision = nil
132 revision = nil
129 parsing = nil
133 parsing = nil
130 io.each_line do |line|
134 io.each_line do |line|
131 if line =~ /^----/
135 if line =~ /^----/
132 revisions << revision if revision
136 revisions << revision if revision
133 revision = Revision.new(:paths => [], :message => '')
137 revision = Revision.new(:paths => [], :message => '')
134 parsing = nil
138 parsing = nil
135 else
139 else
136 next unless revision
140 next unless revision
137 if line =~ /^revno: (\d+)($|\s\[merge\]$)/
141 if line =~ /^revno: (\d+)($|\s\[merge\]$)/
138 revision.identifier = $1.to_i
142 revision.identifier = $1.to_i
139 elsif line =~ /^committer: (.+)$/
143 elsif line =~ /^committer: (.+)$/
140 revision.author = $1.strip
144 revision.author = $1.strip
141 elsif line =~ /^revision-id:(.+)$/
145 elsif line =~ /^revision-id:(.+)$/
142 revision.scmid = $1.strip
146 revision.scmid = $1.strip
143 elsif line =~ /^timestamp: (.+)$/
147 elsif line =~ /^timestamp: (.+)$/
144 revision.time = Time.parse($1).localtime
148 revision.time = Time.parse($1).localtime
145 elsif line =~ /^ -----/
149 elsif line =~ /^ -----/
146 # partial revisions
150 # partial revisions
147 parsing = nil unless parsing == 'message'
151 parsing = nil unless parsing == 'message'
148 elsif line =~ /^(message|added|modified|removed|renamed):/
152 elsif line =~ /^(message|added|modified|removed|renamed):/
149 parsing = $1
153 parsing = $1
150 elsif line =~ /^ (.*)$/
154 elsif line =~ /^ (.*)$/
151 if parsing == 'message'
155 if parsing == 'message'
152 revision.message << "#{$1}\n"
156 revision.message << "#{$1}\n"
153 else
157 else
154 if $1 =~ /^(.*)\s+(\S+)$/
158 if $1 =~ /^(.*)\s+(\S+)$/
155 path_locale = $1.strip
159 path_locale = $1.strip
156 path = scm_iconv('UTF-8', @path_encoding, path_locale)
160 path = scm_iconv('UTF-8', @path_encoding, path_locale)
157 revid = $2
161 revid = $2
158 case parsing
162 case parsing
159 when 'added'
163 when 'added'
160 revision.paths << {:action => 'A', :path => "/#{path}", :revision => revid}
164 revision.paths << {:action => 'A', :path => "/#{path}", :revision => revid}
161 when 'modified'
165 when 'modified'
162 revision.paths << {:action => 'M', :path => "/#{path}", :revision => revid}
166 revision.paths << {:action => 'M', :path => "/#{path}", :revision => revid}
163 when 'removed'
167 when 'removed'
164 revision.paths << {:action => 'D', :path => "/#{path}", :revision => revid}
168 revision.paths << {:action => 'D', :path => "/#{path}", :revision => revid}
165 when 'renamed'
169 when 'renamed'
166 new_path = path.split('=>').last
170 new_path = path.split('=>').last
167 if new_path
171 if new_path
168 revision.paths << {:action => 'M', :path => "/#{new_path.strip}",
172 revision.paths << {:action => 'M', :path => "/#{new_path.strip}",
169 :revision => revid}
173 :revision => revid}
170 end
174 end
171 end
175 end
172 end
176 end
173 end
177 end
174 else
178 else
175 parsing = nil
179 parsing = nil
176 end
180 end
177 end
181 end
178 end
182 end
179 revisions << revision if revision
183 revisions << revision if revision
180 end
184 end
181 revisions
185 revisions
182 rescue ScmCommandAborted
186 rescue ScmCommandAborted
183 return nil
187 return nil
184 end
188 end
185
189
186 def diff(path, identifier_from, identifier_to=nil)
190 def diff(path, identifier_from, identifier_to=nil)
187 path ||= ''
191 path ||= ''
188 if identifier_to
192 if identifier_to
189 identifier_to = identifier_to.to_i
193 identifier_to = identifier_to.to_i
190 else
194 else
191 identifier_to = identifier_from.to_i - 1
195 identifier_to = identifier_from.to_i - 1
192 end
196 end
193 if identifier_from
197 if identifier_from
194 identifier_from = identifier_from.to_i
198 identifier_from = identifier_from.to_i
195 end
199 end
196 diff = []
200 diff = []
197 cmd_args = %w|diff|
201 cmd_args = %w|diff|
198 cmd_args << "-r#{identifier_to}..#{identifier_from}"
202 cmd_args << "-r#{identifier_to}..#{identifier_from}"
199 cmd_args << bzr_target(path)
203 cmd_args << bzr_target(path)
200 scm_cmd_no_raise(*cmd_args) do |io|
204 scm_cmd_no_raise(*cmd_args) do |io|
201 io.each_line do |line|
205 io.each_line do |line|
202 diff << line
206 diff << line
203 end
207 end
204 end
208 end
205 diff
209 diff
206 end
210 end
207
211
208 def cat(path, identifier=nil)
212 def cat(path, identifier=nil)
209 cat = nil
213 cat = nil
210 cmd_args = %w|cat|
214 cmd_args = %w|cat|
211 cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
215 cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
212 cmd_args << bzr_target(path)
216 cmd_args << bzr_target(path)
213 scm_cmd(*cmd_args) do |io|
217 scm_cmd(*cmd_args) do |io|
214 io.binmode
218 io.binmode
215 cat = io.read
219 cat = io.read
216 end
220 end
217 cat
221 cat
218 rescue ScmCommandAborted
222 rescue ScmCommandAborted
219 return nil
223 return nil
220 end
224 end
221
225
222 def annotate(path, identifier=nil)
226 def annotate(path, identifier=nil)
223 blame = Annotate.new
227 blame = Annotate.new
224 cmd_args = %w|annotate -q --all|
228 cmd_args = %w|annotate -q --all|
225 cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
229 cmd_args << "-r#{identifier.to_i}" if identifier && identifier.to_i > 0
226 cmd_args << bzr_target(path)
230 cmd_args << bzr_target(path)
227 scm_cmd(*cmd_args) do |io|
231 scm_cmd(*cmd_args) do |io|
228 author = nil
232 author = nil
229 identifier = nil
233 identifier = nil
230 io.each_line do |line|
234 io.each_line do |line|
231 next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$}
235 next unless line =~ %r{^(\d+) ([^|]+)\| (.*)$}
232 rev = $1
236 rev = $1
233 blame.add_line($3.rstrip,
237 blame.add_line($3.rstrip,
234 Revision.new(
238 Revision.new(
235 :identifier => rev,
239 :identifier => rev,
236 :revision => rev,
240 :revision => rev,
237 :author => $2.strip
241 :author => $2.strip
238 ))
242 ))
239 end
243 end
240 end
244 end
241 blame
245 blame
242 rescue ScmCommandAborted
246 rescue ScmCommandAborted
243 return nil
247 return nil
244 end
248 end
245
249
246 def self.branch_conf_path(path)
250 def self.branch_conf_path(path)
247 bcp = nil
251 bcp = nil
248 m = path.match(%r{^(.*[/\\])\.bzr.*$})
252 m = path.match(%r{^(.*[/\\])\.bzr.*$})
249 if m
253 if m
250 bcp = m[1]
254 bcp = m[1]
251 else
255 else
252 bcp = path
256 bcp = path
253 end
257 end
254 bcp.gsub!(%r{[\/\\]$}, "")
258 bcp.gsub!(%r{[\/\\]$}, "")
255 if bcp
259 if bcp
256 bcp = File.join(bcp, ".bzr", "branch", "branch.conf")
260 bcp = File.join(bcp, ".bzr", "branch", "branch.conf")
257 end
261 end
258 bcp
262 bcp
259 end
263 end
260
264
261 def append_revisions_only
265 def append_revisions_only
262 return @aro if ! @aro.nil?
266 return @aro if ! @aro.nil?
263 @aro = false
267 @aro = false
264 bcp = self.class.branch_conf_path(url)
268 bcp = self.class.branch_conf_path(url)
265 if bcp && File.exist?(bcp)
269 if bcp && File.exist?(bcp)
266 begin
270 begin
267 f = File::open(bcp, "r")
271 f = File::open(bcp, "r")
268 cnt = 0
272 cnt = 0
269 f.each_line do |line|
273 f.each_line do |line|
270 l = line.chomp.to_s
274 l = line.chomp.to_s
271 if l =~ /^\s*append_revisions_only\s*=\s*(\w+)\s*$/
275 if l =~ /^\s*append_revisions_only\s*=\s*(\w+)\s*$/
272 str_aro = $1
276 str_aro = $1
273 if str_aro.upcase == "TRUE"
277 if str_aro.upcase == "TRUE"
274 @aro = true
278 @aro = true
275 cnt += 1
279 cnt += 1
276 elsif str_aro.upcase == "FALSE"
280 elsif str_aro.upcase == "FALSE"
277 @aro = false
281 @aro = false
278 cnt += 1
282 cnt += 1
279 end
283 end
280 if cnt > 1
284 if cnt > 1
281 @aro = false
285 @aro = false
282 break
286 break
283 end
287 end
284 end
288 end
285 end
289 end
286 ensure
290 ensure
287 f.close
291 f.close
288 end
292 end
289 end
293 end
290 @aro
294 @aro
291 end
295 end
292
296
293 def scm_cmd(*args, &block)
297 def scm_cmd(*args, &block)
294 full_args = []
298 full_args = []
295 full_args += args
299 full_args += args
296 full_args_locale = []
300 full_args_locale = []
297 full_args.map do |e|
301 full_args.map do |e|
298 full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
302 full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
299 end
303 end
300 ret = shellout(
304 ret = shellout(
301 self.class.sq_bin + ' ' +
305 self.class.sq_bin + ' ' +
302 full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
306 full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
303 &block
307 &block
304 )
308 )
305 if $? && $?.exitstatus != 0
309 if $? && $?.exitstatus != 0
306 raise ScmCommandAborted, "bzr exited with non-zero status: #{$?.exitstatus}"
310 raise ScmCommandAborted, "bzr exited with non-zero status: #{$?.exitstatus}"
307 end
311 end
308 ret
312 ret
309 end
313 end
310 private :scm_cmd
314 private :scm_cmd
311
315
312 def scm_cmd_no_raise(*args, &block)
316 def scm_cmd_no_raise(*args, &block)
313 full_args = []
317 full_args = []
314 full_args += args
318 full_args += args
315 full_args_locale = []
319 full_args_locale = []
316 full_args.map do |e|
320 full_args.map do |e|
317 full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
321 full_args_locale << scm_iconv(@path_encoding, 'UTF-8', e)
318 end
322 end
319 ret = shellout(
323 ret = shellout(
320 self.class.sq_bin + ' ' +
324 self.class.sq_bin + ' ' +
321 full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
325 full_args_locale.map { |e| shell_quote e.to_s }.join(' '),
322 &block
326 &block
323 )
327 )
324 ret
328 ret
325 end
329 end
326 private :scm_cmd_no_raise
330 private :scm_cmd_no_raise
327
331
328 def bzr_target(path)
332 def bzr_target(path)
329 target(path, false)
333 target(path, false)
330 end
334 end
331 private :bzr_target
335 private :bzr_target
332 end
336 end
333 end
337 end
334 end
338 end
335 end
339 end
General Comments 0
You need to be logged in to leave comments. Login now