squared 0.5.3 → 0.5.4
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 +38 -0
- data/README.ruby.md +17 -13
- data/lib/squared/common/shell.rb +8 -3
- data/lib/squared/common/system.rb +3 -3
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +11 -6
- data/lib/squared/workspace/project/base.rb +52 -35
- data/lib/squared/workspace/project/docker.rb +68 -52
- data/lib/squared/workspace/project/git.rb +213 -129
- data/lib/squared/workspace/project/node.rb +25 -14
- data/lib/squared/workspace/project/python.rb +40 -11
- data/lib/squared/workspace/project/ruby.rb +27 -19
- data/lib/squared/workspace/project/support/class.rb +64 -13
- data/lib/squared/workspace/repo.rb +47 -43
- metadata +2 -2
@@ -4,7 +4,7 @@ module Squared
|
|
4
4
|
module Workspace
|
5
5
|
module Git
|
6
6
|
GIT_REPO = Support.hashobj
|
7
|
-
GIT_PROTO = %r{
|
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
|
@@ -247,7 +247,17 @@ module Squared
|
|
247
247
|
pop: %w[index].freeze,
|
248
248
|
apply: %w[index].freeze
|
249
249
|
}.freeze,
|
250
|
-
status: %w[u
|
250
|
+
status: %w[z u=bm? b|branch long s|short show-stash v|verbose column=b find-renames=i? ignore-submodules=b?
|
251
|
+
ignored=b? porcelain=b? untracked-files=b?].freeze,
|
252
|
+
submodule: {
|
253
|
+
status: %w[cached recursive].freeze,
|
254
|
+
update: %w[checkout f|force init merge N|no-fetch no-recommend-shallow no-single-branch recommend-shallow
|
255
|
+
rebase recursive remote single-branch depth=i filter=q jobs=i reference=b ref-format=q].freeze,
|
256
|
+
branch: %w[b|branch d|default].freeze,
|
257
|
+
sync: %w[recursive].freeze
|
258
|
+
}.freeze,
|
259
|
+
switch: %w[d|detach discard-changes f|force ignore-other-worktrees m|merge q|quiet conflict=b c|create=q
|
260
|
+
C|force-create=q orphan=q t|track=b].freeze,
|
251
261
|
tag: %w[n=im cleanup=b create-reflog i|ignore-case omit-empty color=b? column=b contains=b? format=q merged=b?
|
252
262
|
no-contains=b? no-merged=b? points-at=q sort=q trailer=q].freeze,
|
253
263
|
no: {
|
@@ -273,6 +283,8 @@ module Squared
|
|
273
283
|
rev_parse: %w[flags].freeze,
|
274
284
|
revert: %w[edit gpg-sign rerere-autoupdate].freeze,
|
275
285
|
show: %w[standard-notes].freeze,
|
286
|
+
status: %w[ahead-behind column renames].freeze,
|
287
|
+
switch: %w[guess progress recurse-submodules track].freeze,
|
276
288
|
tag: %w[column].freeze
|
277
289
|
}.freeze
|
278
290
|
}.freeze
|
@@ -294,10 +306,8 @@ module Squared
|
|
294
306
|
def populate(ws, **)
|
295
307
|
return if ws.series.exclude?(:pull, true)
|
296
308
|
|
297
|
-
namespace(
|
298
|
-
all = ws.task_join(
|
299
|
-
|
300
|
-
ws.format_desc(all, 'stash|rebase|autostash?,depend?')
|
309
|
+
namespace(ws.task_name('git')) do |ns|
|
310
|
+
ws.format_desc(all = ws.task_join(ns.scope.path, 'all'), 'stash|rebase|autostash?,depend?')
|
301
311
|
task 'all' do |_, args|
|
302
312
|
args = args.to_a
|
303
313
|
cmd = if args.include?('stash')
|
@@ -314,6 +324,7 @@ module Squared
|
|
314
324
|
cmd << ws.task_sync('build')
|
315
325
|
Common::Utils.task_invoke(*cmd, **ws.invokeargs)
|
316
326
|
end
|
327
|
+
|
317
328
|
ws.series.sync << all
|
318
329
|
ws.series.multiple << all
|
319
330
|
end
|
@@ -335,25 +346,27 @@ module Squared
|
|
335
346
|
'checkout' => %i[commit branch track detach path].freeze,
|
336
347
|
'commit' => %i[add all amend amend-orig fixup].freeze,
|
337
348
|
'diff' => %i[head branch files view between contain].freeze,
|
338
|
-
'fetch' => %i[origin remote].freeze,
|
349
|
+
'fetch' => %i[origin remote all].freeze,
|
339
350
|
'files' => %i[cached modified deleted others].freeze,
|
340
|
-
'git' => %i[add blame clean mv revert rm].freeze,
|
351
|
+
'git' => %i[add blame clean mv revert rm status].freeze,
|
341
352
|
'log' => %i[view between contain].freeze,
|
342
353
|
'merge' => %i[commit no-commit send].freeze,
|
343
|
-
'pull' => %i[origin remote].freeze,
|
354
|
+
'pull' => %i[origin remote all].freeze,
|
344
355
|
'rebase' => %i[branch onto send].freeze,
|
345
356
|
'refs' => %i[heads tags remote].freeze,
|
346
|
-
'reset' => %i[commit index patch mode].freeze,
|
357
|
+
'reset' => %i[commit index patch mode undo].freeze,
|
347
358
|
'restore' => %i[source staged worktree].freeze,
|
348
359
|
'rev' => %i[commit build output].freeze,
|
349
360
|
'show' => %i[format oneline textconv].freeze,
|
350
361
|
'stash' => %i[push pop apply branch drop clear list].freeze,
|
351
|
-
'
|
362
|
+
'submodule' => %i[status update branch url sync].freeze,
|
363
|
+
'switch' => %i[branch create detach].freeze,
|
352
364
|
'tag' => %i[add sign delete list].freeze
|
353
365
|
})
|
354
366
|
|
355
367
|
def initialize(*, **)
|
356
368
|
super
|
369
|
+
@submodule = basepath('.gitmodules').exist?
|
357
370
|
initialize_ref Git.ref if gitpath.exist?
|
358
371
|
end
|
359
372
|
|
@@ -363,7 +376,7 @@ module Squared
|
|
363
376
|
|
364
377
|
def populate(*, **)
|
365
378
|
super
|
366
|
-
return unless ref?(Git.ref)
|
379
|
+
return unless ref?(Git.ref) || @only
|
367
380
|
|
368
381
|
namespace name do
|
369
382
|
Git.subtasks do |action, flags|
|
@@ -385,11 +398,34 @@ module Squared
|
|
385
398
|
__send__(action, flag, args, remote: remote)
|
386
399
|
end
|
387
400
|
else
|
388
|
-
format_desc
|
401
|
+
format_desc(action, flag, 'opts*', after: flag == :all && action == 'pull' ? 'pattern*' : nil)
|
389
402
|
task flag do |_, args|
|
390
403
|
__send__ action, flag, args.to_a
|
391
404
|
end
|
392
405
|
end
|
406
|
+
when 'submodule'
|
407
|
+
break unless @submodule
|
408
|
+
|
409
|
+
case flag
|
410
|
+
when :branch
|
411
|
+
format_desc action, flag, 'path,opts*'
|
412
|
+
task flag, [:path] do |_, args|
|
413
|
+
path = param_guard(action, flag, args: args, key: :path)
|
414
|
+
submodule(flag, args.extras, path: path)
|
415
|
+
end
|
416
|
+
when :url
|
417
|
+
format_desc action, flag, 'path,url,opts*'
|
418
|
+
task flag, [:path, :url] do |_, args|
|
419
|
+
path = param_guard(action, flag, args: args, key: :path)
|
420
|
+
url = param_guard(action, flag, args: args, key: :url)
|
421
|
+
submodule(flag, args.extras, path: path, url: url)
|
422
|
+
end
|
423
|
+
else
|
424
|
+
format_desc action, flag, 'opts*,path*'
|
425
|
+
task flag do |_, args|
|
426
|
+
submodule flag, args.to_a
|
427
|
+
end
|
428
|
+
end
|
393
429
|
when 'commit'
|
394
430
|
case flag
|
395
431
|
when :all
|
@@ -629,10 +665,7 @@ module Squared
|
|
629
665
|
task flag, [:upstream, :name] do |_, args|
|
630
666
|
if (ref = args.upstream)
|
631
667
|
target = args.name
|
632
|
-
if ref.
|
633
|
-
ref = ref[1..-1]
|
634
|
-
remote = true
|
635
|
-
end
|
668
|
+
remote = true if ref.delete_prefix!('~')
|
636
669
|
else
|
637
670
|
ref, remote, target = choice_refs('Choose a remote', 'remotes', accept: [['Push?', true]],
|
638
671
|
values: ['Enter branch name'])
|
@@ -685,10 +718,10 @@ module Squared
|
|
685
718
|
when :create
|
686
719
|
format_desc action, flag, '(^)name,ref?=HEAD|:'
|
687
720
|
task flag, [:name, :commit] do |_, args|
|
688
|
-
|
721
|
+
branch = param_guard(action, flag, args: args, key: :name)
|
689
722
|
commit = commithead args.commit
|
690
723
|
commit, track = choice_commit(values: ['Track? [Y|n]'], force: false) if commit == ':'
|
691
|
-
switch(flag,
|
724
|
+
switch(flag, branch: branch, commit: commit, track: track)
|
692
725
|
end
|
693
726
|
when :detach
|
694
727
|
format_desc action, flag, 'ref?=HEAD'
|
@@ -696,11 +729,16 @@ module Squared
|
|
696
729
|
commit = commithead(args.commit) || choice_commit(force: false)
|
697
730
|
switch(flag, commit: commit)
|
698
731
|
end
|
699
|
-
when :
|
700
|
-
format_desc action, flag, '
|
701
|
-
task flag, [:
|
702
|
-
|
703
|
-
|
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'))
|
704
742
|
end
|
705
743
|
end
|
706
744
|
when 'reset'
|
@@ -721,10 +759,10 @@ module Squared
|
|
721
759
|
end
|
722
760
|
print_success if success?(reset(flag, args, commit: commit))
|
723
761
|
end
|
724
|
-
when :index
|
725
|
-
format_desc
|
762
|
+
when :index, :undo
|
763
|
+
format_desc(action, flag, flag == :index ? 'opts*,pathspec*' : nil)
|
726
764
|
task flag do |_, args|
|
727
|
-
reset
|
765
|
+
reset(flag, flag == :index ? args.to_a : [])
|
728
766
|
end
|
729
767
|
when :mode
|
730
768
|
format_desc action, flag, 'mode,ref?=HEAD|:'
|
@@ -823,7 +861,7 @@ module Squared
|
|
823
861
|
rev_parse(flag, ref: ref, size: size)
|
824
862
|
end
|
825
863
|
when :build
|
826
|
-
format_desc action, flag,
|
864
|
+
format_desc action, flag, 'opts*'
|
827
865
|
task flag do |_, args|
|
828
866
|
revbuild flag, args.to_a
|
829
867
|
end
|
@@ -840,7 +878,7 @@ module Squared
|
|
840
878
|
ls_remote(flag, args.extras, remote: args.remote)
|
841
879
|
end
|
842
880
|
else
|
843
|
-
format_desc
|
881
|
+
format_desc(action, flag, 'opts*,pattern*', after: action == 'files' ? 'pathspec*' : nil)
|
844
882
|
task flag do |_, args|
|
845
883
|
__send__(action == 'refs' ? :ls_remote : :ls_files, flag, args.to_a)
|
846
884
|
end
|
@@ -885,10 +923,13 @@ module Squared
|
|
885
923
|
when :mv then 'source+,destination'
|
886
924
|
when :revert then 'commit+' end
|
887
925
|
format_desc(action, flag, 'opts*', before: before, after: case flag
|
888
|
-
when :add
|
889
|
-
|
926
|
+
when :add
|
927
|
+
'pathspec*,pattern*'
|
928
|
+
when :clean, :rm, :status
|
929
|
+
'pathspec*'
|
930
|
+
end)
|
890
931
|
task flag do |_, args|
|
891
|
-
git flag, args.to_a
|
932
|
+
__send__(flag == :status ? :status : :git, flag, args.to_a)
|
892
933
|
end
|
893
934
|
end
|
894
935
|
end
|
@@ -912,11 +953,44 @@ module Squared
|
|
912
953
|
super
|
913
954
|
end
|
914
955
|
|
915
|
-
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)
|
916
957
|
cmd, opts = git_session('pull', opts: opts)
|
917
|
-
|
958
|
+
cmd << '--autostash' if option('autostash')
|
959
|
+
case flag
|
960
|
+
when :rebase
|
918
961
|
cmd << '--rebase'
|
919
|
-
|
962
|
+
when :all
|
963
|
+
unless git_spawn('status -s -z --untracked-files=all').empty?
|
964
|
+
if confirm('Stash local changes?', 'Y')
|
965
|
+
git_spawn 'stash push --keep-index --quiet'
|
966
|
+
elsif !(force = confirm('Force checkout?', '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
|
920
994
|
else
|
921
995
|
cmd << '--autostash' if flag == :autostash
|
922
996
|
option('rebase', ignore: false) do |val|
|
@@ -935,7 +1009,7 @@ module Squared
|
|
935
1009
|
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
|
936
1010
|
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(.*)$/, styles: color(:green), index: 3 }
|
937
1011
|
]
|
938
|
-
end, **threadargs)
|
1012
|
+
end, hint: hint, **threadargs)
|
939
1013
|
end
|
940
1014
|
|
941
1015
|
def rebase(flag = nil, opts = [], sync: invoked_sync?('rebase', flag), commit: nil, upstream: nil, branch: nil,
|
@@ -972,6 +1046,7 @@ module Squared
|
|
972
1046
|
|
973
1047
|
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
|
974
1048
|
opts = git_session('fetch', opts: opts).last
|
1049
|
+
opts << 'all' if flag == :all || option('all')
|
975
1050
|
append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
|
976
1051
|
remote: remote, flag: flag, from: :fetch)
|
977
1052
|
source(sync: sync, **threadargs)
|
@@ -1014,15 +1089,15 @@ module Squared
|
|
1014
1089
|
cmd, opts = git_session('stash', flag, opts: opts)
|
1015
1090
|
list = OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, [])
|
1016
1091
|
if flag == :list
|
1017
|
-
list += collect_hash
|
1018
|
-
no = collect_hash
|
1092
|
+
list += collect_hash OPT_GIT[:log]
|
1093
|
+
no = collect_hash OPT_GIT[:no][:log]
|
1019
1094
|
end
|
1020
1095
|
op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: flag == :push ? matchpathspec : nil)
|
1021
1096
|
case flag
|
1022
1097
|
when :push
|
1023
1098
|
append_pathspec op.extras
|
1024
1099
|
when :pop, :apply, :drop, :branch
|
1025
|
-
if op.
|
1100
|
+
if op.remove(':')
|
1026
1101
|
if flag == :branch
|
1027
1102
|
if op.empty?
|
1028
1103
|
values = [['Branch name', true]]
|
@@ -1055,29 +1130,34 @@ module Squared
|
|
1055
1130
|
end
|
1056
1131
|
else
|
1057
1132
|
git_session('stash', 'push', opts: opts)
|
1058
|
-
append_option(OPT_GIT[:stash][:push]
|
1133
|
+
append_option(OptionPartition.select(OPT_GIT[:stash][:push], no: false), no: true, ignore: false)
|
1059
1134
|
append_message
|
1060
1135
|
end
|
1061
1136
|
source(banner: !quiet?, sync: sync, **threadargs)
|
1062
1137
|
end
|
1063
1138
|
|
1064
|
-
def status(
|
1065
|
-
cmd = git_session
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1139
|
+
def status(flag = nil, opts = [])
|
1140
|
+
cmd, opts = git_session('status', opts: opts)
|
1141
|
+
if flag
|
1142
|
+
op = OptionPartition.new(opts, OPT_GIT[:status], cmd, project: self, no: OPT_GIT[:no][:status])
|
1143
|
+
append_pathspec op.extras
|
1144
|
+
else
|
1145
|
+
cmd << (option('long') ? '--long' : '--short')
|
1146
|
+
cmd << '--branch' if option('branch')
|
1147
|
+
option('ignore-submodules', ignore: false) do |val|
|
1148
|
+
cmd << basic_option('ignore-submodules', case val
|
1149
|
+
when '0', 'none'
|
1150
|
+
'none'
|
1151
|
+
when '1', 'untracked'
|
1152
|
+
'untracked'
|
1153
|
+
when '2', 'dirty'
|
1154
|
+
'dirty'
|
1155
|
+
else
|
1156
|
+
'all'
|
1157
|
+
end)
|
1158
|
+
end
|
1159
|
+
append_pathspec
|
1079
1160
|
end
|
1080
|
-
append_pathspec
|
1081
1161
|
if verbose
|
1082
1162
|
r = color(:red)
|
1083
1163
|
g = color(:green)
|
@@ -1119,7 +1199,7 @@ module Squared
|
|
1119
1199
|
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.call : @revbuild || {}
|
1120
1200
|
case flag
|
1121
1201
|
when :build
|
1122
|
-
op = OptionPartition.new(opts,
|
1202
|
+
op = OptionPartition.new(opts, %w[ignore-submodules=b? ignored=b? untracked-files=b?], project: self)
|
1123
1203
|
op.clear(append: true)
|
1124
1204
|
args = op.to_a
|
1125
1205
|
else
|
@@ -1176,6 +1256,9 @@ module Squared
|
|
1176
1256
|
when :patch
|
1177
1257
|
cmd << '--patch'
|
1178
1258
|
append_pathspec(refs, pass: false)
|
1259
|
+
when :undo
|
1260
|
+
cmd << '--hard HEAD@{1}'
|
1261
|
+
ref = false
|
1179
1262
|
end
|
1180
1263
|
unless ref == false
|
1181
1264
|
append_commit(ref, head: true)
|
@@ -1186,20 +1269,15 @@ module Squared
|
|
1186
1269
|
|
1187
1270
|
def checkout(flag, opts = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil, merge: false)
|
1188
1271
|
cmd, opts = git_session('checkout', opts: opts)
|
1189
|
-
append_option 'force', 'merge'
|
1272
|
+
append_option 'force', 'f', 'merge'
|
1190
1273
|
case flag
|
1191
1274
|
when :branch
|
1192
1275
|
cmd << '--detach' if detach == 'd' || option('detach')
|
1193
1276
|
append_option('track', equals: true)
|
1194
1277
|
cmd << (create ? quote_option(create, branch) : branch) << commit
|
1195
1278
|
when :track
|
1196
|
-
|
1197
|
-
|
1198
|
-
opt = 'B'
|
1199
|
-
branch = branch[1..-1]
|
1200
|
-
end
|
1201
|
-
cmd << quote_option(opt || 'b', branch)
|
1202
|
-
end
|
1279
|
+
|
1280
|
+
cmd << quote_option(branch.delete_prefix!('^') ? 'B' : 'b', branch) if branch
|
1203
1281
|
cmd << '--track' << shell_quote(origin)
|
1204
1282
|
when :detach
|
1205
1283
|
cmd << '-m' if merge
|
@@ -1228,7 +1306,7 @@ module Squared
|
|
1228
1306
|
elsif !session_arg?('s', 'sign', 'u', 'local-user')
|
1229
1307
|
cmd << '--annotate'
|
1230
1308
|
end
|
1231
|
-
cmd << '--force' if option('force')
|
1309
|
+
cmd << '--force' if option('force', 'f')
|
1232
1310
|
if !commit && message && (sha = commithash(message))
|
1233
1311
|
commit = sha
|
1234
1312
|
message = nil
|
@@ -1259,7 +1337,7 @@ module Squared
|
|
1259
1337
|
first: matchpathspec)
|
1260
1338
|
case flag
|
1261
1339
|
when :between, :contain
|
1262
|
-
op
|
1340
|
+
op.add_quote(range.join(flag == :between ? '..' : '...'))
|
1263
1341
|
else
|
1264
1342
|
op.merge(index)
|
1265
1343
|
end
|
@@ -1288,13 +1366,13 @@ module Squared
|
|
1288
1366
|
op.merge(range)
|
1289
1367
|
when :between, :contain
|
1290
1368
|
op.delete('--merge-base')
|
1291
|
-
op
|
1369
|
+
op.add_quote(range.join(flag == :between ? '..' : '...'))
|
1292
1370
|
else
|
1293
1371
|
op << '--merge-base' if option('merge-base')
|
1294
|
-
op
|
1372
|
+
op.add_quote(branch) if branch
|
1295
1373
|
if !index.empty?
|
1296
1374
|
if op.arg?('cached')
|
1297
|
-
raise_error("one commit only: #{index.join(', ')}", hint: '
|
1375
|
+
raise_error("one commit only: #{index.join(', ')}", hint: 'cached') if index.size > 1
|
1298
1376
|
op << index.first
|
1299
1377
|
else
|
1300
1378
|
op.merge(index)
|
@@ -1424,13 +1502,13 @@ module Squared
|
|
1424
1502
|
'--track'
|
1425
1503
|
end
|
1426
1504
|
end
|
1427
|
-
cmd << '--force' if option('force')
|
1505
|
+
cmd << '--force' if option('force', 'f')
|
1428
1506
|
cmd << shell_quote(target)
|
1429
1507
|
cmd << shell_quote(ref) if ref
|
1430
1508
|
when :track
|
1431
1509
|
raise_error('invalid upstream', hint: ref) unless ref.include?('/')
|
1432
|
-
if ref.
|
1433
|
-
cmd << '--unset-upstream' << shell_quote(ref
|
1510
|
+
if ref.delete_prefix!('^')
|
1511
|
+
cmd << '--unset-upstream' << shell_quote(ref)
|
1434
1512
|
remote = false
|
1435
1513
|
stdout = true
|
1436
1514
|
else
|
@@ -1439,7 +1517,7 @@ module Squared
|
|
1439
1517
|
end
|
1440
1518
|
when :delete
|
1441
1519
|
remote&.each do |val|
|
1442
|
-
source git_output('push
|
1520
|
+
source git_output('push --delete', *val.split('/', 2).map { |s| shell_quote(s) })
|
1443
1521
|
end
|
1444
1522
|
force, list = refs.partition { |val| val.start_with?(/[~^]/) }
|
1445
1523
|
force.each do |val|
|
@@ -1455,7 +1533,7 @@ module Squared
|
|
1455
1533
|
remote = nil
|
1456
1534
|
when :move, :copy
|
1457
1535
|
flag = "-#{flag.to_s[0]}"
|
1458
|
-
cmd << (option('force') ? flag.upcase : flag)
|
1536
|
+
cmd << (option('force', 'f') ? flag.upcase : flag)
|
1459
1537
|
refs.compact.each { |val| cmd << shell_quote(val) }
|
1460
1538
|
stdout = true
|
1461
1539
|
when :current
|
@@ -1465,7 +1543,7 @@ module Squared
|
|
1465
1543
|
when :list
|
1466
1544
|
op = OptionPartition.new(opts, OPT_GIT[:branch], cmd << '--list',
|
1467
1545
|
project: self, no: OPT_GIT[:no][:branch], single: /\Av+\z/)
|
1468
|
-
op.each { |val| op
|
1546
|
+
op.each { |val| op.add_quote(val) }
|
1469
1547
|
out, banner, from = source(io: true)
|
1470
1548
|
print_item banner
|
1471
1549
|
ret = write_lines(out, sub: [
|
@@ -1511,33 +1589,47 @@ module Squared
|
|
1511
1589
|
if !ref
|
1512
1590
|
print_success if flag == :create
|
1513
1591
|
elsif remote && target
|
1514
|
-
source git_output('push
|
1592
|
+
source git_output('push -u', shell_quote(ref.split('/', 2).first), shell_quote(target))
|
1515
1593
|
end
|
1516
1594
|
end
|
1517
1595
|
|
1518
|
-
def switch(flag, opts = [],
|
1519
|
-
cmd = git_session('switch', opts: opts)
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1596
|
+
def switch(flag, opts = [], branch: nil, commit: nil, track: nil)
|
1597
|
+
cmd, opts = git_session('switch', opts: opts)
|
1598
|
+
cmd << '--force' if option('force', 'f')
|
1599
|
+
if flag == :branch
|
1600
|
+
op = OptionPartition.new(opts, OPT_GIT[:switch], cmd, project: self, no: OPT_GIT[:no][:switch])
|
1601
|
+
op.add_quote(branch)
|
1602
|
+
else
|
1603
|
+
case flag
|
1604
|
+
when :create
|
1605
|
+
cmd << quote_option(branch.delete_prefix!('^') ? 'C' : 'c', branch)
|
1606
|
+
cmd << case (track ||= option('track', ignore: false))
|
1607
|
+
when 'n', 'N', '0', 'false'
|
1608
|
+
'--no-track'
|
1609
|
+
when 'y', 'Y', '1', 'true'
|
1610
|
+
'--track'
|
1611
|
+
when 'direct', 'inherit'
|
1612
|
+
basic_option 'track', track
|
1613
|
+
end
|
1614
|
+
when :detach
|
1615
|
+
cmd << "--#{flag}"
|
1526
1616
|
end
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
when :
|
1537
|
-
|
1617
|
+
append_head commit
|
1618
|
+
end
|
1619
|
+
source
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
def submodule(flag, opts = [], path: nil, url: nil)
|
1623
|
+
cmd, opts = git_session('submodule', opts: opts)
|
1624
|
+
op = OptionPartition.new(opts, OPT_GIT[:submodule].fetch(flag, []), cmd, project: self)
|
1625
|
+
case flag
|
1626
|
+
when :branch, :url
|
1627
|
+
op << '--'
|
1628
|
+
op.add_path(path) if path
|
1629
|
+
op.add_quote(url) if url
|
1630
|
+
else
|
1631
|
+
op.splice(path: true)
|
1538
1632
|
end
|
1539
|
-
cmd << '--force' if option('force')
|
1540
|
-
append_head commit
|
1541
1633
|
source
|
1542
1634
|
end
|
1543
1635
|
|
@@ -1606,7 +1698,7 @@ module Squared
|
|
1606
1698
|
cmd, opts = git_session('ls-remote', '--refs', opts: opts)
|
1607
1699
|
cmd << "--#{flag}" unless flag == :remote
|
1608
1700
|
op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self)
|
1609
|
-
op
|
1701
|
+
op.add_quote(remote) if remote
|
1610
1702
|
out, banner, from = source(io: true)
|
1611
1703
|
print_item banner
|
1612
1704
|
ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
|
@@ -1616,6 +1708,7 @@ module Squared
|
|
1616
1708
|
def ls_files(flag, opts = [])
|
1617
1709
|
cmd, opts = git_session('ls-files', "--#{flag}", opts: opts)
|
1618
1710
|
op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self)
|
1711
|
+
op.splice(path: true, pattern: true)
|
1619
1712
|
out, banner, from = source(io: true)
|
1620
1713
|
print_item banner
|
1621
1714
|
ret = write_lines(out, grep: op.extras)
|
@@ -1644,15 +1737,16 @@ module Squared
|
|
1644
1737
|
end
|
1645
1738
|
when :add, :clean
|
1646
1739
|
if flag == :add && !op.arg?('pathspec-from-file')
|
1647
|
-
grep, list = op.partition { |val|
|
1740
|
+
grep, list = op.partition { |val| OptionPartition.pattern?(val) }
|
1648
1741
|
unless grep.empty? && !list.empty?
|
1649
1742
|
grep.map! { |val| Regexp.new(val[1..-2]) }
|
1650
|
-
files =
|
1651
|
-
|
1743
|
+
files = [].tap do |out|
|
1744
|
+
status_data.each do |a, b|
|
1745
|
+
next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
|
1652
1746
|
|
1653
|
-
|
1747
|
+
out << "#{sub_style(b, styles: color(:red))} #{a}"
|
1748
|
+
end
|
1654
1749
|
end
|
1655
|
-
.compact
|
1656
1750
|
unless files.empty?
|
1657
1751
|
files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/,
|
1658
1752
|
accept: [['Add?', false, true]])
|
@@ -1660,7 +1754,7 @@ module Squared
|
|
1660
1754
|
op.swap(list + files)
|
1661
1755
|
end
|
1662
1756
|
end
|
1663
|
-
return source(git_session('status
|
1757
|
+
return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
|
1664
1758
|
|
1665
1759
|
verbose = flag == :add && !op.arg?('verbose')
|
1666
1760
|
print_success if success?(source) && verbose
|
@@ -1690,7 +1784,7 @@ module Squared
|
|
1690
1784
|
private
|
1691
1785
|
|
1692
1786
|
def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
|
1693
|
-
multiple: false, from: nil, **kwargs)
|
1787
|
+
multiple: false, hint: nil, from: nil, **kwargs)
|
1694
1788
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1695
1789
|
if io && banner == false
|
1696
1790
|
from = nil
|
@@ -1708,7 +1802,8 @@ module Squared
|
|
1708
1802
|
cmd = session_done cmd
|
1709
1803
|
log&.info cmd
|
1710
1804
|
banner = if banner
|
1711
|
-
|
1805
|
+
banner = (banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), '')
|
1806
|
+
format_banner(hint ? "#{banner} (#{hint})" : banner, banner: true)
|
1712
1807
|
end
|
1713
1808
|
on :first, from
|
1714
1809
|
begin
|
@@ -1756,16 +1851,7 @@ module Squared
|
|
1756
1851
|
end
|
1757
1852
|
|
1758
1853
|
def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
|
1759
|
-
grep =
|
1760
|
-
grep.map do |val|
|
1761
|
-
if val.is_a?(Regexp)
|
1762
|
-
val
|
1763
|
-
else
|
1764
|
-
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
1765
|
-
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
1766
|
-
end
|
1767
|
-
end
|
1768
|
-
end
|
1854
|
+
grep = grep.empty? ? nil : matchmap(grep, prefix)
|
1769
1855
|
sub = nil if stdin?
|
1770
1856
|
ret = 0
|
1771
1857
|
out = []
|
@@ -1839,8 +1925,7 @@ module Squared
|
|
1839
1925
|
glob = kwargs.fetch(:include, [])
|
1840
1926
|
pass = kwargs.fetch(:exclude, [])
|
1841
1927
|
ret = {}
|
1842
|
-
status_data(*args).each do |
|
1843
|
-
file = line.first
|
1928
|
+
status_data(*args).each do |file,|
|
1844
1929
|
next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1845
1930
|
next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1846
1931
|
|
@@ -1850,17 +1935,17 @@ module Squared
|
|
1850
1935
|
end
|
1851
1936
|
|
1852
1937
|
def status_data(*args)
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1938
|
+
[].tap do |ret|
|
1939
|
+
git_spawn('status -z -uall', *args).split("\x0").each do |line|
|
1940
|
+
next unless line =~ /^(.)(.) (.+)$/
|
1856
1941
|
|
1857
|
-
|
1942
|
+
ret << [$3, $2, $1]
|
1943
|
+
end
|
1858
1944
|
end
|
1859
|
-
ret
|
1860
1945
|
end
|
1861
1946
|
|
1862
1947
|
def append_pull(opts, list, target: @session, flag: nil, no: nil, remote: nil, from: nil)
|
1863
|
-
target << '--force' if option('force', target: target)
|
1948
|
+
target << '--force' if option('force', 'f', target: target)
|
1864
1949
|
append_submodules(target: target, from: from)
|
1865
1950
|
return if !remote && opts.empty?
|
1866
1951
|
|
@@ -1918,7 +2003,7 @@ module Squared
|
|
1918
2003
|
option_clear files
|
1919
2004
|
true
|
1920
2005
|
else
|
1921
|
-
option('pathspec', target: target) { |val| files = split_escape
|
2006
|
+
option('pathspec', target: target) { |val| files = split_escape(val) } if files.empty?
|
1922
2007
|
files = projectmap(files, parent: parent, pass: pass)
|
1923
2008
|
if !files.empty?
|
1924
2009
|
target << '--' << files.join(' ')
|
@@ -1976,12 +2061,11 @@ module Squared
|
|
1976
2061
|
end
|
1977
2062
|
|
1978
2063
|
def git_session(*cmd, opts: nil, worktree: true, **kwargs)
|
1979
|
-
dir = worktree ? [
|
2064
|
+
dir = worktree ? [quote_option('work-tree', path), quote_option('git-dir', gitpath)] : []
|
1980
2065
|
return session('git', *dir, *cmd, **kwargs) unless opts
|
1981
2066
|
|
1982
2067
|
op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self)
|
1983
|
-
|
1984
|
-
[ret, op.extras]
|
2068
|
+
[session('git', *op.to_a, *cmd, **kwargs), op.extras]
|
1985
2069
|
end
|
1986
2070
|
|
1987
2071
|
def git_output(*cmd, **kwargs)
|