stg 0.1.3 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a24fa114435be573b5b125dc7631052ba02e9b87c071d900aef8be5dd3c771e3
4
- data.tar.gz: ae2e3189797eb7f737bf2e6f44502458dbf0567d69c8659a1adf18c5a7619a0b
3
+ metadata.gz: 0f993bbd2bd4575637beb24485c54a88a2679551000551df0f1b1a552249922f
4
+ data.tar.gz: cca41c04c1ab146a16055debbf6364081993d4afb647222865a219d88d9a40bb
5
5
  SHA512:
6
- metadata.gz: e9b91105669be9f1b50129e3c347af9c7b9dc6adfd1d476d7c015005db0990927848956587961f16f6e3cd8a134edfc4cf4707ea720bd78423110d807e197e7e
7
- data.tar.gz: c19cea532598c24f46e8743f6f5af524d087780730b19e1081cc0318dea0ec2a68757effdd440429384e17107abf714161f302f4d9daf90f861a7e0206029fd8
6
+ metadata.gz: 745cc975c54fc9e1449a514c711ca2a3ab98df951deb554b6e37de8f5e01ddbacf4e2001a20d0cd512d4ed5411291b4a213e0293928878b805ee5395acbd02c7
7
+ data.tar.gz: 9afe52e540571bd3330743229d8e267150d243a9e28a815a503841199979c1a156434ad07b4a4d828a3f5db042710a3a5756999c8bf525a10aafa17f3dd0ff26
@@ -9,6 +9,22 @@ module Actions
9
9
  include DiffCalc
10
10
 
11
11
  def p_initialize
12
+ begin
13
+ OptionParser.new do |opts|
14
+ opts.banner = 'Usage: stg init'
15
+
16
+ opts.on_tail('-h', '--help', 'Show this help') do
17
+ puts opts
18
+ exit
19
+ end
20
+ end.parse!
21
+ rescue OptionParser::ParseError => e
22
+ puts e.message
23
+ puts 'Usage: stg init'
24
+ puts ' -h, --help Show this help'
25
+ exit 1
26
+ end
27
+
12
28
  # Check if already initialized
13
29
  if File.exist?('.stolen-git')
14
30
  if confirm?('An instance of stolen-git is already up here do you want to replace it')
@@ -41,6 +57,7 @@ module Actions
41
57
 
42
58
  # main files
43
59
  File.write('.stolen-git/project_info.json', {})
60
+ File.write('.stg-ignore', JSON.pretty_generate(['.*/']))
44
61
  File.write('.stolen-git/commits.json', JSON.pretty_generate({ commits: [] }))
45
62
  File.write('.stolen-git/index.json', {})
46
63
 
@@ -54,16 +71,36 @@ module Actions
54
71
  end
55
72
 
56
73
  def stage
74
+ begin
75
+ OptionParser.new do |opts|
76
+ opts.banner = 'Usage: stg stage <file> [files...]'
77
+
78
+ opts.on_tail('-h', '--help', 'Show this help') do
79
+ puts opts
80
+ exit
81
+ end
82
+ end.parse!
83
+ rescue OptionParser::ParseError => e
84
+ puts e.message
85
+ puts 'Usage: stg stage <file> [files...]'
86
+ puts ' -h, --help Show this help'
87
+ exit 1
88
+ end
89
+
57
90
  inp = ARGV
58
91
 
59
92
  if inp.empty?
60
- puts 'Usage: stg stage <directory/> <file.xy>'
93
+ puts 'Usage: stg stage <file> [files...]'
61
94
  return
62
95
  end
63
96
 
64
- index = JSON.parse(File.read('.stolen-git/index.json'))
65
-
97
+ index = read_json('.stolen-git/index.json')
98
+ ignore = read_json('.stg-ignore')
66
99
  stage_file = lambda do |file_path|
100
+ ignore&.each do |ignore_pattern|
101
+ return if File.fnmatch(ignore_pattern, file_path)
102
+ end
103
+ file_path = clean_path(file_path)
67
104
  file_hash = get_file_hash(file_path)
68
105
  file_content = File.read(file_path)
69
106
 
@@ -79,7 +116,10 @@ module Actions
79
116
  end
80
117
 
81
118
  stage_directory = lambda do |dir_path|
119
+ dir_path = clean_path(dir_path)
82
120
  Dir.children(dir_path).each do |entry|
121
+ next if entry == '.stolen-git'
122
+
83
123
  path = File.join(dir_path, entry)
84
124
  if File.file?(path)
85
125
  stage_file.call(path)
@@ -90,6 +130,7 @@ module Actions
90
130
  end
91
131
 
92
132
  inp.each do |inp_path|
133
+ inp_path = clean_path(inp_path)
93
134
  unless File.exist? inp_path
94
135
  puts "#{inp_path} doesn't exist"
95
136
  next
@@ -111,17 +152,31 @@ module Actions
111
152
  options = { name: '', description: '' }
112
153
 
113
154
  # Getting commit name & description
114
- OptionParser.new do |opts|
115
- opts.banner = 'Usage: stg commit [options]'
155
+ begin
156
+ OptionParser.new do |opts|
157
+ opts.banner = 'Usage: stg commit [options]'
116
158
 
117
- opts.on('-n', '--name NAME', 'Add a commit name') do |name|
118
- options[:name] = name
119
- end
159
+ opts.on('-n', '--name NAME', 'Add a commit name') do |name|
160
+ options[:name] = name
161
+ end
120
162
 
121
- opts.on('-d', '--description DESCRIPTION', 'Add a commit description') do |description|
122
- options[:description] = description
123
- end
124
- end.parse!
163
+ opts.on('-d', '--description DESCRIPTION', 'Add a commit description') do |description|
164
+ options[:description] = description
165
+ end
166
+
167
+ opts.on_tail('-h', '--help', 'Show this help') do
168
+ puts opts
169
+ exit
170
+ end
171
+ end.parse!
172
+ rescue OptionParser::ParseError => e
173
+ puts e.message
174
+ puts 'Usage: stg commit [options]'
175
+ puts ' -n, --name NAME Add a commit name'
176
+ puts ' -d, --description DESCRIPTION Add a commit description'
177
+ puts ' -h, --help Show this help'
178
+ exit 1
179
+ end
125
180
 
126
181
  options[:name] = ask('Add a commit name: ') if options[:name].empty?
127
182
 
@@ -139,35 +194,57 @@ module Actions
139
194
  parent_commit = branch_content['commit_pointer']
140
195
 
141
196
  # Getting differences to last commit
142
-
143
197
  no_insertions = 0
144
198
  no_deletions = 0
145
199
  no_file_changed = 0
200
+
146
201
  commit_diff = {}
147
202
 
148
203
  getting_diff = lambda do |entries|
149
- parent_index = 0
204
+ if entries.nil?
205
+ index.each do |key, value|
206
+ key = clean_path(key)
207
+ new_entry_content = File.read(".stolen-git/storage/blobs/#{value['hash']}").lines.to_a
208
+ compute_diff([], new_entry_content)
209
+ diff = build_sequences
210
+ no_insertions += diff[:insertions]
211
+ no_deletions += diff[:deletions]
212
+ no_file_changed += 1
213
+ commit_diff[key] = diff
214
+ end
215
+ else
216
+ parent_map = entries.to_h { |e| [e['path'], e['hash']] }
150
217
 
151
- index.each do |key, value|
152
- if entries && entries[parent_index] && key == entries[parent_index]['path']
218
+ index.each do |key, value|
219
+ key = clean_path(key)
153
220
  new_hash = value['hash']
154
- old_hash = entries[parent_index]['hash']
155
- parent_index += 1
156
- next if value['hash'] == new_hash
221
+ old_hash = parent_map[key]
222
+
223
+ if old_hash
224
+ next if old_hash == new_hash
225
+
226
+ entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
227
+ new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
228
+ compute_diff(entry_content, new_entry_content)
229
+ else
230
+ new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
231
+ compute_diff([], new_entry_content)
232
+ end
157
233
 
158
- entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
159
- new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
160
- compute_diff(entry_content, new_entry_content)
161
234
  diff = build_sequences
162
235
  no_insertions += diff[:insertions]
163
236
  no_deletions += diff[:deletions]
164
237
  no_file_changed += 1
165
238
  commit_diff[key] = diff
166
- else
167
- new_entry_content = File.read(".stolen-git/storage/blobs/#{value['hash']}").lines.to_a
168
- compute_diff('', new_entry_content)
169
- diff = build_sequences
239
+ end
170
240
 
241
+ parent_map.each do |key, old_hash|
242
+ key = clean_path(key)
243
+ next if index.key?(key)
244
+
245
+ entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
246
+ compute_diff(entry_content, [])
247
+ diff = build_sequences
171
248
  no_insertions += diff[:insertions]
172
249
  no_deletions += diff[:deletions]
173
250
  no_file_changed += 1
@@ -193,6 +270,7 @@ module Actions
193
270
 
194
271
  # Making the tree
195
272
  index.each do |key, value|
273
+ key = clean_path(key)
196
274
  tree_content[:entries].push({
197
275
  path: key,
198
276
  type: 'blob',
@@ -243,6 +321,22 @@ module Actions
243
321
  end
244
322
 
245
323
  def reset
324
+ begin
325
+ OptionParser.new do |opts|
326
+ opts.banner = 'Usage: stg reset [commit_id]'
327
+
328
+ opts.on_tail('-h', '--help', 'Show this help') do
329
+ puts opts
330
+ exit
331
+ end
332
+ end.parse!
333
+ rescue OptionParser::ParseError => e
334
+ puts e.message
335
+ puts 'Usage: stg reset [commit_id]'
336
+ puts ' -h, --help Show this help'
337
+ exit 1
338
+ end
339
+
246
340
  commit_id = ARGV.first
247
341
  commit_history = read_json('.stolen-git/commits.json')
248
342
  pointer = read_json('.stolen-git/pointer.json')
@@ -272,13 +366,27 @@ module Actions
272
366
  options = { commit: false }
273
367
 
274
368
  # Getting commit name & description
275
- OptionParser.new do |opts|
276
- opts.banner = 'Usage: stg checkout [options]'
369
+ begin
370
+ OptionParser.new do |opts|
371
+ opts.banner = 'Usage: stg checkout [options]'
372
+
373
+ opts.on('-c', '--commit', 'Add a commit id instead') do
374
+ options[:commit] = true
375
+ end
376
+
377
+ opts.on_tail('-h', '--help', 'Show this help') do
378
+ puts opts
379
+ exit
380
+ end
381
+ end.parse!
382
+ rescue OptionParser::ParseError => e
383
+ puts e.message
384
+ puts 'Usage: stg checkout [options]'
385
+ puts ' -c, --commit Add a commit id instead'
386
+ puts ' -h, --help Show this help'
387
+ exit 1
388
+ end
277
389
 
278
- opts.on('-c', '--commit', 'Add a commit id instead') do
279
- options[:commit] = true
280
- end
281
- end.parse!
282
390
  inp = ARGV.last
283
391
  if !inp
284
392
  puts 'Please Enter the name of a branch or commit_id'
@@ -287,7 +395,7 @@ module Actions
287
395
  current_commit_hash = commit_history['commits'].find { |x| x['id'] == inp }['hash']
288
396
  revert_to_commit(current_commit_hash)
289
397
  else
290
- # TODO: Handle if user enters branch_id instead
398
+ # TODO: Handle if user enters branch_id instead of name
291
399
  branch_content = {}
292
400
  branch_id = ''
293
401
  Dir.children('.stolen-git/branches').each do |entry|
@@ -302,28 +410,47 @@ module Actions
302
410
  nil
303
411
  end
304
412
  commit_hash = branch_content['commit_pointer']
305
- revert_to_commit(commit_hash)
413
+ revert_to_commit(commit_hash) if commit_hash&.length&.positive?
306
414
  pointer = read_json('.stolen-git/pointer.json')
307
415
  pointer['point_to'] = branch_id
308
416
  pointer['type'] = 'branch'
309
417
  File.write('.stolen-git/pointer.json', JSON.pretty_generate(pointer))
418
+
310
419
  end
311
420
  end
312
421
 
313
422
  def branch
314
- name = ARGV.last
423
+ begin
424
+ OptionParser.new do |opts|
425
+ opts.banner = 'Usage: stg branch [name]'
426
+
427
+ opts.on_tail('-h', '--help', 'Show this help') do
428
+ puts opts
429
+ exit
430
+ end
431
+ end.parse!
432
+ rescue OptionParser::ParseError => e
433
+ puts e.message
434
+ puts 'Usage: stg branch [name]'
435
+ puts ' -h, --help Show this help'
436
+ exit 1
437
+ end
438
+
439
+ names = ARGV
315
440
  pointer = read_json('.stolen-git/pointer.json')
316
441
  pointed_branch = pointer['type'] == 'branch' ? pointer['point_to'] : ''
317
- if name
318
- first_commit = pointer['type'] == 'branch' ? read_json(".stolen-git/branches/#{pointed_branch}.json")['commit_pointer'] : pointer['point_to']
319
- id = SecureRandom.uuid
320
- File.write(".stolen-git/branches/#{id}.json", JSON.pretty_generate({
321
- name: name,
322
- created_at: Time.now,
323
- commit_pointer: first_commit
324
- }))
442
+ if names && names.length.positive?
443
+ names.each do |name|
444
+ first_commit = pointer['type'] == 'branch' ? read_json(".stolen-git/branches/#{pointed_branch}.json")['commit_pointer'] : pointer['point_to']
445
+ id = SecureRandom.uuid
446
+ File.write(".stolen-git/branches/#{id}.json", JSON.pretty_generate({
447
+ name: name,
448
+ created_at: Time.now,
449
+ commit_pointer: first_commit
450
+ }))
451
+ puts "branch #{name} created"
452
+ end
325
453
  return
326
- puts "branch #{name} created"
327
454
  end
328
455
  Dir.children('.stolen-git/branches').each do |entry|
329
456
  branch_content = read_json(".stolen-git/branches/#{entry}")
@@ -338,8 +465,25 @@ module Actions
338
465
  end
339
466
 
340
467
  def diff
468
+ begin
469
+ OptionParser.new do |opts|
470
+ opts.banner = 'Usage: stg diff'
471
+
472
+ opts.on_tail('-h', '--help', 'Show this help') do
473
+ puts opts
474
+ exit
475
+ end
476
+ end.parse!
477
+ rescue OptionParser::ParseError => e
478
+ puts e.message
479
+ puts 'Usage: stg diff'
480
+ puts ' -h, --help Show this help'
481
+ exit 1
482
+ end
483
+
341
484
  index = read_json('.stolen-git/index.json')
342
485
  index.each do |key, value|
486
+ key = clean_path(key)
343
487
  new_file_content = File.exist?(key) ? File.read(key) : nil
344
488
  file_name = File.basename(key)
345
489
  if new_file_content.nil?
@@ -357,25 +501,65 @@ module Actions
357
501
  end
358
502
 
359
503
  def log
360
- limit = ARGV.last
361
- limit = limit && !limit.empty? ? limit.to_i : 0
362
- commit_history_content = read_json('.stolen-git/commits.json')
504
+ # Handle if the user wants to -[num]
505
+ ARGV.map! do |arg|
506
+ if arg =~ /^-(\d+)$/
507
+ ['-l', ::Regexp.last_match(1)]
508
+ else
509
+ arg
510
+ end
511
+ end.flatten!
363
512
 
364
- commit_history_content['commits'].each_with_index do |commit, i|
365
- break if limit > 0 && i >= limit
513
+ options = { limit: 0 }
514
+ begin
515
+ OptionParser.new do |opts|
516
+ opts.banner = 'Usage: stg log [limit]'
366
517
 
367
- if limit == 0 && i >= 5
368
- q = ask(':')
369
- break if q == 'q'
370
- end
371
- commit_content = read_json(".stolen-git/commits/#{commit['hash']}.json")
518
+ opts.on('-l', '--limit LIMIT', 'limit showed logs') do |num|
519
+ options[:limit] = num.to_i
520
+ end
521
+
522
+ opts.on_tail('-h', '--help', 'Show this help') do
523
+ puts opts
524
+ exit
525
+ end
526
+ end.parse!
527
+ rescue OptionParser::ParseError => e
528
+ puts e.message
529
+ puts 'Usage: stg log [limit]'
530
+ puts ' -[num], --limit limit showed logs i.e. stg log -5'
531
+ puts ' -l, --limit limit showed logs'
532
+ puts ' -h, --help Show this help'
533
+ exit 1
534
+ end
535
+
536
+ is_limited = options[:limit] > 0
537
+ pointer = read_json('.stolen-git/pointer.json')
538
+ last_commit = pointer['type'] == 'commit' ? pointer['point_to'] : read_json(".stolen-git/branches/#{pointer['point_to']}.json")['commit_pointer']
539
+ unless last_commit
540
+ puts "Couldn't find last commits. The setup might have been corrupted. If that's the case run 'stg init'"
541
+ end
542
+ i = 0
543
+
544
+ print_commit = lambda do |commit_hash, commit_content|
372
545
  puts
373
546
  puts "commit #{commit_content['id']}".green
547
+ puts "hash: #{commit_hash[0..5]}...#{commit_hash[-5..]}".green
374
548
  puts "Author #{commit_content['author_profile']['username']} <#{commit_content['author_profile']['email']}>"
375
549
  puts "Date: #{commit_content['created_at']}"
376
550
  puts
377
551
  puts " #{commit_content['name']}"
378
- puts
552
+ end
553
+
554
+ while (is_limited && i < options[:limit] || !is_limited) && last_commit && last_commit.length.positive?
555
+ last_commit_content = read_json(".stolen-git/commits/#{last_commit}.json")
556
+ print_commit.call(last_commit, last_commit_content)
557
+ last_commit = last_commit_content['parent_commit']
558
+ i += 1
559
+ if !is_limited && i >= 5
560
+ q = ask(':')
561
+ break if q == 'q'
562
+ end
379
563
  end
380
564
  end
381
565
  end
@@ -27,14 +27,12 @@ module DiffCalc
27
27
  if i1 >= @old_s.length
28
28
  result = { diff_cnt: @new_s.length - i2, insertions: @new_s.length - i2, deletions: 0, action: :insert }
29
29
  @mem[[i1, i2]] = result
30
- differencing(i1, i2 + 1) if i2 < @new_s.length
31
30
  return result
32
31
  end
33
32
 
34
33
  if i2 >= @new_s.length
35
34
  result = { diff_cnt: @old_s.length - i1, insertions: 0, deletions: @old_s.length - i1, action: :delete }
36
35
  @mem[[i1, i2]] = result
37
- differencing(i1 + 1, i2) if i1 < @old_s.length
38
36
  return result
39
37
  end
40
38
 
@@ -69,7 +67,10 @@ module DiffCalc
69
67
  deletion_seq = {}
70
68
 
71
69
  while i1 < @old_s.length || i2 < @new_s.length
72
- action = @mem[[i1, i2]][:action]
70
+ entry = @mem[[i1, i2]]
71
+ break unless entry
72
+
73
+ action = entry[:action]
73
74
 
74
75
  case action
75
76
  when :done
@@ -82,12 +83,12 @@ module DiffCalc
82
83
  deletion_seq[i2].push({ old_index: i1, ma_type: 'bs' })
83
84
  i1 += 1
84
85
  when :insert
85
- insertion_seq[i2] = { value: @new_s[i2], old_index: i1 }
86
+ insertion_seq[i2] = { value: @new_s[i2].encode('UTF-8', invalid: :replace, undef: :replace, replace: ''), old_index: i1 }
86
87
  i2 += 1
87
88
  end
88
89
  end
89
90
 
90
- result = @mem[[0, 0]]
91
+ result = @mem[[0, 0]] || { insertions: 0, deletions: 0, diff_cnt: 0 }
91
92
  {
92
93
  insertion_seq: insertion_seq,
93
94
  deletion_seq: deletion_seq,
@@ -8,11 +8,11 @@ module Help
8
8
  stage: 'add a file or directory to be tracked ',
9
9
  commit: 'Save the current tracked state ',
10
10
  diff: 'get the difference between working directory and the last commit ',
11
- log: 'print out commit history (limit print by a number `log <number>`) ',
11
+ log: 'print out commit history',
12
12
  reset: 'Revert to commit',
13
13
  checkout: 'check a commit or a branch without loss in data',
14
- branch: 'List all branches. (or creating a branch by `branch <name>`) '
15
-
14
+ branch: 'List all branches.',
15
+ help: 'show this list'
16
16
  }
17
17
  max_len = 0
18
18
  commands_docs.each_key do |command|
@@ -1,6 +1,7 @@
1
1
  require 'fileutils'
2
2
  require 'optparse'
3
3
  require 'digest'
4
+ require 'pathname'
4
5
  module Utils
5
6
  def confirm?(prompt)
6
7
  loop do
@@ -28,6 +29,8 @@ module Utils
28
29
 
29
30
  def read_json(path)
30
31
  JSON.parse(File.read(path))
32
+ rescue StandardError
33
+ nil
31
34
  end
32
35
 
33
36
  def get_file_hash(path)
@@ -58,6 +61,17 @@ module Utils
58
61
 
59
62
  File.write('.stolen-git/index.json', JSON.pretty_generate(index))
60
63
  end
64
+
65
+ def clean_path(path)
66
+ Pathname.new(path).cleanpath.to_s
67
+ end
68
+
69
+ def check_program_exists
70
+ return true if File.exist? '.stolen-git'
71
+
72
+ puts "There is no instance of stolen-git found. Please run 'stg init' first."
73
+ false
74
+ end
61
75
  end
62
76
 
63
77
  include Utils
@@ -0,0 +1,3 @@
1
+ module Stg
2
+ VERSION = '0.1.5'
3
+ end
data/lib/stg.rb CHANGED
@@ -1,5 +1,7 @@
1
- require_relative 'help'
2
- require_relative 'actions'
1
+ require 'optparse'
2
+ require_relative 'stg/help'
3
+ require_relative 'stg/actions'
4
+ require_relative 'stg/version'
3
5
 
4
6
  module Stg
5
7
  class CLI
@@ -7,10 +9,36 @@ module Stg
7
9
  extend Help
8
10
 
9
11
  def self.start
12
+ begin
13
+ OptionParser.new do |opts|
14
+ opts.banner = 'Usage: stg <command> [options]'
15
+
16
+ opts.on('-v', '--version', 'Show version') do
17
+ puts "stg version #{VERSION}"
18
+ exit
19
+ end
20
+
21
+ opts.on('-h', '--help', 'Show this help') do
22
+ puts print_usage
23
+ exit
24
+ end
25
+ end.order!
26
+ rescue OptionParser::ParseError
27
+ # Ignore unknown options, let command handlers deal with them
28
+ end
29
+
10
30
  command = ARGV.shift
11
- case command
12
- when 'init'
31
+ if !command || command.empty?
32
+ puts print_usage
33
+ return
34
+ elsif command == 'init'
13
35
  p_initialize
36
+ return
37
+ else
38
+ return unless check_program_exists
39
+ end
40
+
41
+ case command
14
42
  when 'commit'
15
43
  commit
16
44
  when 'diff'
@@ -42,3 +70,5 @@ module Stg
42
70
  end
43
71
  end
44
72
  end
73
+
74
+ Stg::CLI.start if __FILE__ == $PROGRAM_NAME
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amr ElTaweel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-02 00:00:00.000000000 Z
11
+ date: 2026-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -35,11 +35,12 @@ extra_rdoc_files: []
35
35
  files:
36
36
  - README.md
37
37
  - bin/stg
38
- - lib/actions.rb
39
- - lib/differencing.rb
40
- - lib/help.rb
41
38
  - lib/stg.rb
42
- - lib/utils.rb
39
+ - lib/stg/actions.rb
40
+ - lib/stg/differencing.rb
41
+ - lib/stg/help.rb
42
+ - lib/stg/utils.rb
43
+ - lib/stg/version.rb
43
44
  homepage: https://github.com/amrbassem218/stolen-git
44
45
  licenses:
45
46
  - MIT