copernicium 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/cn +3 -2
- data/lib/RevLog.rb +43 -44
- data/lib/banners.rb +4 -0
- data/lib/pushpull.rb +226 -105
- data/lib/repos.rb +151 -79
- data/lib/required.rb +3 -5
- data/lib/ui.rb +128 -56
- data/lib/workspace.rb +121 -73
- metadata +25 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dba707602c7f877affc0641be13bd03bcf0148da
|
4
|
+
data.tar.gz: 62c8ea960286bcf26035bc94fe437756efa88fdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c07b40b065382971669a01444f0204e1ddef79ada08fb599b56b6b04d1ef9c6433a392be840823d7ba2ed86e5d66669564d5b5dedad4ef4591e5739deb91575
|
7
|
+
data.tar.gz: e27a5d5060d7a074e031b44034a6ad735ee8a74c692f5a951d88d38eb5539fd3881fc8c9b6b9a5caf838e7bfb9949657e95c127c277e2423de9c4ce09e76e194
|
data/bin/cn
CHANGED
data/lib/RevLog.rb
CHANGED
@@ -25,47 +25,47 @@
|
|
25
25
|
# out - success and merged file name/content, or failure and conflict
|
26
26
|
|
27
27
|
module Copernicium
|
28
|
-
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
module RevLog
|
29
|
+
def RevLog.setup(root = Dir.pwd)
|
30
|
+
@@root = root
|
31
|
+
@@cop_path = File.join(@@root, '.cn')
|
32
|
+
@@rev_path = File.join(@@cop_path, 'revs')
|
33
|
+
@@log_path = File.join(@@cop_path, 'logmap.yaml')
|
34
|
+
@@hash_path = File.join(@@cop_path, 'hashmap.yaml')
|
35
|
+
Dir.mkdir(@@cop_path) unless Dir.exist?(@@cop_path)
|
36
|
+
Dir.mkdir(@@rev_path) unless Dir.exist?(@@rev_path)
|
37
|
+
if File.exist?(@@log_path) && File.exist?(@@hash_path)
|
38
|
+
@@logmap = hash_array.merge(YAML.load_file(@@log_path))
|
39
|
+
@@hashmap = hash_array.merge(YAML.load_file(@@hash_path))
|
37
40
|
else
|
38
|
-
|
39
|
-
|
40
|
-
Dir.mkdir(@cop_path) unless File.exist?(@cop_path)
|
41
|
+
@@logmap = hash_array
|
42
|
+
@@hashmap = hash_array
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
def hash_array
|
47
|
+
Hash.new {[]}
|
48
|
+
end
|
47
49
|
|
48
|
-
def add_file(file_name, content)
|
50
|
+
def RevLog.add_file(file_name, content)
|
49
51
|
hash = hash_file(file_name, content)
|
50
|
-
File.open(File.join(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
:filename => file_name}
|
57
|
-
update_log_file
|
52
|
+
File.open(File.join(@@rev_path, hash), 'w') { |f| f.write(content) }
|
53
|
+
@@logmap[file_name] = @@logmap[file_name] << {:time => Time.now,
|
54
|
+
:hash => hash}
|
55
|
+
@@hashmap[hash] = @@hashmap[hash] << {:time => Time.now,
|
56
|
+
:filename => file_name}
|
57
|
+
updatelog
|
58
58
|
return hash
|
59
59
|
end
|
60
60
|
|
61
61
|
## return 1 if succeed, otherwise 0
|
62
|
-
def delete_file(file_id)
|
62
|
+
def RevLog.delete_file(file_id)
|
63
63
|
begin
|
64
|
-
file_name =
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
File.delete(File.join(
|
64
|
+
file_name = @@hashmap[file_id][0][:filename]
|
65
|
+
@@hashmap[file_id].delete_if { |e| e[:filename] == file_name }
|
66
|
+
@@logmap[file_name].delete_if { |e| e[:hash] == file_id }
|
67
|
+
updatelog
|
68
|
+
File.delete(File.join(@@rev_path, file_id))
|
69
69
|
return 1
|
70
70
|
rescue Exception
|
71
71
|
return 0
|
@@ -73,8 +73,8 @@ module Copernicium
|
|
73
73
|
end
|
74
74
|
|
75
75
|
|
76
|
-
def get_file(id)
|
77
|
-
file_path = File.join(
|
76
|
+
def RevLog.get_file(id)
|
77
|
+
file_path = File.join(@@rev_path, id)
|
78
78
|
if File.exist? file_path
|
79
79
|
File.open(file_path, 'r') { |f| return f.read }
|
80
80
|
else
|
@@ -83,40 +83,39 @@ module Copernicium
|
|
83
83
|
end
|
84
84
|
|
85
85
|
|
86
|
-
def diff_files(file_id1, file_id2)
|
86
|
+
def RevLog.diff_files(file_id1, file_id2)
|
87
87
|
Diffy::Diff.new(get_file(file_id1), get_file(file_id2)).to_s()
|
88
88
|
end
|
89
89
|
|
90
|
-
def hash_file(file_name, content)
|
90
|
+
def RevLog.hash_file(file_name, content)
|
91
91
|
Digest::SHA256.hexdigest(file_name + content.to_s)
|
92
92
|
end
|
93
93
|
|
94
|
-
def merge(id1, id2)
|
94
|
+
def RevLog.merge(id1, id2)
|
95
95
|
diff_a = Diffy::Diff.new(get_file(id1), get_file(id2)).each_chunk.to_a
|
96
96
|
return get_file(id2) if diff_a.all? { |d| d[0]!='-'}
|
97
97
|
# return get_file(id1) if diff_a.all? { |d| d[0]!='+'}
|
98
98
|
diff_a
|
99
99
|
end
|
100
100
|
|
101
|
-
def history(file_name)
|
101
|
+
def RevLog.history(file_name)
|
102
102
|
hashs = []
|
103
|
-
|
103
|
+
@@logmap[file_name].each { |m| hashs << m[:hash] }
|
104
104
|
hashs
|
105
105
|
end
|
106
106
|
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
writeFile(File.join(@cop_path, 'hashmap.yaml'), @hashmap.to_yaml)
|
107
|
+
def RevLog.updatelog
|
108
|
+
File.open(@@log_path, 'w') { |f| f.write(@@logmap.to_yaml) }
|
109
|
+
File.open(@@hash_path, 'w') { |f| f.write(@@hashmap.to_yaml) }
|
111
110
|
end
|
112
111
|
|
113
|
-
# def alterFile(fileObject, fileReferenceString, versionReferenceString)
|
112
|
+
# def RevLog.alterFile(fileObject, fileReferenceString, versionReferenceString)
|
114
113
|
# end
|
115
114
|
|
116
|
-
# def deleteFileVersion(fileReferenceString, versionReferenceString)
|
115
|
+
# def RevLog.deleteFileVersion(fileReferenceString, versionReferenceString)
|
117
116
|
# end
|
118
117
|
|
119
|
-
# def viewFileHistory(fileReferenceString)
|
118
|
+
# def RevLog.viewFileHistory(fileReferenceString)
|
120
119
|
# end
|
121
120
|
end
|
122
121
|
end
|
data/lib/banners.rb
CHANGED
@@ -34,6 +34,7 @@ Commands:
|
|
34
34
|
branch [opt] [branchname]
|
35
35
|
-r | rename current branch
|
36
36
|
-c | create a new branch
|
37
|
+
-d | delete a branch
|
37
38
|
merge <branch name>
|
38
39
|
clone <remote url>
|
39
40
|
push [remote name]
|
@@ -47,3 +48,6 @@ Note: [optional] <required>
|
|
47
48
|
|
48
49
|
EOS
|
49
50
|
|
51
|
+
REPO_WARNING = <<-EOS
|
52
|
+
You are not currently in a Copernicium repo... run `cn init` to create one!
|
53
|
+
EOS
|
data/lib/pushpull.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# CSC 253
|
3
3
|
# PushPull Module
|
4
4
|
# November 6, 2015
|
5
|
+
require 'net/ssh'
|
6
|
+
require 'net/scp'
|
5
7
|
|
6
8
|
|
7
9
|
module Copernicium
|
@@ -26,155 +28,274 @@ module Copernicium
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
|
31
|
+
# Function: connect()
|
32
|
+
#
|
33
|
+
# Description:
|
34
|
+
# a net/ssh wrapper, if given a block will execute block on server, otherwise tests connection.
|
35
|
+
#
|
36
|
+
# remote: the remote server, formatted "my.server"
|
37
|
+
# user: the user to connect as
|
38
|
+
def connect(remote, user, &block)
|
30
39
|
exit_code = false
|
31
40
|
if(block.nil?)
|
32
41
|
begin
|
33
|
-
|
42
|
+
Net::SSH.start(remote, user) do |ssh|
|
43
|
+
result = ssh.exec!("echo Successful Connection!")
|
44
|
+
puts result
|
45
|
+
exit_code = true;
|
46
|
+
end
|
47
|
+
rescue
|
48
|
+
begin
|
34
49
|
print "Username for remote repo?: "
|
35
50
|
user = (STDIN.readline).strip
|
36
|
-
|
37
|
-
if(passwd.nil?)
|
51
|
+
|
38
52
|
print "Password for #{user}: "
|
39
53
|
passwd = (STDIN.noecho(&:gets)).strip
|
40
54
|
puts
|
55
|
+
|
56
|
+
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
57
|
+
result = ssh.exec!("echo Successful Connection!")
|
58
|
+
puts result
|
59
|
+
exit_code = true;
|
60
|
+
end
|
61
|
+
rescue
|
62
|
+
puts "Unsuccessful Connection"
|
41
63
|
end
|
42
|
-
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
43
|
-
result = ssh.exec!("echo Successful Connection!")
|
44
|
-
puts result
|
45
|
-
exit_code = true;
|
46
|
-
end
|
47
|
-
rescue
|
48
|
-
puts "Connection Unsuccessful"
|
49
64
|
end
|
50
65
|
else
|
51
66
|
begin
|
52
|
-
|
67
|
+
Net::SSH.start(remote, user) do |ssh|
|
68
|
+
yield ssh
|
69
|
+
end
|
70
|
+
exit_code = true;
|
71
|
+
rescue
|
72
|
+
begin
|
53
73
|
print "Username for remote repo: "
|
54
74
|
user = (STDIN.readline).strip
|
55
|
-
|
56
|
-
if(passwd.nil?)
|
75
|
+
|
57
76
|
print "Password for #{user}: "
|
58
77
|
passwd = (STDIN.noecho(&:gets)).strip
|
59
78
|
puts
|
79
|
+
|
80
|
+
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
81
|
+
yield ssh
|
82
|
+
end
|
83
|
+
exit_code = true;
|
84
|
+
rescue
|
85
|
+
puts "Unable to execute command!"
|
60
86
|
end
|
61
|
-
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
62
|
-
yield ssh
|
63
|
-
end
|
64
|
-
exit_code = true;
|
65
|
-
rescue
|
66
|
-
puts "Unable to execute command!"
|
67
87
|
end
|
68
88
|
end
|
69
89
|
return exit_code
|
70
90
|
end
|
71
91
|
|
72
|
-
|
92
|
+
# Function: transfer()
|
93
|
+
#
|
94
|
+
# Description:
|
95
|
+
# a net/scp wrapper to copy to server
|
96
|
+
#
|
97
|
+
# remote: the remote server and directory to pull from, formatted "my.server:/the/location/we/want"
|
98
|
+
# user: the user to connect as
|
99
|
+
def transfer(remote, user, &block)
|
73
100
|
exit_code = false
|
74
|
-
if(user.nil?)
|
75
|
-
print "Username for remote repo: "
|
76
|
-
user = (STDIN.readline).strip
|
77
|
-
end
|
78
|
-
if(passwd.nil?)
|
79
|
-
print "Password for #{user}: "
|
80
|
-
passwd = (STDIN.noecho(&:gets)).strip
|
81
|
-
puts
|
82
|
-
end
|
83
101
|
begin
|
84
|
-
Net::SCP.start(remote, user
|
85
|
-
scp
|
102
|
+
Net::SCP.start(remote, user) do |scp|
|
103
|
+
yield scp
|
86
104
|
end
|
87
105
|
exit_code = true
|
88
106
|
rescue
|
89
|
-
|
107
|
+
begin
|
108
|
+
print "Username for remote repo: "
|
109
|
+
user = (STDIN.readline).strip
|
110
|
+
|
111
|
+
print "Password for #{user}: "
|
112
|
+
passwd = (STDIN.noecho(&:gets)).strip
|
113
|
+
puts
|
114
|
+
|
115
|
+
Net::SCP.start(remote, user, :passwd => passwd) do |scp|
|
116
|
+
yield scp
|
117
|
+
end
|
118
|
+
exit_code = true
|
119
|
+
rescue
|
120
|
+
puts "Unable to upload file!"
|
121
|
+
end
|
90
122
|
end
|
91
123
|
end
|
92
124
|
|
93
|
-
|
125
|
+
# Function: fetch()
|
126
|
+
#
|
127
|
+
# Description:
|
128
|
+
# a net/scp wrapper to copy from server, can take a block or do a one-off copy without one
|
129
|
+
#
|
130
|
+
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
131
|
+
# dest: what we want of the branch, not needed for blocked calls
|
132
|
+
# local: where we want to put the file, not needed for blocked calls
|
133
|
+
# user: the user to connect as
|
134
|
+
def fetch(remote, dest, local, user, &block)
|
94
135
|
exit_code = false
|
95
|
-
if(
|
96
|
-
|
97
|
-
|
136
|
+
if(block.nil?)
|
137
|
+
begin
|
138
|
+
Net::SCP.start(remote, user, :password => passwd) do |scp|
|
139
|
+
scp.download!(dest, local, :recursive => true)
|
140
|
+
end
|
141
|
+
exit_code = true
|
142
|
+
rescue
|
143
|
+
begin
|
144
|
+
print "Username for remote repo: "
|
145
|
+
user = (STDIN.readline).strip
|
146
|
+
|
147
|
+
print "Password for #{user}: "
|
148
|
+
passwd = (STDIN.noecho(&:gets)).strip
|
149
|
+
puts
|
150
|
+
|
151
|
+
Net::SCP.start(remote, user, :password => passwd) do |scp|
|
152
|
+
scp.download!(dest, local, :recursive => true)
|
153
|
+
end
|
154
|
+
exit_code = true
|
155
|
+
rescue
|
156
|
+
puts "Unable to fetch file(s)!"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
else
|
160
|
+
begin
|
161
|
+
Net::SCP.start(remote, user, :password => passwd) do |scp|
|
162
|
+
yield scp
|
163
|
+
end
|
164
|
+
exit_code = true
|
165
|
+
rescue
|
166
|
+
begin
|
167
|
+
print "Username for remote repo: "
|
168
|
+
user = (STDIN.readline).strip
|
169
|
+
|
170
|
+
print "Password for #{user}: "
|
171
|
+
passwd = (STDIN.noecho(&:gets)).strip
|
172
|
+
puts
|
173
|
+
|
174
|
+
Net::SCP.start(remote, user, :password => passwd) do |scp|
|
175
|
+
yield scp
|
176
|
+
end
|
177
|
+
exit_code = true
|
178
|
+
rescue
|
179
|
+
puts "Unable to fetch file(s)!"
|
180
|
+
end
|
181
|
+
end
|
98
182
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
183
|
+
return exit_code
|
184
|
+
end
|
185
|
+
|
186
|
+
# Function: push()
|
187
|
+
#
|
188
|
+
# Description:
|
189
|
+
# pushes local changes on the current branch to a remote branch
|
190
|
+
#
|
191
|
+
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
192
|
+
# branch: the branch that we are pushing to
|
193
|
+
# user: the user to connect as
|
194
|
+
def push(remote, branch, user)
|
195
|
+
# check contents of folder for .cn, fail if not present and remove otherwise
|
196
|
+
dest = remote.split(':');
|
197
|
+
contents = Dir.entries(Dir.pwd)
|
198
|
+
if(!content.include? '.cn')
|
199
|
+
puts 'failed to push to remote, not an initialized Copernicium repo'
|
200
|
+
return
|
201
|
+
else
|
202
|
+
contents = contents.delete_if{|x| (x.eql? '.cn') || (x.eql? '.') || (x.eql? '..')}
|
103
203
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
204
|
+
|
205
|
+
connect(dest[0], user) do |session|
|
206
|
+
session.exec!("cd #{dest[1]}")
|
207
|
+
result = session.exec!('ls .cn')
|
208
|
+
if(result.strip.eql? '')
|
209
|
+
puts 'remote directory not a Copernicium repo'
|
210
|
+
return
|
107
211
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
212
|
+
session.exec!("cn branch .temp_push_#{user}")
|
213
|
+
session.exec!("find . ! -name \".cn\" -exec rm -r {} \\;")
|
214
|
+
|
215
|
+
# Move the files over to the remote branch
|
216
|
+
transfer(dest[0], user) do |scp|
|
217
|
+
contents.each do |x|
|
218
|
+
scp.upload!(Dir.pwd+'/'+x, dest[1], :recursive => true)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Commit the files and merge the branches
|
223
|
+
session.exec!('cn add .')
|
224
|
+
session.exec!('cn commit -m \'Temp commit for push\'')
|
225
|
+
session.exec!('cn checkout #{branch}')
|
226
|
+
session.exec!("cn merge .temp_push_#{user}")
|
227
|
+
session.exec!("cn branch -r temp_push_#{user}")
|
111
228
|
end
|
112
229
|
|
113
|
-
|
230
|
+
puts "Successfully pushed to #{remote}"
|
114
231
|
end
|
115
232
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
#
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# end
|
136
|
-
#############################################################
|
137
|
-
end
|
233
|
+
# Function: pull()
|
234
|
+
#
|
235
|
+
# Description:
|
236
|
+
# pulls remote changes to the current branch from remote branch
|
237
|
+
#
|
238
|
+
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
239
|
+
# branch: the branch that we are pushing to
|
240
|
+
# user: the user to connect as
|
241
|
+
def pull(remote, branch, user)
|
242
|
+
# check contents of folder for .cn, fail if not present and remove otherwise
|
243
|
+
crbr = Repos.new.current_branch() # assumed function
|
244
|
+
dest = remote.split(':');
|
245
|
+
contents = Dir.entries(Dir.pwd)
|
246
|
+
if(!content.include? '.cn')
|
247
|
+
puts 'failed to pull from remote, not an initialized Copernicium repo'
|
248
|
+
return
|
249
|
+
else
|
250
|
+
contents = contents.delete_if{|x| (x.eql? '.cn') || (x.eql? '.') || (x.eql? '..')}
|
251
|
+
end
|
138
252
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
# connect(remote) do |x|
|
145
|
-
# result = test.exec!("<call to Repos to diff the snapshots>")
|
146
|
-
# end
|
147
|
-
# print "Username for remote repo: "
|
148
|
-
# user = (STDIN.readline).strip
|
149
|
-
# print "Password for #{user}: "
|
150
|
-
# passwd = (STDIN.noecho(&:gets)).strip
|
151
|
-
# puts
|
152
|
-
# for result.each do |x|
|
153
|
-
# fetch(remote, remote_dir, "./#{x}", user, passwd)
|
154
|
-
# RevLog::Revlog.merge(x, local_x)
|
155
|
-
# File.delete(x)
|
156
|
-
# end
|
157
|
-
#############################################################
|
158
|
-
end
|
253
|
+
# create a new branch and clean it in prep for the incoming files
|
254
|
+
system "cn branch .temp_pull_#{user}"
|
255
|
+
contents.each do |x|
|
256
|
+
system "rm -r #{x}"
|
257
|
+
end
|
159
258
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
259
|
+
# get the file list from the remote directory
|
260
|
+
connect(dest[0], user) do |session|
|
261
|
+
session.exec!("cd #{dest[1]}")
|
262
|
+
session.exec!("cn checkout #{branch}")
|
263
|
+
collection = session.exec!("ls | cat")
|
264
|
+
end
|
265
|
+
collection = collection.split('\n')
|
266
|
+
if(!collection.include? '.cn')
|
267
|
+
puts 'failed to pull from remote, remote folder not an initialized Copernicium repo'
|
268
|
+
return
|
269
|
+
else
|
270
|
+
collection = collection.delete_if{|x| (x.eql? '.cn') || (x.eql? '.') || (x.eql? '..')}
|
165
271
|
end
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
272
|
+
|
273
|
+
# fetch the files from the remote directory and merge them to the branch
|
274
|
+
fetch(dest[0], nil, nil, user) do |scp|
|
275
|
+
collection.each do |x|
|
276
|
+
scp.download!(dest[1]+'/'+x, Dir.pwd, :recursive => true)
|
277
|
+
end
|
170
278
|
end
|
279
|
+
system "cn add ."
|
280
|
+
system "cn commit -m \'Temp commit for pull\'"
|
281
|
+
system "cn checkout #{crbr}"
|
282
|
+
system "cn merge .temp_pull_#{user}"
|
283
|
+
system "cn branch -r .temp_pull_#{user}"
|
284
|
+
puts "Successfully pulled from #{remote}"
|
285
|
+
end
|
286
|
+
|
287
|
+
# Function: clone()
|
288
|
+
#
|
289
|
+
# Description:
|
290
|
+
# Grabs a repository from a remote server
|
291
|
+
#
|
292
|
+
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
293
|
+
# user: the user to connect as
|
294
|
+
def clone(remote, user = nil)
|
295
|
+
exit_code = false
|
296
|
+
dest = remote.split(':')
|
171
297
|
begin
|
172
|
-
fetch(
|
173
|
-
nd = File.basename(dir)
|
174
|
-
################ Needs Repos Functionality! #################
|
175
|
-
# Initializes the folder as a Repo
|
176
|
-
# Repos::Repos.make_branch(nd)
|
177
|
-
#############################################################
|
298
|
+
fetch(dest[0], dest[1], Dir.pwd, user)
|
178
299
|
exit_code = true;
|
179
300
|
rescue
|
180
301
|
puts "Failed to clone the remote branch!"
|