rscm 0.4.5 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +12 -0
- data/README +14 -0
- data/Rakefile +4 -24
- data/lib/rscm.rb +1 -2
- data/lib/rscm/base.rb +289 -281
- data/lib/rscm/command_line.rb +135 -112
- data/lib/rscm/revision.rb +63 -166
- data/lib/rscm/revision_file.rb +8 -2
- data/lib/rscm/revision_poller.rb +78 -67
- data/lib/rscm/revisions.rb +79 -0
- data/lib/rscm/scm/clearcase.rb +11 -9
- data/lib/rscm/scm/cvs.rb +374 -352
- data/lib/rscm/scm/cvs_log_parser.rb +1 -0
- data/lib/rscm/scm/darcs.rb +9 -0
- data/lib/rscm/scm/perforce.rb +216 -149
- data/lib/rscm/scm/subversion.rb +44 -24
- data/lib/rscm/scm/subversion_log_parser.rb +37 -51
- data/lib/rscm/time_ext.rb +0 -1
- data/lib/rscm/version.rb +2 -2
- data/test/rscm/command_line_test.rb +7 -5
- data/test/rscm/compatibility/config.yml +4 -4
- data/test/rscm/compatibility/cvs_metaproject/diff.txt +52 -0
- data/test/rscm/compatibility/cvs_metaproject/file.txt +48 -0
- data/test/rscm/compatibility/cvs_metaproject/old.yml +13 -0
- data/test/rscm/compatibility/full.rb +2 -223
- data/test/rscm/compatibility/p4_gfx/files_0.yml +10 -0
- data/test/rscm/compatibility/p4_gfx/old.yml +26 -0
- data/test/rscm/compatibility/p4_gfx/revisions.yml +24 -0
- data/test/rscm/compatibility/p4_gfx/scm.yml +4 -0
- data/test/rscm/compatibility/rscm_engine.rb +197 -0
- data/test/rscm/compatibility/subversion_rscm/diff.txt +12 -0
- data/test/rscm/compatibility/subversion_rscm/file.txt +567 -0
- data/test/rscm/compatibility/subversion_rscm/old.yml +14 -0
- data/test/rscm/compatibility/subversion_rscm/revisions.yml +17 -0
- data/test/rscm/compatibility/subversion_rscm/scm.yml +1 -0
- data/test/rscm/revision_file_test.rb +10 -0
- data/test/rscm/revision_poller_test.rb +91 -0
- data/test/rscm/revision_test.rb +22 -117
- data/test/rscm/revisions_test.rb +80 -0
- data/test/rscm/scm/cvs_log_parser_test.rb +569 -567
- data/test/rscm/scm/cvs_test.rb +6 -3
- data/test/rscm/scm/darcs_test.rb +4 -7
- data/test/rscm/scm/perforce_test.rb +6 -2
- data/test/rscm/scm/star_team_test.rb +10 -0
- data/test/rscm/scm/subversion_log_parser_test.rb +38 -5
- data/test/rscm/scm/subversion_test.rb +2 -3
- data/test/rscm/test_helper.rb +41 -2
- data/testproject/damagecontrolled/build.xml +154 -154
- data/testproject/damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java +6 -6
- metadata +19 -7
- data/lib/rscm/historic_file.rb +0 -30
- data/test/rscm/compatibility/damage_control_minimal.rb +0 -104
- data/test/rscm/revision_fixture.rb +0 -20
- data/test/rscm/revisions.yaml +0 -42
- data/test/rscm/scm/star_team.rb +0 -36
data/lib/rscm/scm/darcs.rb
CHANGED
@@ -7,6 +7,15 @@ module RSCM
|
|
7
7
|
# See http://progetti.arstecnica.it/tailor/browser/vcpx/darcs.py
|
8
8
|
attr_accessor :dir
|
9
9
|
|
10
|
+
def installed?
|
11
|
+
begin
|
12
|
+
darcs("--version", {})
|
13
|
+
true
|
14
|
+
rescue
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
10
19
|
def initialize(dir=".")
|
11
20
|
@dir = File.expand_path(dir)
|
12
21
|
end
|
data/lib/rscm/scm/perforce.rb
CHANGED
@@ -1,149 +1,216 @@
|
|
1
|
-
# TODO
|
2
|
-
# Support int revision numbers AND dates
|
3
|
-
# Leverage default P4 client settings (optional)
|
4
|
-
|
5
|
-
require 'rscm/base'
|
6
|
-
require 'rscm/path_converter'
|
7
|
-
require 'rscm/line_editor'
|
8
|
-
|
9
|
-
require 'fileutils'
|
10
|
-
require 'time'
|
11
|
-
require 'socket'
|
12
|
-
|
13
|
-
module RSCM
|
14
|
-
class Perforce < Base
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
1
|
+
# TODO
|
2
|
+
# Support int revision numbers AND dates
|
3
|
+
# Leverage default P4 client settings (optional)
|
4
|
+
|
5
|
+
require 'rscm/base'
|
6
|
+
require 'rscm/path_converter'
|
7
|
+
require 'rscm/line_editor'
|
8
|
+
|
9
|
+
require 'fileutils'
|
10
|
+
require 'time'
|
11
|
+
require 'socket'
|
12
|
+
|
13
|
+
module RSCM
|
14
|
+
class Perforce < Base
|
15
|
+
unless defined? DATE_FORMAT
|
16
|
+
DATE_FORMAT = "%Y/%m/%d:%H:%M:%S"
|
17
|
+
# Doesn't work for empty messages, (Like 21358 in Aslak's P4 repo)
|
18
|
+
CHANGELIST_PATTERN = /^Change \d+ by (.*)@.* on (.*)\n\n(.*)\n\nAffected files ...\n\n(.*)/m
|
19
|
+
# But this one does
|
20
|
+
CHANGELIST_PATTERN_NO_MSG = /^Change \d+ by (.*)@.* on (.*)\n\nAffected files ...\n\n(.*)/m
|
21
|
+
|
22
|
+
STATES = {
|
23
|
+
"add" => RevisionFile::ADDED,
|
24
|
+
"edit" => RevisionFile::MODIFIED,
|
25
|
+
"delete" => RevisionFile::DELETED
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :view
|
30
|
+
attr_accessor :username
|
31
|
+
attr_accessor :password
|
32
|
+
|
33
|
+
def installed?
|
34
|
+
begin
|
35
|
+
execute("p4 info", {})
|
36
|
+
true
|
37
|
+
rescue
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def revisions(from_identifier=Time.new.utc, options={})
|
43
|
+
raise "from_identifer cannot be nil" if from_identifier.nil?
|
44
|
+
set_utc_offset(options)
|
45
|
+
view_as_regexp = "^" + @view.gsub(/\.\.\./, "(.*)")
|
46
|
+
relative_path_pattern = Regexp.new(view_as_regexp)
|
47
|
+
|
48
|
+
from_identifier = Time.epoch unless from_identifier
|
49
|
+
from_identifier = Time.epoch if (from_identifier.is_a? Time and from_identifier < Time.epoch)
|
50
|
+
from = revision_spec(from_identifier + 1) # We have to add 1 because of the contract of this method.
|
51
|
+
|
52
|
+
to_identifier = options[:to_identifier] ? options[:to_identifier] : Time.infinity
|
53
|
+
to = revision_spec(to_identifier - 1) # We have to subtract 1 because of the contract of this method.
|
54
|
+
|
55
|
+
cmd = "p4 #{p4_opts(false)} changes #{@view}@#{from},#{to}"
|
56
|
+
revisions = Revisions.new
|
57
|
+
revisions.cmd = cmd if store_revisions_command?
|
58
|
+
|
59
|
+
changes = execute(cmd, options) do |io|
|
60
|
+
io.read
|
61
|
+
end
|
62
|
+
|
63
|
+
changes.each do |line|
|
64
|
+
revision = nil
|
65
|
+
identifier = line.match(/^Change (\d+)/)[1].to_i
|
66
|
+
|
67
|
+
execute("p4 #{p4_opts(false)} describe -s #{identifier}", options) do |io|
|
68
|
+
log = io.read
|
69
|
+
|
70
|
+
if log =~ CHANGELIST_PATTERN
|
71
|
+
developer, time, message, files = $1, $2, $3, $4
|
72
|
+
elsif log =~ CHANGELIST_PATTERN_NO_MSG
|
73
|
+
developer, time, files = $1, $2, $3
|
74
|
+
else
|
75
|
+
puts "PARSE ERROR:"
|
76
|
+
puts log
|
77
|
+
puts "\nDIDN'T MATCH:"
|
78
|
+
puts CHANGELIST_PATTERN
|
79
|
+
end
|
80
|
+
|
81
|
+
# The parsed time doesn't have timezone info. We'll tweak it.
|
82
|
+
time = Time.parse(time + " UTC") - @utc_offset
|
83
|
+
|
84
|
+
files.each_line do |line|
|
85
|
+
if line =~ /^\.\.\. (\/\/.+)#(\d+) (.+)/
|
86
|
+
depot_path = $1
|
87
|
+
file_identifier = $2.to_i
|
88
|
+
state = $3.strip
|
89
|
+
if(STATES[state])
|
90
|
+
if(depot_path =~ relative_path_pattern)
|
91
|
+
relative_path = $1
|
92
|
+
|
93
|
+
if revision.nil?
|
94
|
+
revision = Revision.new
|
95
|
+
revision.identifier = identifier
|
96
|
+
revision.developer = developer
|
97
|
+
revision.message = message
|
98
|
+
revision.time = time
|
99
|
+
revisions.add revision
|
100
|
+
end
|
101
|
+
|
102
|
+
file = RevisionFile.new
|
103
|
+
file.path = relative_path
|
104
|
+
file.native_revision_identifier = file_identifier
|
105
|
+
file.previous_native_revision_identifier = file.native_revision_identifier-1
|
106
|
+
file.status = STATES[state]
|
107
|
+
revision.add file
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
revisions
|
115
|
+
end
|
116
|
+
|
117
|
+
def destroy_working_copy(options={})
|
118
|
+
execute("p4 #{p4_opts(false)} client -d #{client_name}", options)
|
119
|
+
end
|
120
|
+
|
121
|
+
def open(revision_file, options={}, &block)
|
122
|
+
path = @view.gsub(/\.\.\./, revision_file.path) # + "@" + revision_file.native_revision_identifier
|
123
|
+
cmd = "p4 #{p4_opts(false)} print -q #{path}"
|
124
|
+
execute(cmd, options) do |io|
|
125
|
+
block.call io
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def diff
|
130
|
+
#p4 diff2 //depot/trunk/build.xml@26405 //depot/trunk/build.xml@26409
|
131
|
+
end
|
132
|
+
|
133
|
+
protected
|
134
|
+
|
135
|
+
def checkout_silent(to_identifier, options)
|
136
|
+
checkout_dir = PathConverter.filepath_to_nativepath(@checkout_dir, false)
|
137
|
+
FileUtils.mkdir_p(@checkout_dir)
|
138
|
+
|
139
|
+
ensure_client(options)
|
140
|
+
execute("p4 #{p4_opts} sync #{@view}@#{to_identifier}", options)
|
141
|
+
end
|
142
|
+
|
143
|
+
def ignore_paths
|
144
|
+
[]
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def p4_opts(with_client=true)
|
150
|
+
user_opt = @username.to_s.empty? ? "" : "-u #{@username}"
|
151
|
+
password_opt = @password.to_s.empty? ? "" : "-P #{@password}"
|
152
|
+
client_opt = with_client ? "-c \"#{client_name}\"" : ""
|
153
|
+
"#{user_opt} #{password_opt} #{client_opt}"
|
154
|
+
end
|
155
|
+
|
156
|
+
def client_name
|
157
|
+
raise "checkout_dir not set" unless @checkout_dir
|
158
|
+
Socket.gethostname + ":" + @checkout_dir
|
159
|
+
end
|
160
|
+
|
161
|
+
def ensure_client(options)
|
162
|
+
create_client(options)
|
163
|
+
end
|
164
|
+
|
165
|
+
def create_client(options)
|
166
|
+
options = {:mode => "w+"}.merge(options)
|
167
|
+
FileUtils.mkdir_p(@checkout_dir)
|
168
|
+
execute("p4 #{p4_opts(false)} client -i", options) do |io|
|
169
|
+
io.puts(client_spec)
|
170
|
+
io.close_write
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def client_spec
|
175
|
+
<<-EOF
|
176
|
+
Client: #{client_name}
|
177
|
+
Owner: #{@username}
|
178
|
+
Host: #{Socket.gethostname}
|
179
|
+
Description: RSCM client
|
180
|
+
Root: #{@checkout_dir}
|
181
|
+
Options: noallwrite noclobber nocompress unlocked nomodtime normdir
|
182
|
+
LineEnd: local
|
183
|
+
View: #{@view} //#{client_name}/...
|
184
|
+
EOF
|
185
|
+
end
|
186
|
+
|
187
|
+
def revision_spec(identifier)
|
188
|
+
if identifier.is_a?(Time)
|
189
|
+
# The p4 client uses local time, but rscm uses utc
|
190
|
+
# We have to convert to local time
|
191
|
+
identifier += @utc_offset
|
192
|
+
identifier.strftime(DATE_FORMAT)
|
193
|
+
else
|
194
|
+
identifier.to_i
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Queries the server for the time offset. Required in order to get proper
|
199
|
+
# timezone for revisions
|
200
|
+
def set_utc_offset(options)
|
201
|
+
unless @utc_offset
|
202
|
+
execute("p4 #{p4_opts(false)} info", options) do |io|
|
203
|
+
io.each do |line|
|
204
|
+
if line =~ /^Server date: (.*)/
|
205
|
+
server_time = Time.parse($1)
|
206
|
+
@utc_offset = server_time.utc_offset
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
raise "Couldn't get server's UTC offset" if @utc_offset.nil?
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
data/lib/rscm/scm/subversion.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rscm/base'
|
|
2
2
|
require 'rscm/path_converter'
|
3
3
|
require 'rscm/line_editor'
|
4
4
|
require 'rscm/scm/subversion_log_parser'
|
5
|
+
require 'stringio'
|
5
6
|
|
6
7
|
module RSCM
|
7
8
|
|
@@ -27,17 +28,30 @@ module RSCM
|
|
27
28
|
@username = ""
|
28
29
|
@password = ""
|
29
30
|
end
|
31
|
+
|
32
|
+
def path
|
33
|
+
@path ||= ""
|
34
|
+
end
|
35
|
+
|
36
|
+
def installed?
|
37
|
+
begin
|
38
|
+
svn("--version", {})
|
39
|
+
true
|
40
|
+
rescue
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
30
44
|
|
31
45
|
def to_identifier(raw_identifier)
|
32
46
|
raw_identifier.to_i
|
33
47
|
end
|
34
48
|
|
35
49
|
def add(relative_filename, options={})
|
36
|
-
svn("add #{relative_filename}", options)
|
50
|
+
svn("add #{checkout_dir}/#{relative_filename}", options)
|
37
51
|
end
|
38
52
|
|
39
53
|
def move(relative_src, relative_dest, options={})
|
40
|
-
svn("mv #{relative_src} #{relative_dest}", options)
|
54
|
+
svn("mv #{checkout_dir}/#{relative_src} #{checkout_dir}/#{relative_dest}", options)
|
41
55
|
end
|
42
56
|
|
43
57
|
def transactional?
|
@@ -56,24 +70,25 @@ module RSCM
|
|
56
70
|
def commit(message, options={})
|
57
71
|
svn(commit_command(message), options)
|
58
72
|
# We have to do an update to get the local revision right
|
59
|
-
|
73
|
+
checkout_silent(nil, options)
|
60
74
|
end
|
61
75
|
|
62
76
|
def label
|
63
77
|
local_revision_identifier.to_s
|
64
78
|
end
|
65
79
|
|
66
|
-
def diff(
|
67
|
-
cmd = "svn diff --revision #{
|
80
|
+
def diff(path, from, to, options={}, &block)
|
81
|
+
cmd = "svn diff --revision #{from}:#{to} \"#{url}/#{path}\""
|
68
82
|
execute(cmd, options) do |io|
|
69
|
-
return(
|
83
|
+
return(block.call(io))
|
70
84
|
end
|
71
85
|
end
|
72
86
|
|
73
|
-
def open(
|
74
|
-
|
87
|
+
def open(path, native_revision_identifier, options={}, &block)
|
88
|
+
raise "native_revision_identifier cannot be nil" if native_revision_identifier.nil?
|
89
|
+
cmd = "svn cat #{url}/#{path}@#{native_revision_identifier}"
|
75
90
|
execute(cmd, options) do |io|
|
76
|
-
return(
|
91
|
+
return(block.call(io))
|
77
92
|
end
|
78
93
|
end
|
79
94
|
|
@@ -123,10 +138,10 @@ module RSCM
|
|
123
138
|
native_path = PathConverter.filepath_to_nativepath(svnrootdir, false)
|
124
139
|
mkdir_p(PathConverter.nativepath_to_filepath(native_path))
|
125
140
|
svnadmin("create #{native_path}", options)
|
126
|
-
if(
|
141
|
+
if(path != "")
|
127
142
|
options = options.dup.merge({:dir => "."})
|
128
143
|
# create the directories
|
129
|
-
paths =
|
144
|
+
paths = path.split("/")
|
130
145
|
paths.each_with_index do |p,i|
|
131
146
|
p = paths[0..i]
|
132
147
|
u = "#{repourl}/#{p.join('/')}"
|
@@ -153,12 +168,13 @@ module RSCM
|
|
153
168
|
not_already_commented
|
154
169
|
end
|
155
170
|
|
156
|
-
def import_central(options)
|
157
|
-
import_cmd = "import #{url} -m \"#{options[:message]}\""
|
171
|
+
def import_central(dir, options={})
|
172
|
+
import_cmd = "import #{dir} #{url} -m \"#{options[:message]}\""
|
158
173
|
svn(import_cmd, options)
|
159
174
|
end
|
160
175
|
|
161
|
-
def revisions(from_identifier, options={})
|
176
|
+
def revisions(from_identifier=Time.new.utc, options={})
|
177
|
+
raise "from_identifer cannot be nil" if from_identifier.nil?
|
162
178
|
options = {
|
163
179
|
:from_identifier => from_identifier,
|
164
180
|
:to_identifier => Time.infinity,
|
@@ -170,9 +186,11 @@ module RSCM
|
|
170
186
|
revisions = nil
|
171
187
|
command = "svn #{changes_command(options[:from_identifier], options[:to_identifier], options[:relative_path])}"
|
172
188
|
execute(command, options) do |stdout|
|
173
|
-
|
189
|
+
stdout = StringIO.new(stdout.read)
|
190
|
+
parser = SubversionLogParser.new(stdout, @url, options[:from_identifier], options[:to_identifier], path)
|
174
191
|
revisions = parser.parse_revisions
|
175
192
|
end
|
193
|
+
revisions.cmd = command if store_revisions_command?
|
176
194
|
revisions
|
177
195
|
end
|
178
196
|
|
@@ -208,7 +226,7 @@ module RSCM
|
|
208
226
|
|
209
227
|
def local_revision_identifier(options)
|
210
228
|
local_revision_identifier = nil
|
211
|
-
svn("info", options) do |line|
|
229
|
+
svn("info #{quoted_checkout_dir}", options) do |line|
|
212
230
|
if(line =~ /Revision: ([0-9]*)/)
|
213
231
|
return $1.to_i
|
214
232
|
end
|
@@ -287,21 +305,17 @@ module RSCM
|
|
287
305
|
end
|
288
306
|
|
289
307
|
def checkout_command(to_identifier)
|
290
|
-
|
291
|
-
raise "checkout_dir not set" if cd == ""
|
292
|
-
"checkout #{login_options} #{url} #{cd} #{revision_option(nil,to_identifier)}"
|
308
|
+
"checkout #{login_options} #{url} #{revision_option(nil,to_identifier)} #{quoted_checkout_dir}"
|
293
309
|
end
|
294
310
|
|
295
311
|
def update_command(to_identifier)
|
296
|
-
"update #{login_options} #{revision_option(nil,to_identifier)}"
|
312
|
+
"update #{login_options} #{revision_option(nil,to_identifier)} #{quoted_checkout_dir}"
|
297
313
|
end
|
298
314
|
|
299
315
|
def changes_command(from_identifier, to_identifier, relative_path)
|
300
316
|
# http://svnbook.red-bean.com/svnbook-1.1/svn-book.html#svn-ch-3-sect-3.3
|
301
317
|
# file_list = files.join('\n')
|
302
|
-
|
303
|
-
cmd = "log --verbose #{login_options} #{revision_option(from_identifier, to_identifier)} #{full_url}"
|
304
|
-
cmd
|
318
|
+
"log --verbose #{login_options} #{revision_option(from_identifier, to_identifier)} #{@url}"
|
305
319
|
end
|
306
320
|
|
307
321
|
def login_options
|
@@ -352,7 +366,13 @@ module RSCM
|
|
352
366
|
end
|
353
367
|
|
354
368
|
def commit_command(message)
|
355
|
-
"commit #{login_options} --force-log -m \"#{message}\""
|
369
|
+
"commit #{login_options} --force-log -m \"#{message}\" #{quoted_checkout_dir}"
|
370
|
+
end
|
371
|
+
|
372
|
+
def quoted_checkout_dir
|
373
|
+
cd = '"' + PathConverter.filepath_to_nativepath(checkout_dir, false) + '"'
|
374
|
+
raise "checkout_dir not set" if cd == ""
|
375
|
+
cd
|
356
376
|
end
|
357
377
|
|
358
378
|
def local?
|