squared 0.4.15 → 0.4.17
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/CHANGELOG.md +60 -0
- data/README.md +10 -5
- data/README.ruby.md +21 -15
- data/lib/squared/common/prompt.rb +3 -3
- data/lib/squared/common/shell.rb +1 -2
- data/lib/squared/common/system.rb +17 -16
- data/lib/squared/common/utils.rb +9 -0
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +24 -15
- data/lib/squared/workspace/project/base.rb +193 -130
- data/lib/squared/workspace/project/docker.rb +84 -70
- data/lib/squared/workspace/project/git.rb +233 -138
- data/lib/squared/workspace/project/node.rb +87 -30
- data/lib/squared/workspace/project/python.rb +48 -19
- data/lib/squared/workspace/project/ruby.rb +98 -57
- data/lib/squared/workspace/project/support/class.rb +66 -17
- data/lib/squared/workspace/repo.rb +46 -42
- data/lib/squared/workspace/series.rb +4 -4
- data/lib/squared/workspace/support/base.rb +17 -0
- data/lib/squared/workspace/support.rb +1 -0
- data/lib/squared/workspace.rb +0 -8
- data/squared.gemspec +2 -2
- metadata +3 -2
@@ -3,8 +3,8 @@
|
|
3
3
|
module Squared
|
4
4
|
module Workspace
|
5
5
|
module Git
|
6
|
-
GIT_REPO =
|
7
|
-
GIT_PROTO = %r{
|
6
|
+
GIT_REPO = Support.hashobj
|
7
|
+
GIT_PROTO = %r{\A(https?|ssh|git|file)://}i.freeze
|
8
8
|
private_constant :GIT_REPO, :GIT_PROTO
|
9
9
|
|
10
10
|
attr_reader :revfile
|
@@ -179,6 +179,9 @@ module Squared
|
|
179
179
|
}.freeze,
|
180
180
|
git: {
|
181
181
|
add: %w[N|intent-to-add refresh].freeze,
|
182
|
+
blame: %w[b c l s t w C=im? L=q M=im? S=p color-by-age color-lines first-parent incremental line-porcelain
|
183
|
+
p|porcelain root score-debug f|show-name e|show-email n|show-number show-stats abbrev=i
|
184
|
+
contents=p date=q encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
|
182
185
|
clean: %w[d x X f|force n|dry-run i|interactive q|quiet e|exclude=q].freeze,
|
183
186
|
mv: %w[k f|force n|dry-run v|verbose].freeze,
|
184
187
|
revert: %w[e S=bm? abort continue n|no-commit quit reference skip cleanup=b gpg-sign=b? m|mainline=i
|
@@ -241,10 +244,21 @@ module Squared
|
|
241
244
|
pop: %w[index].freeze,
|
242
245
|
apply: %w[index].freeze
|
243
246
|
}.freeze,
|
244
|
-
status: %w[u
|
247
|
+
status: %w[z u=bm? b|branch long s|short show-stash v|verbose column=b find-renames=i? ignore-submodules=b?
|
248
|
+
ignored=b? porcelain=b? untracked-files=b?].freeze,
|
249
|
+
submodule: {
|
250
|
+
status: %w[cached recursive].freeze,
|
251
|
+
update: %w[checkout f|force init merge N|no-fetch no-recommend-shallow no-single-branch recommend-shallow
|
252
|
+
rebase recursive remote single-branch depth=i filter=q jobs=i reference=b ref-format=q].freeze,
|
253
|
+
branch: %w[b|branch d|default].freeze,
|
254
|
+
sync: %w[recursive].freeze
|
255
|
+
}.freeze,
|
256
|
+
switch: %w[d|detach discard-changes f|force ignore-other-worktrees m|merge q|quiet conflict=b c|create=q
|
257
|
+
C|force-create=q orphan=q t|track=b].freeze,
|
245
258
|
tag: %w[n=im cleanup=b create-reflog i|ignore-case color=b? column=b contains=b? format=q merged=b?
|
246
259
|
no-contains=b? no-merged=b? points-at=q sort=q].freeze,
|
247
260
|
no: {
|
261
|
+
blame: %w[progress].freeze,
|
248
262
|
branch: %w[color color-moved column track].freeze,
|
249
263
|
checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
|
250
264
|
fetch: {
|
@@ -266,6 +280,8 @@ module Squared
|
|
266
280
|
rev_parse: %w[flags].freeze,
|
267
281
|
revert: %w[edit gpg-sign rerere-autoupdate].freeze,
|
268
282
|
show: %w[standard-notes].freeze,
|
283
|
+
status: %w[ahead-behind column renames].freeze,
|
284
|
+
switch: %w[guess progress recurse-submodules track].freeze,
|
269
285
|
tag: %w[column].freeze
|
270
286
|
}.freeze
|
271
287
|
}.freeze
|
@@ -287,10 +303,8 @@ module Squared
|
|
287
303
|
def populate(ws, **)
|
288
304
|
return if ws.series.exclude?(:pull, true)
|
289
305
|
|
290
|
-
namespace(
|
291
|
-
all = ws.task_join(
|
292
|
-
|
293
|
-
ws.format_desc(all, 'stash|rebase|autostash?,depend?')
|
306
|
+
namespace(ws.task_name('git')) do |ns|
|
307
|
+
ws.format_desc(all = ws.task_join(ns.scope.path, 'all'), 'stash|rebase|autostash?,depend?')
|
294
308
|
task 'all' do |_, args|
|
295
309
|
args = args.to_a
|
296
310
|
cmd = if args.include?('stash')
|
@@ -307,6 +321,7 @@ module Squared
|
|
307
321
|
cmd << ws.task_sync('build')
|
308
322
|
Common::Utils.task_invoke(*cmd, **ws.invokeargs)
|
309
323
|
end
|
324
|
+
|
310
325
|
ws.series.sync << all
|
311
326
|
ws.series.multiple << all
|
312
327
|
end
|
@@ -328,25 +343,27 @@ module Squared
|
|
328
343
|
'checkout' => %i[commit branch track detach path].freeze,
|
329
344
|
'commit' => %i[add all amend amend-orig fixup].freeze,
|
330
345
|
'diff' => %i[head branch files view between contain].freeze,
|
331
|
-
'fetch' => %i[origin remote].freeze,
|
346
|
+
'fetch' => %i[origin remote all].freeze,
|
332
347
|
'files' => %i[cached modified deleted others].freeze,
|
333
|
-
'git' => %i[add clean mv revert rm].freeze,
|
348
|
+
'git' => %i[add blame clean mv revert rm status].freeze,
|
334
349
|
'log' => %i[view between contain].freeze,
|
335
350
|
'merge' => %i[commit no-commit send].freeze,
|
336
|
-
'pull' => %i[origin remote].freeze,
|
351
|
+
'pull' => %i[origin remote all].freeze,
|
337
352
|
'rebase' => %i[branch onto send].freeze,
|
338
353
|
'refs' => %i[heads tags remote].freeze,
|
339
|
-
'reset' => %i[commit index patch mode].freeze,
|
354
|
+
'reset' => %i[commit index patch mode undo].freeze,
|
340
355
|
'restore' => %i[source staged worktree].freeze,
|
341
356
|
'rev' => %i[commit build output].freeze,
|
342
357
|
'show' => %i[format oneline textconv].freeze,
|
343
358
|
'stash' => %i[push pop apply branch drop clear list].freeze,
|
344
|
-
'
|
359
|
+
'submodule' => %i[status update branch url sync].freeze,
|
360
|
+
'switch' => %i[branch create detach].freeze,
|
345
361
|
'tag' => %i[add sign delete list].freeze
|
346
362
|
})
|
347
363
|
|
348
364
|
def initialize(*, **)
|
349
365
|
super
|
366
|
+
@submodule = basepath('.gitmodules').exist?
|
350
367
|
initialize_ref Git.ref if gitpath.exist?
|
351
368
|
end
|
352
369
|
|
@@ -356,11 +373,11 @@ module Squared
|
|
356
373
|
|
357
374
|
def populate(*, **)
|
358
375
|
super
|
359
|
-
return unless ref?(Git.ref)
|
376
|
+
return unless ref?(Git.ref) || @only
|
360
377
|
|
361
378
|
namespace name do
|
362
379
|
Git.subtasks do |action, flags|
|
363
|
-
next if
|
380
|
+
next if task_pass?(action)
|
364
381
|
|
365
382
|
namespace action do
|
366
383
|
flags.each do |flag|
|
@@ -378,11 +395,34 @@ module Squared
|
|
378
395
|
__send__(action, flag, args, remote: remote)
|
379
396
|
end
|
380
397
|
else
|
381
|
-
format_desc
|
398
|
+
format_desc(action, flag, 'opts*', after: flag == :all && action == 'pull' ? 'pattern*' : nil)
|
382
399
|
task flag do |_, args|
|
383
400
|
__send__ action, flag, args.to_a
|
384
401
|
end
|
385
402
|
end
|
403
|
+
when 'submodule'
|
404
|
+
break unless @submodule
|
405
|
+
|
406
|
+
case flag
|
407
|
+
when :branch
|
408
|
+
format_desc action, flag, 'path,opts*'
|
409
|
+
task flag, [:path] do |_, args|
|
410
|
+
path = param_guard(action, flag, args: args, key: :path)
|
411
|
+
submodule(flag, args.extras, path: path)
|
412
|
+
end
|
413
|
+
when :url
|
414
|
+
format_desc action, flag, 'path,url,opts*'
|
415
|
+
task flag, [:path, :url] do |_, args|
|
416
|
+
path = param_guard(action, flag, args: args, key: :path)
|
417
|
+
url = param_guard(action, flag, args: args, key: :url)
|
418
|
+
submodule(flag, args.extras, path: path, url: url)
|
419
|
+
end
|
420
|
+
else
|
421
|
+
format_desc action, flag, 'opts*,path*'
|
422
|
+
task flag do |_, args|
|
423
|
+
submodule flag, args.to_a
|
424
|
+
end
|
425
|
+
end
|
386
426
|
when 'commit'
|
387
427
|
case flag
|
388
428
|
when :all
|
@@ -678,10 +718,10 @@ module Squared
|
|
678
718
|
when :create
|
679
719
|
format_desc action, flag, '(^)name,ref?=HEAD|:'
|
680
720
|
task flag, [:name, :commit] do |_, args|
|
681
|
-
|
721
|
+
branch = param_guard(action, flag, args: args, key: :name)
|
682
722
|
commit = commithead args.commit
|
683
723
|
commit, track = choice_commit(values: ['Track? [Y|n]'], force: false) if commit == ':'
|
684
|
-
switch(flag,
|
724
|
+
switch(flag, branch: branch, commit: commit, track: track)
|
685
725
|
end
|
686
726
|
when :detach
|
687
727
|
format_desc action, flag, 'ref?=HEAD'
|
@@ -689,11 +729,16 @@ module Squared
|
|
689
729
|
commit = commithead(args.commit) || choice_commit(force: false)
|
690
730
|
switch(flag, commit: commit)
|
691
731
|
end
|
692
|
-
when :
|
693
|
-
format_desc action, flag, '
|
694
|
-
task flag, [:
|
695
|
-
|
696
|
-
|
732
|
+
when :branch
|
733
|
+
format_desc action, flag, 'name|:,opts*'
|
734
|
+
task flag, [:name] do |_, args|
|
735
|
+
if (branch = args.name)
|
736
|
+
args = args.extras
|
737
|
+
branch = nil if branch == ':'
|
738
|
+
else
|
739
|
+
args = []
|
740
|
+
end
|
741
|
+
switch(flag, args, branch: branch || choice_refs('Choose a branch'))
|
697
742
|
end
|
698
743
|
end
|
699
744
|
when 'reset'
|
@@ -714,10 +759,10 @@ module Squared
|
|
714
759
|
end
|
715
760
|
print_success if success?(reset(flag, args, commit: commit))
|
716
761
|
end
|
717
|
-
when :index
|
718
|
-
format_desc
|
762
|
+
when :index, :undo
|
763
|
+
format_desc(action, flag, flag == :index ? 'opts*,pathspec*' : nil)
|
719
764
|
task flag do |_, args|
|
720
|
-
reset
|
765
|
+
reset(flag, flag == :index ? args.to_a : [])
|
721
766
|
end
|
722
767
|
when :mode
|
723
768
|
format_desc action, flag, 'mode,ref?=HEAD|:'
|
@@ -816,7 +861,7 @@ module Squared
|
|
816
861
|
rev_parse(flag, ref: ref, size: size)
|
817
862
|
end
|
818
863
|
when :build
|
819
|
-
format_desc action, flag,
|
864
|
+
format_desc action, flag, 'opts*'
|
820
865
|
task flag do |_, args|
|
821
866
|
revbuild flag, args.to_a
|
822
867
|
end
|
@@ -833,7 +878,7 @@ module Squared
|
|
833
878
|
ls_remote(flag, args.extras, remote: args.remote)
|
834
879
|
end
|
835
880
|
else
|
836
|
-
format_desc
|
881
|
+
format_desc(action, flag, 'opts*,pattern*', after: action == 'files' ? 'pathspec*' : nil)
|
837
882
|
task flag do |_, args|
|
838
883
|
__send__(action == 'refs' ? :ls_remote : :ls_files, flag, args.to_a)
|
839
884
|
end
|
@@ -859,19 +904,14 @@ module Squared
|
|
859
904
|
args = args.to_a
|
860
905
|
if args.empty? || args.last == ':'
|
861
906
|
files = []
|
862
|
-
status_data.each
|
863
|
-
case (flag == :staged ? line[2] : line[1])
|
864
|
-
when /[AMDRTC]/
|
865
|
-
files << line[0]
|
866
|
-
end
|
867
|
-
end
|
907
|
+
status_data.each { |row| files << row[0] if row[flag == :staged ? 2 : 1].match?(/[AMDRTC]/) }
|
868
908
|
unless files.empty?
|
869
909
|
files = choice_index('Select a file', files, multiple: true, force: false,
|
870
910
|
accept: 'Restore?')
|
871
911
|
end
|
872
912
|
args.pop
|
873
913
|
args, glob = args.partition { |val| val.match?(/^(?:[a-z-]+=|[^*]+$)/) }
|
874
|
-
|
914
|
+
files.concat(glob)
|
875
915
|
next if args.empty? && files.empty?
|
876
916
|
end
|
877
917
|
restore(flag, args, files: files)
|
@@ -879,13 +919,17 @@ module Squared
|
|
879
919
|
end
|
880
920
|
when 'git'
|
881
921
|
before = case flag
|
922
|
+
when :blame then 'file'
|
882
923
|
when :mv then 'source+,destination'
|
883
924
|
when :revert then 'commit+' end
|
884
925
|
format_desc(action, flag, 'opts*', before: before, after: case flag
|
885
|
-
when :add
|
886
|
-
|
926
|
+
when :add
|
927
|
+
'pathspec*,pattern*'
|
928
|
+
when :clean, :rm, :status
|
929
|
+
'pathspec*'
|
930
|
+
end)
|
887
931
|
task flag do |_, args|
|
888
|
-
git flag, args.to_a
|
932
|
+
__send__(flag == :status ? :status : :git, flag, args.to_a)
|
889
933
|
end
|
890
934
|
end
|
891
935
|
end
|
@@ -909,11 +953,44 @@ module Squared
|
|
909
953
|
super
|
910
954
|
end
|
911
955
|
|
912
|
-
def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
|
956
|
+
def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil, hint: nil)
|
913
957
|
cmd, opts = git_session('pull', opts: opts)
|
914
|
-
|
958
|
+
cmd << '--autostash' if option('autostash')
|
959
|
+
case flag
|
960
|
+
when :rebase
|
915
961
|
cmd << '--rebase'
|
916
|
-
|
962
|
+
when :all
|
963
|
+
unless git_spawn('status -s -z --untracked-files=all').empty?
|
964
|
+
if confirm('Stash local changes? [Y/n] ', 'Y')
|
965
|
+
git_spawn 'stash push --keep-index --quiet'
|
966
|
+
elsif !(force = confirm('Force checkout? [y/N] ', 'N'))
|
967
|
+
return
|
968
|
+
end
|
969
|
+
end
|
970
|
+
op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, no: OPT_GIT[:no][:pull])
|
971
|
+
reg = if op.empty?
|
972
|
+
[]
|
973
|
+
else
|
974
|
+
opts = opts.reject { |val| op.extras.include?(val) }
|
975
|
+
matchmap op
|
976
|
+
end
|
977
|
+
session_done op.target
|
978
|
+
heads = []
|
979
|
+
cur = nil
|
980
|
+
foreachref('heads', format: '%(if)%(HEAD)%(then)* %(end)%(refname:short)').each do |line|
|
981
|
+
line.chomp!
|
982
|
+
cur ||= line.delete_prefix!('* ')
|
983
|
+
heads << line if matchany?(line, reg)
|
984
|
+
end
|
985
|
+
raise_error('head not found', hint: 'for-each-ref') unless cur
|
986
|
+
opts << 'ff-only' if opts.empty? && !option('ff-only', equals: '0')
|
987
|
+
(heads.dup << cur).each_with_index do |branch, index|
|
988
|
+
next unless (index < heads.size && cur != branch) || index == heads.size
|
989
|
+
|
990
|
+
git_spawn 'switch --quiet', force && '--force', shell_quote(branch)
|
991
|
+
pull(nil, opts, sync: false, hint: branch) if heads.include?(branch)
|
992
|
+
end
|
993
|
+
return
|
917
994
|
else
|
918
995
|
cmd << '--autostash' if flag == :autostash
|
919
996
|
if (val = option('rebase', ignore: false))
|
@@ -932,7 +1009,7 @@ module Squared
|
|
932
1009
|
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
|
933
1010
|
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(.*)$/, styles: color(:green), index: 3 }
|
934
1011
|
]
|
935
|
-
end, **threadargs)
|
1012
|
+
end, hint: hint, **threadargs)
|
936
1013
|
end
|
937
1014
|
|
938
1015
|
def rebase(flag = nil, opts = [], sync: invoked_sync?('rebase', flag), commit: nil, upstream: nil, branch: nil,
|
@@ -969,6 +1046,7 @@ module Squared
|
|
969
1046
|
|
970
1047
|
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
|
971
1048
|
opts = git_session('fetch', opts: opts).last
|
1049
|
+
opts << 'all' if flag == :all || option('all')
|
972
1050
|
append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
|
973
1051
|
remote: remote, flag: flag, from: :fetch)
|
974
1052
|
source(sync: sync, **threadargs)
|
@@ -1008,15 +1086,15 @@ module Squared
|
|
1008
1086
|
cmd, opts = git_session('stash', flag, opts: opts)
|
1009
1087
|
list = OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, [])
|
1010
1088
|
if flag == :list
|
1011
|
-
list += collect_hash
|
1012
|
-
no = collect_hash
|
1089
|
+
list += collect_hash OPT_GIT[:log]
|
1090
|
+
no = collect_hash OPT_GIT[:no][:log]
|
1013
1091
|
end
|
1014
1092
|
op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: flag == :push ? matchpathspec : nil)
|
1015
1093
|
case flag
|
1016
1094
|
when :push
|
1017
1095
|
append_pathspec op.extras
|
1018
1096
|
when :pop, :apply, :drop, :branch
|
1019
|
-
if op.
|
1097
|
+
if op.remove(':')
|
1020
1098
|
if flag == :branch
|
1021
1099
|
if op.empty?
|
1022
1100
|
values = [['Branch name', true]]
|
@@ -1051,29 +1129,34 @@ module Squared
|
|
1051
1129
|
end
|
1052
1130
|
else
|
1053
1131
|
git_session('stash', 'push', opts: opts)
|
1054
|
-
append_option(OPT_GIT[:stash][:push]
|
1132
|
+
append_option(OptionPartition.select(OPT_GIT[:stash][:push], no: false), no: true, ignore: false)
|
1055
1133
|
append_message
|
1056
1134
|
end
|
1057
1135
|
source(banner: !quiet?, sync: sync, **threadargs)
|
1058
1136
|
end
|
1059
1137
|
|
1060
|
-
def status(
|
1061
|
-
cmd = git_session
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1138
|
+
def status(flag = nil, opts = [])
|
1139
|
+
cmd, opts = git_session('status', opts: opts)
|
1140
|
+
if flag
|
1141
|
+
op = OptionPartition.new(opts, OPT_GIT[:status], cmd, project: self, no: OPT_GIT[:no][:status])
|
1142
|
+
append_pathspec op.extras
|
1143
|
+
else
|
1144
|
+
cmd << (option('long') ? '--long' : '--short')
|
1145
|
+
cmd << '--branch' if option('branch')
|
1146
|
+
if (val = option('ignore-submodules', ignore: false))
|
1147
|
+
cmd << basic_option('ignore-submodules', case val
|
1148
|
+
when '0', 'none'
|
1149
|
+
'none'
|
1150
|
+
when '1', 'untracked'
|
1151
|
+
'untracked'
|
1152
|
+
when '2', 'dirty'
|
1153
|
+
'dirty'
|
1154
|
+
else
|
1155
|
+
'all'
|
1156
|
+
end)
|
1157
|
+
end
|
1158
|
+
append_pathspec
|
1075
1159
|
end
|
1076
|
-
append_pathspec
|
1077
1160
|
if verbose
|
1078
1161
|
r = color(:red)
|
1079
1162
|
g = color(:green)
|
@@ -1115,7 +1198,7 @@ module Squared
|
|
1115
1198
|
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.call : @revbuild || {}
|
1116
1199
|
case flag
|
1117
1200
|
when :build
|
1118
|
-
op = OptionPartition.new(opts,
|
1201
|
+
op = OptionPartition.new(opts, %w[ignore-submodules=b? ignored=b? untracked-files=b?], project: self)
|
1119
1202
|
op.clear(append: true)
|
1120
1203
|
args = op.to_a
|
1121
1204
|
else
|
@@ -1142,10 +1225,7 @@ module Squared
|
|
1142
1225
|
rescue StandardError => e
|
1143
1226
|
warn log_message(Logger::WARN, e, pass: true) if warning?
|
1144
1227
|
else
|
1145
|
-
|
1146
|
-
msg = sub_style('completed', styles: theme[:active])
|
1147
|
-
puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
|
1148
|
-
end
|
1228
|
+
print_status(name, subject: 'revbuild', start: start, from: :completed)
|
1149
1229
|
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
|
1150
1230
|
sync: sync, utc: 'build')
|
1151
1231
|
end
|
@@ -1175,6 +1255,9 @@ module Squared
|
|
1175
1255
|
when :patch
|
1176
1256
|
cmd << '--patch'
|
1177
1257
|
append_pathspec(refs, pass: false)
|
1258
|
+
when :undo
|
1259
|
+
cmd << '--hard HEAD@{1}'
|
1260
|
+
ref = false
|
1178
1261
|
end
|
1179
1262
|
unless ref == false
|
1180
1263
|
append_commit(ref, head: true)
|
@@ -1185,7 +1268,7 @@ module Squared
|
|
1185
1268
|
|
1186
1269
|
def checkout(flag, opts = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil, merge: false)
|
1187
1270
|
cmd, opts = git_session('checkout', opts: opts)
|
1188
|
-
append_option 'force', 'merge'
|
1271
|
+
append_option 'force', 'f', 'merge'
|
1189
1272
|
case flag
|
1190
1273
|
when :branch
|
1191
1274
|
cmd << '--detach' if detach == 'd' || option('detach')
|
@@ -1227,7 +1310,7 @@ module Squared
|
|
1227
1310
|
elsif !session_arg?('s', 'sign', 'u', 'local-user')
|
1228
1311
|
cmd << '--annotate'
|
1229
1312
|
end
|
1230
|
-
cmd << '--force' if option('force')
|
1313
|
+
cmd << '--force' if option('force', 'f')
|
1231
1314
|
if !commit && message && (sha = commithash(message))
|
1232
1315
|
commit = sha
|
1233
1316
|
message = nil
|
@@ -1258,7 +1341,7 @@ module Squared
|
|
1258
1341
|
first: matchpathspec)
|
1259
1342
|
case flag
|
1260
1343
|
when :between, :contain
|
1261
|
-
op
|
1344
|
+
op.add_quote(range.join(flag == :between ? '..' : '...'))
|
1262
1345
|
else
|
1263
1346
|
op.merge(index)
|
1264
1347
|
end
|
@@ -1287,13 +1370,13 @@ module Squared
|
|
1287
1370
|
op.merge(range)
|
1288
1371
|
when :between, :contain
|
1289
1372
|
op.delete('--merge-base')
|
1290
|
-
op
|
1373
|
+
op.add_quote(range.join(flag == :between ? '..' : '...'))
|
1291
1374
|
else
|
1292
1375
|
op << '--merge-base' if option('merge-base')
|
1293
|
-
op
|
1376
|
+
op.add_quote(branch) if branch
|
1294
1377
|
if !index.empty?
|
1295
1378
|
if op.arg?('cached')
|
1296
|
-
raise_error("one commit only: #{index.join(', ')}", hint: '
|
1379
|
+
raise_error("one commit only: #{index.join(', ')}", hint: 'cached') if index.size > 1
|
1297
1380
|
op << index.first
|
1298
1381
|
else
|
1299
1382
|
op.merge(index)
|
@@ -1423,7 +1506,7 @@ module Squared
|
|
1423
1506
|
'--track'
|
1424
1507
|
end
|
1425
1508
|
end
|
1426
|
-
cmd << '--force' if option('force')
|
1509
|
+
cmd << '--force' if option('force', 'f')
|
1427
1510
|
cmd << shell_quote(target)
|
1428
1511
|
cmd << shell_quote(ref) if ref
|
1429
1512
|
when :track
|
@@ -1438,7 +1521,7 @@ module Squared
|
|
1438
1521
|
end
|
1439
1522
|
when :delete
|
1440
1523
|
remote&.each do |val|
|
1441
|
-
source git_output('push
|
1524
|
+
source git_output('push --delete', *val.split('/', 2).map { |s| shell_quote(s) })
|
1442
1525
|
end
|
1443
1526
|
force, list = refs.partition { |val| val.match?(/^[~^]/) }
|
1444
1527
|
force.each do |val|
|
@@ -1454,7 +1537,7 @@ module Squared
|
|
1454
1537
|
remote = nil
|
1455
1538
|
when :move, :copy
|
1456
1539
|
flag = "-#{flag.to_s[0]}"
|
1457
|
-
cmd << (option('force') ? flag.upcase : flag)
|
1540
|
+
cmd << (option('force', 'f') ? flag.upcase : flag)
|
1458
1541
|
refs.compact.each { |val| cmd << shell_quote(val) }
|
1459
1542
|
stdout = true
|
1460
1543
|
when :current
|
@@ -1464,7 +1547,7 @@ module Squared
|
|
1464
1547
|
when :list
|
1465
1548
|
op = OptionPartition.new(opts, OPT_GIT[:branch], cmd << '--list',
|
1466
1549
|
project: self, no: OPT_GIT[:no][:branch], single: /\Av+\z/)
|
1467
|
-
op.each { |val| op
|
1550
|
+
op.each { |val| op.add_quote(val) }
|
1468
1551
|
out, banner, from = source(io: true)
|
1469
1552
|
print_item banner
|
1470
1553
|
ret = write_lines(out, sub: [
|
@@ -1510,33 +1593,52 @@ module Squared
|
|
1510
1593
|
if !ref
|
1511
1594
|
print_success if flag == :create
|
1512
1595
|
elsif remote && target
|
1513
|
-
source git_output('push
|
1596
|
+
source git_output('push -u', shell_quote(ref.split('/', 2).first), shell_quote(target))
|
1514
1597
|
end
|
1515
1598
|
end
|
1516
1599
|
|
1517
|
-
def switch(flag, opts = [],
|
1518
|
-
cmd = git_session('switch', opts: opts)
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1600
|
+
def switch(flag, opts = [], branch: nil, commit: nil, track: nil)
|
1601
|
+
cmd, opts = git_session('switch', opts: opts)
|
1602
|
+
cmd << '--force' if option('force', 'f')
|
1603
|
+
if flag == :branch
|
1604
|
+
op = OptionPartition.new(opts, OPT_GIT[:switch], cmd, project: self, no: OPT_GIT[:no][:switch])
|
1605
|
+
op.add_quote(branch)
|
1606
|
+
else
|
1607
|
+
case flag
|
1608
|
+
when :create
|
1609
|
+
c = 'c'
|
1610
|
+
if target.start_with?('^')
|
1611
|
+
target = target[1..-1]
|
1612
|
+
c = c.upcase
|
1613
|
+
end
|
1614
|
+
cmd << quote_option(c, target)
|
1615
|
+
cmd << case (track ||= option('track', ignore: false))
|
1616
|
+
when 'n', 'N', '0', 'false'
|
1617
|
+
'--no-track'
|
1618
|
+
when 'y', 'Y', '1', 'true'
|
1619
|
+
'--track'
|
1620
|
+
when 'direct', 'inherit'
|
1621
|
+
basic_option 'track', track
|
1622
|
+
end
|
1623
|
+
when :detach
|
1624
|
+
cmd << "--#{flag}"
|
1525
1625
|
end
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
when :
|
1536
|
-
|
1626
|
+
append_head commit
|
1627
|
+
end
|
1628
|
+
source
|
1629
|
+
end
|
1630
|
+
|
1631
|
+
def submodule(flag, opts = [], path: nil, url: nil)
|
1632
|
+
cmd, opts = git_session('submodule', opts: opts)
|
1633
|
+
op = OptionPartition.new(opts, OPT_GIT[:submodule].fetch(flag, []), cmd, project: self)
|
1634
|
+
case flag
|
1635
|
+
when :branch, :url
|
1636
|
+
op << '--'
|
1637
|
+
op.add_path(path) if path
|
1638
|
+
op.add_quote(url) if url
|
1639
|
+
else
|
1640
|
+
op.splice(path: true)
|
1537
1641
|
end
|
1538
|
-
cmd << '--force' if option('force')
|
1539
|
-
append_head commit
|
1540
1642
|
source
|
1541
1643
|
end
|
1542
1644
|
|
@@ -1605,7 +1707,7 @@ module Squared
|
|
1605
1707
|
cmd, opts = git_session('ls-remote', '--refs', opts: opts)
|
1606
1708
|
cmd << "--#{flag}" unless flag == :remote
|
1607
1709
|
op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self)
|
1608
|
-
op
|
1710
|
+
op.add_quote(remote) if remote
|
1609
1711
|
out, banner, from = source(io: true)
|
1610
1712
|
print_item banner
|
1611
1713
|
ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
|
@@ -1615,6 +1717,7 @@ module Squared
|
|
1615
1717
|
def ls_files(flag, opts = [])
|
1616
1718
|
cmd, opts = git_session('ls-files', "--#{flag}", opts: opts)
|
1617
1719
|
op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self)
|
1720
|
+
op.splice(path: true, pattern: true)
|
1618
1721
|
out, banner, from = source(io: true)
|
1619
1722
|
print_item banner
|
1620
1723
|
ret = write_lines(out, grep: op.extras)
|
@@ -1623,10 +1726,16 @@ module Squared
|
|
1623
1726
|
|
1624
1727
|
def git(flag, opts = [])
|
1625
1728
|
cmd, opts = git_session(flag, opts: opts)
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1729
|
+
op = OptionPartition.new(opts, OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, []), cmd,
|
1730
|
+
project: self, no: OPT_GIT[:no][flag], first: case flag
|
1731
|
+
when :blame, :revert
|
1732
|
+
nil
|
1733
|
+
else matchpathspec end)
|
1629
1734
|
case flag
|
1735
|
+
when :blame
|
1736
|
+
raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
|
1737
|
+
op << '--' << shell_quote(path + op.delete_at(n))
|
1738
|
+
op.clear
|
1630
1739
|
when :revert
|
1631
1740
|
if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
|
1632
1741
|
op.clear
|
@@ -1637,16 +1746,16 @@ module Squared
|
|
1637
1746
|
end
|
1638
1747
|
when :add, :clean
|
1639
1748
|
if flag == :add && !op.arg?('pathspec-from-file')
|
1640
|
-
grep, list = op.
|
1641
|
-
|
1642
|
-
red = color(:red)
|
1749
|
+
grep, list = op.partition { |val| OptionPartition.pattern?(val) }
|
1750
|
+
unless grep.empty? && !list.empty?
|
1643
1751
|
grep.map! { |val| Regexp.new(val[1..-2]) }
|
1644
|
-
files =
|
1645
|
-
|
1752
|
+
files = [].tap do |out|
|
1753
|
+
status_data.each do |a, b|
|
1754
|
+
next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
|
1646
1755
|
|
1647
|
-
|
1756
|
+
out << "#{sub_style(b, styles: color(:red))} #{a}"
|
1757
|
+
end
|
1648
1758
|
end
|
1649
|
-
.compact
|
1650
1759
|
unless files.empty?
|
1651
1760
|
files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/,
|
1652
1761
|
accept: [['Add?', false, true]])
|
@@ -1654,7 +1763,7 @@ module Squared
|
|
1654
1763
|
op.swap(list + files)
|
1655
1764
|
end
|
1656
1765
|
end
|
1657
|
-
return source(git_session('status
|
1766
|
+
return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
|
1658
1767
|
|
1659
1768
|
verbose = flag == :add && !op.arg?('verbose')
|
1660
1769
|
print_success if success?(source) && verbose
|
@@ -1684,7 +1793,7 @@ module Squared
|
|
1684
1793
|
private
|
1685
1794
|
|
1686
1795
|
def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
|
1687
|
-
multiple: false, from: nil, **kwargs)
|
1796
|
+
multiple: false, hint: nil, from: nil, **kwargs)
|
1688
1797
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1689
1798
|
if io && banner == false
|
1690
1799
|
from = nil
|
@@ -1702,7 +1811,8 @@ module Squared
|
|
1702
1811
|
cmd = session_done cmd
|
1703
1812
|
log&.info cmd
|
1704
1813
|
banner = if banner
|
1705
|
-
|
1814
|
+
banner = (banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), '')
|
1815
|
+
format_banner(hint ? "#{banner} (#{hint})" : banner, banner: true)
|
1706
1816
|
end
|
1707
1817
|
on :first, from
|
1708
1818
|
begin
|
@@ -1741,11 +1851,7 @@ module Squared
|
|
1741
1851
|
end
|
1742
1852
|
end
|
1743
1853
|
rescue StandardError => e
|
1744
|
-
|
1745
|
-
ret = on(:error, from, e)
|
1746
|
-
raise if exception && ret != true
|
1747
|
-
|
1748
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
1854
|
+
on_error(e, from, pass: true)
|
1749
1855
|
nil
|
1750
1856
|
else
|
1751
1857
|
on :last, from
|
@@ -1754,16 +1860,7 @@ module Squared
|
|
1754
1860
|
end
|
1755
1861
|
|
1756
1862
|
def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
|
1757
|
-
grep =
|
1758
|
-
grep.map do |val|
|
1759
|
-
if val.is_a?(Regexp)
|
1760
|
-
val
|
1761
|
-
else
|
1762
|
-
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
1763
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
1764
|
-
end
|
1765
|
-
end
|
1766
|
-
end
|
1863
|
+
grep = grep.empty? ? nil : matchmap(grep, prefix)
|
1767
1864
|
sub = nil if stdin?
|
1768
1865
|
ret = 0
|
1769
1866
|
out = []
|
@@ -1837,8 +1934,7 @@ module Squared
|
|
1837
1934
|
glob = kwargs.fetch(:include, [])
|
1838
1935
|
pass = kwargs.fetch(:exclude, [])
|
1839
1936
|
ret = {}
|
1840
|
-
status_data(*args).each do |
|
1841
|
-
file = line.first
|
1937
|
+
status_data(*args).each do |file,|
|
1842
1938
|
next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1843
1939
|
next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1844
1940
|
|
@@ -1848,17 +1944,17 @@ module Squared
|
|
1848
1944
|
end
|
1849
1945
|
|
1850
1946
|
def status_data(*args)
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1947
|
+
[].tap do |ret|
|
1948
|
+
git_spawn('status -z -uall', *args).split("\x0").each do |line|
|
1949
|
+
next unless line =~ /^(.)(.) (.+)$/
|
1854
1950
|
|
1855
|
-
|
1951
|
+
ret << [$3, $2, $1]
|
1952
|
+
end
|
1856
1953
|
end
|
1857
|
-
ret
|
1858
1954
|
end
|
1859
1955
|
|
1860
1956
|
def append_pull(opts, list, target: @session, flag: nil, no: nil, remote: nil, from: nil)
|
1861
|
-
target << '--force' if option('force', target: target)
|
1957
|
+
target << '--force' if option('force', 'f', target: target)
|
1862
1958
|
append_submodules(target: target, from: from)
|
1863
1959
|
return if !remote && opts.empty?
|
1864
1960
|
|
@@ -1976,12 +2072,11 @@ module Squared
|
|
1976
2072
|
end
|
1977
2073
|
|
1978
2074
|
def git_session(*cmd, opts: nil, worktree: true, **kwargs)
|
1979
|
-
dir = worktree ? [
|
2075
|
+
dir = worktree ? [quote_option('work-tree', path), quote_option('git-dir', gitpath)] : []
|
1980
2076
|
return session('git', *dir, *cmd, **kwargs) unless opts
|
1981
2077
|
|
1982
2078
|
op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self)
|
1983
|
-
|
1984
|
-
[ret, op.extras]
|
2079
|
+
[session('git', *op.to_a, *cmd, **kwargs), op.extras]
|
1985
2080
|
end
|
1986
2081
|
|
1987
2082
|
def git_output(*cmd, **kwargs)
|