squared 0.7.13 → 0.8.0
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 +44 -176
- data/README.md +38 -35
- data/lib/squared/common/base.rb +0 -9
- data/lib/squared/common/format.rb +5 -14
- data/lib/squared/common/prompt.rb +30 -32
- data/lib/squared/common/shell.rb +11 -11
- data/lib/squared/common/system.rb +9 -19
- data/lib/squared/common/utils.rb +19 -23
- data/lib/squared/config.rb +5 -12
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +99 -31
- data/lib/squared/workspace/project/base.rb +84 -94
- data/lib/squared/workspace/project/docker.rb +85 -117
- data/lib/squared/workspace/project/git.rb +187 -94
- data/lib/squared/workspace/project/node.rb +184 -177
- data/lib/squared/workspace/project/python.rb +52 -51
- data/lib/squared/workspace/project/ruby.rb +54 -46
- data/lib/squared/workspace/project/support/class.rb +2 -2
- data/lib/squared/workspace/project/support/optionpartition.rb +17 -42
- data/lib/squared/workspace/project/support/utils.rb +15 -22
- data/lib/squared/workspace/repo.rb +10 -7
- data/lib/squared/workspace/series.rb +12 -5
- metadata +2 -2
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Squared
|
|
4
4
|
module Workspace
|
|
5
|
+
GIT_PROTO = %r{\A(https?|ssh|git|file)://}i.freeze
|
|
6
|
+
private_constant :GIT_PROTO
|
|
7
|
+
|
|
5
8
|
module Git
|
|
6
9
|
GIT_REPO = Support.hashobj
|
|
7
|
-
|
|
8
|
-
private_constant :GIT_REPO, :GIT_PROTO
|
|
10
|
+
private_constant :GIT_REPO
|
|
9
11
|
|
|
10
12
|
attr_reader :revfile
|
|
11
13
|
|
|
@@ -141,6 +143,7 @@ module Squared
|
|
|
141
143
|
end
|
|
142
144
|
File.write(@revfile, JSON.pretty_generate(@revdoc))
|
|
143
145
|
rescue => e
|
|
146
|
+
log&.debug e
|
|
144
147
|
warn log_warn(e, pass: true) if warning
|
|
145
148
|
ensure
|
|
146
149
|
@revlock = false
|
|
@@ -169,10 +172,9 @@ module Squared
|
|
|
169
172
|
fetch: {
|
|
170
173
|
base: %w[multiple porcelain progress P|prune-tags refetch stdin u|update-head-ok
|
|
171
174
|
recurse-submodules-default=b?].freeze,
|
|
172
|
-
pull: %w[n t
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
upload-pack=q].freeze
|
|
175
|
+
pull: %w[4 6 n t a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet set-upstream
|
|
176
|
+
unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q recurse-submodules=v
|
|
177
|
+
refmap=q o|server-option=q shallow-exclude=b shallow-since=v upload-pack=q].freeze
|
|
176
178
|
}.freeze,
|
|
177
179
|
git: {
|
|
178
180
|
add: %w[N|intent-to-add].freeze,
|
|
@@ -187,6 +189,7 @@ module Squared
|
|
|
187
189
|
A|after-context=i B|before-context=i color=b C|context=i m|max-count=n max-depth=n
|
|
188
190
|
open-files-in-pager=b threads=n].freeze,
|
|
189
191
|
mv: %w[k f|force n|dry-run v|verbose].freeze,
|
|
192
|
+
remote: %w[f m=b t=b no-tags tags mirror=b].freeze,
|
|
190
193
|
revert: %w[e S=bm? n|no-commit reference cleanup=b gpg-sign=b? m|mainline=i s|signoff strategy=b
|
|
191
194
|
X|strategy-option=b].freeze,
|
|
192
195
|
rm: %w[r cached f|force n|dry-run ignore-unmatch pathspec-file-nul q|quiet sparse
|
|
@@ -212,7 +215,7 @@ module Squared
|
|
|
212
215
|
graph ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames
|
|
213
216
|
numstat patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary
|
|
214
217
|
a|text abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
|
|
215
|
-
diff-algorithm=b diff-filter=
|
|
218
|
+
diff-algorithm=b diff-filter=e? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
|
|
216
219
|
find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? line-prefix=q
|
|
217
220
|
max-depth=n output=p output-indicator-context=q output-indicator-new=q output-indicator-old=q
|
|
218
221
|
relative=p rotate-to=p skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i
|
|
@@ -233,6 +236,16 @@ module Squared
|
|
|
233
236
|
f|force-rebase ignore-date ignore-whitespace i|interactive keep-base m|merge no-ff q|quiet quit
|
|
234
237
|
reset-author-date root show-current-patch signoff v|verbose empty=b x|exec=q gpg-sign=b? onto=b
|
|
235
238
|
r|rebase-merges=b s|strategy=b X|strategy-option=b trailer=q whitespace=b].freeze,
|
|
239
|
+
remote: {
|
|
240
|
+
rename: %w[no-progress progress].freeze,
|
|
241
|
+
remove: [].freeze,
|
|
242
|
+
'set-head': %w[a|auto d|delete].freeze,
|
|
243
|
+
'set-branches': %w[add].freeze,
|
|
244
|
+
'get-url': %w[all push].freeze,
|
|
245
|
+
'set-url': %w[add delete push].freeze,
|
|
246
|
+
show: %w[n].freeze,
|
|
247
|
+
prune: %w[n dry-run].freeze
|
|
248
|
+
}.freeze,
|
|
236
249
|
reset: %w[N pathspec-file-nul q|quiet pathspec-from-file=p].freeze,
|
|
237
250
|
restore: %w[ignore-skip-worktree-bits ignore-unmerged m|merge ours p|patch pathspec-file-nul q|quiet S|staged
|
|
238
251
|
theirs W|worktree conflict=b pathspec-from-file=p s|source=b].freeze,
|
|
@@ -277,7 +290,7 @@ module Squared
|
|
|
277
290
|
checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
|
|
278
291
|
fetch: {
|
|
279
292
|
base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
|
|
280
|
-
pull: %w[all recurse-submodules show-forced-updates tags].freeze
|
|
293
|
+
pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
|
|
281
294
|
},
|
|
282
295
|
grep: %w[color exclude-standard recursive textconv].freeze,
|
|
283
296
|
log: {
|
|
@@ -310,7 +323,7 @@ module Squared
|
|
|
310
323
|
}.freeze,
|
|
311
324
|
rebase: {
|
|
312
325
|
send: %w[continue skip abort quit].freeze,
|
|
313
|
-
value: %w[false
|
|
326
|
+
value: %w[true false merges interactive].freeze
|
|
314
327
|
}.freeze,
|
|
315
328
|
reset: %w[soft mixed hard merge keep recurse-submodules no-recurse-submodules].freeze,
|
|
316
329
|
revbuild: %w[untracked-files ignore-submodules ignored].freeze
|
|
@@ -345,12 +358,13 @@ module Squared
|
|
|
345
358
|
'pull' => %i[origin remote all].freeze,
|
|
346
359
|
'rebase' => %i[branch onto send].freeze,
|
|
347
360
|
'refs' => %i[heads tags remote].freeze,
|
|
361
|
+
'remote' => %i[add select].freeze,
|
|
348
362
|
'reset' => %i[commit index patch mode undo].freeze,
|
|
349
363
|
'restore' => %i[source staged worktree].freeze,
|
|
350
364
|
'rev' => %i[commit branch build output].freeze,
|
|
351
365
|
'show' => %i[format oneline textconv].freeze,
|
|
352
366
|
'sparse-checkout' => %i[add reapply list clean disable].freeze,
|
|
353
|
-
'stash' => %i[push pop apply
|
|
367
|
+
'stash' => %i[push pop apply drop command].freeze,
|
|
354
368
|
'submodule' => %i[status update branch url sync].freeze,
|
|
355
369
|
'switch' => %i[branch create detach].freeze,
|
|
356
370
|
'tag' => %i[add sign delete list].freeze
|
|
@@ -481,31 +495,37 @@ module Squared
|
|
|
481
495
|
when :add, :sign
|
|
482
496
|
format_desc action, flag, 'name,message?,commit?,remote?'
|
|
483
497
|
task flag, [:name, :message, :commit, :remote] do |_, args|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
498
|
+
if (name = args.name)
|
|
499
|
+
message = args.message
|
|
500
|
+
commit = commithead args.commit
|
|
501
|
+
remote = args.remote
|
|
502
|
+
if !remote && commit && !commit.start_with?('@') && !git_grep('remote', commit).empty?
|
|
503
|
+
remote = commit
|
|
504
|
+
commit = nil
|
|
505
|
+
end
|
|
506
|
+
else
|
|
507
|
+
commit, name, message = choice_commit(reflog: false, series: true,
|
|
508
|
+
values: [['Enter tag name', true], 'Enter message'])
|
|
509
|
+
remote = choice_remote
|
|
510
|
+
end
|
|
496
511
|
ret = tag(flag, refs: [name], message: message, commit: commit, remote: remote)
|
|
497
512
|
success?(ret, !remote)
|
|
498
513
|
end
|
|
499
514
|
end
|
|
500
515
|
when 'stash'
|
|
501
|
-
format_desc(action, flag, 'opts*',
|
|
516
|
+
format_desc(action, flag, 'opts*', before: ('clear|list|all|staged|worktree' if flag == :command),
|
|
517
|
+
after: case flag
|
|
502
518
|
when :push then 'pathspec*,:'
|
|
503
|
-
when :
|
|
504
|
-
when :clear, :list, :all then nil
|
|
519
|
+
when :command then nil
|
|
505
520
|
else 'stash?|:'
|
|
506
521
|
end)
|
|
507
522
|
task flag do |_, args|
|
|
508
|
-
|
|
523
|
+
args = args.to_a
|
|
524
|
+
if flag == :command
|
|
525
|
+
param_guard(action, flag, args: args)
|
|
526
|
+
flag = args.shift.to_sym
|
|
527
|
+
end
|
|
528
|
+
stash flag, args
|
|
509
529
|
end
|
|
510
530
|
when 'log', 'diff', 'range-diff'
|
|
511
531
|
case flag
|
|
@@ -531,7 +551,7 @@ module Squared
|
|
|
531
551
|
end
|
|
532
552
|
args = args.drop(index.size)
|
|
533
553
|
end
|
|
534
|
-
|
|
554
|
+
log_(flag, args, index: index)
|
|
535
555
|
end
|
|
536
556
|
next
|
|
537
557
|
end
|
|
@@ -549,7 +569,7 @@ module Squared
|
|
|
549
569
|
opts.concat(refs.shellsplit) if refs
|
|
550
570
|
end
|
|
551
571
|
if action == 'log'
|
|
552
|
-
|
|
572
|
+
log_(flag, opts, range: range)
|
|
553
573
|
else
|
|
554
574
|
diff(flag, opts, range: range, from: action.to_sym)
|
|
555
575
|
end
|
|
@@ -601,10 +621,10 @@ module Squared
|
|
|
601
621
|
when 'i', 'E', 'F', 'P'
|
|
602
622
|
opts << last
|
|
603
623
|
else
|
|
604
|
-
if last =~ /^f(
|
|
624
|
+
if last =~ /^(f(-ormat)?)=(.+)$/
|
|
605
625
|
opts.shift
|
|
606
626
|
opts << "format=#{$1}"
|
|
607
|
-
elsif last =~ /^max(
|
|
627
|
+
elsif last =~ /^(max(-count)?)=(\d+)$/
|
|
608
628
|
opts << "max-count=#{$1}"
|
|
609
629
|
else
|
|
610
630
|
grep << last
|
|
@@ -613,7 +633,7 @@ module Squared
|
|
|
613
633
|
end
|
|
614
634
|
end
|
|
615
635
|
param_guard(action, flag, args: grep)
|
|
616
|
-
|
|
636
|
+
log_(flag, opts, grep: grep)
|
|
617
637
|
end
|
|
618
638
|
end
|
|
619
639
|
when 'checkout'
|
|
@@ -794,10 +814,10 @@ module Squared
|
|
|
794
814
|
end
|
|
795
815
|
success?(reset(flag, args, commit: commit))
|
|
796
816
|
end
|
|
797
|
-
when :index
|
|
798
|
-
format_desc
|
|
817
|
+
when :index
|
|
818
|
+
format_desc action, flag, 'opts*,pathspec*'
|
|
799
819
|
task flag do |_, args|
|
|
800
|
-
reset(flag,
|
|
820
|
+
reset(flag, args.to_a, refs: [])
|
|
801
821
|
end
|
|
802
822
|
when :mode
|
|
803
823
|
format_desc action, flag, 'mode,ref/:'
|
|
@@ -812,6 +832,11 @@ module Squared
|
|
|
812
832
|
ref = commithead args.ref
|
|
813
833
|
reset(flag, refs: args.extras, ref: !ref || ref == ':' ? choice_commit(reflog: false) : ref)
|
|
814
834
|
end
|
|
835
|
+
when :undo
|
|
836
|
+
format_desc action, flag
|
|
837
|
+
task flag do
|
|
838
|
+
reset flag
|
|
839
|
+
end
|
|
815
840
|
end
|
|
816
841
|
when 'show'
|
|
817
842
|
case flag
|
|
@@ -976,6 +1001,51 @@ module Squared
|
|
|
976
1001
|
task flag do |_, args|
|
|
977
1002
|
sparse_checkout flag, args.to_a
|
|
978
1003
|
end
|
|
1004
|
+
when 'remote'
|
|
1005
|
+
if flag == :add
|
|
1006
|
+
format_desc action, flag, 'name,url,opts*'
|
|
1007
|
+
task flag, [:name, :url] do |_, args|
|
|
1008
|
+
name = param_guard(action, flag, args: args, key: :name)
|
|
1009
|
+
url = param_guard(action, flag, args: args, key: :url)
|
|
1010
|
+
raise ArgumentError, message('invalid url', hint: url) unless url.match?(GIT_PROTO)
|
|
1011
|
+
|
|
1012
|
+
git(:remote, args.extras, extras: [name, url])
|
|
1013
|
+
end
|
|
1014
|
+
else
|
|
1015
|
+
format_desc action, flag, "#{OPT_GIT[:remote].keys.join('|')},opts*" if TASK_METADATA
|
|
1016
|
+
task flag, [:command] do |_, args|
|
|
1017
|
+
command = param_guard(action, flag, args: args, key: :command)
|
|
1018
|
+
cmd, opts = git_session('remote', opts: args.extras)
|
|
1019
|
+
param = case command
|
|
1020
|
+
when 'rename'
|
|
1021
|
+
'New name'
|
|
1022
|
+
when 'set-branches'
|
|
1023
|
+
'Branches'
|
|
1024
|
+
when 'set-head'
|
|
1025
|
+
'Branch' if opts.empty?
|
|
1026
|
+
when 'set-url'
|
|
1027
|
+
'URL'
|
|
1028
|
+
end
|
|
1029
|
+
remote, target = choice_remote(force: true, values: param ? [[param, true]] : [])
|
|
1030
|
+
cmd << '-v' if has_value!(opts, 'v', 'verbose') && command == 'show'
|
|
1031
|
+
cmd << command << remote
|
|
1032
|
+
op = OptionPartition.new(opts, OPT_GIT[:remote].fetch(command.to_sym, []), cmd,
|
|
1033
|
+
project: self, strict: strict?)
|
|
1034
|
+
case command
|
|
1035
|
+
when 'remove'
|
|
1036
|
+
exit 1 unless confirm_basic('Remove?', remote, 'N')
|
|
1037
|
+
when 'get-url', 'show', 'prune'
|
|
1038
|
+
status = false
|
|
1039
|
+
else
|
|
1040
|
+
raise ArgumentError, message('unrecognized command', command, hint: action) unless param
|
|
1041
|
+
raise ArgumentError, message('missing target', command, hint: action) unless target
|
|
1042
|
+
|
|
1043
|
+
op << target
|
|
1044
|
+
end
|
|
1045
|
+
op.clear
|
|
1046
|
+
success?(source(banner: !quiet?), status)
|
|
1047
|
+
end
|
|
1048
|
+
end
|
|
979
1049
|
when 'git'
|
|
980
1050
|
before = case flag
|
|
981
1051
|
when :blame
|
|
@@ -1048,15 +1118,16 @@ module Squared
|
|
|
1048
1118
|
op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, strict: strict?,
|
|
1049
1119
|
no: OPT_GIT[:no][:pull])
|
|
1050
1120
|
opts -= op.extras
|
|
1051
|
-
reg
|
|
1121
|
+
reg = matchmap op
|
|
1052
1122
|
session_done op.target
|
|
1053
1123
|
heads = []
|
|
1054
1124
|
cur = nil
|
|
1055
1125
|
foreachref('heads', format: '%(if)%(HEAD)%(then)* %(end)%(refname:short)').each do |line|
|
|
1056
1126
|
cur ||= line.delete_prefix!('* ')
|
|
1057
|
-
heads << line if matchany?(reg, line)
|
|
1127
|
+
heads << line if matchany?(reg, line)
|
|
1058
1128
|
end
|
|
1059
|
-
|
|
1129
|
+
raise message('head not found', hint: 'for-each-ref') unless cur
|
|
1130
|
+
|
|
1060
1131
|
opts << 'ff-only' if opts.empty? && option('ff-only', notequals: '0')
|
|
1061
1132
|
(heads.dup << cur).each_with_index do |branch, i|
|
|
1062
1133
|
next unless (i < heads.size && cur != branch) || i == heads.size
|
|
@@ -1201,11 +1272,7 @@ module Squared
|
|
|
1201
1272
|
first: (matchpathspec if flag == :push))
|
|
1202
1273
|
case flag
|
|
1203
1274
|
when :push
|
|
1204
|
-
if op.remove(':')
|
|
1205
|
-
op.readline('Enter message', option: 'message', quote: true)
|
|
1206
|
-
else
|
|
1207
|
-
append_message
|
|
1208
|
-
end
|
|
1275
|
+
op.readline('Enter message', option: 'message', quote: true) if op.remove(':')
|
|
1209
1276
|
append_pathspec op.extras
|
|
1210
1277
|
when :pop, :apply, :drop, :branch
|
|
1211
1278
|
if op.remove(':')
|
|
@@ -1223,22 +1290,21 @@ module Squared
|
|
|
1223
1290
|
else
|
|
1224
1291
|
op << out
|
|
1225
1292
|
end
|
|
1226
|
-
elsif !op.empty?
|
|
1227
|
-
op.add_first(prefix: ':')
|
|
1228
1293
|
elsif flag == :branch
|
|
1229
|
-
|
|
1294
|
+
op.add_first(prefix: ':', expect: 'no branch name')
|
|
1230
1295
|
end
|
|
1231
|
-
op.
|
|
1296
|
+
op.add_first
|
|
1297
|
+
.clear
|
|
1232
1298
|
when :clear
|
|
1233
1299
|
n = sub_style file.read.lines.size, theme[:inline]
|
|
1234
1300
|
s = sub_style name, theme[:active]
|
|
1235
1301
|
source(stdout: true) if confirm("Remove #{n} stash entries from #{s}?", 'N')
|
|
1236
1302
|
return
|
|
1237
|
-
|
|
1303
|
+
else
|
|
1238
1304
|
op.clear
|
|
1239
1305
|
out, banner, from = source(io: true)
|
|
1240
1306
|
print_item banner
|
|
1241
|
-
list_result(write_lines(out), 'objects',
|
|
1307
|
+
list_result(write_lines(out), 'objects', from: from)
|
|
1242
1308
|
return
|
|
1243
1309
|
end
|
|
1244
1310
|
else
|
|
@@ -1290,7 +1356,7 @@ module Squared
|
|
|
1290
1356
|
end
|
|
1291
1357
|
out, banner, from = source(io: true)
|
|
1292
1358
|
ret = write_lines(out, banner: banner, sub: sub)
|
|
1293
|
-
list_result(ret, 'files', action: 'modified',
|
|
1359
|
+
list_result(ret, 'files', action: 'modified', from: from)
|
|
1294
1360
|
end
|
|
1295
1361
|
|
|
1296
1362
|
def revbuild(flag = nil, opts = [], **kwargs)
|
|
@@ -1325,6 +1391,7 @@ module Squared
|
|
|
1325
1391
|
|
|
1326
1392
|
sync = kwargs.fetch(:sync) { invoked_sync?('revbuild', flag) }
|
|
1327
1393
|
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? kw.call : @revbuild || { pass: true }
|
|
1394
|
+
from = symjoin 'git', 'revbuild'
|
|
1328
1395
|
case flag
|
|
1329
1396
|
when :build
|
|
1330
1397
|
op = OptionPartition.new(opts, VAL_GIT[:revbuild].map { |key| "#{key}=b?" }, project: self, strict: strict?)
|
|
@@ -1337,7 +1404,7 @@ module Squared
|
|
|
1337
1404
|
.compact
|
|
1338
1405
|
OptionPartition.uniq!(args)
|
|
1339
1406
|
end
|
|
1340
|
-
run_p(*Array(kwargs[:before]), sync: sync, from:
|
|
1407
|
+
run_p(*Array(kwargs[:before]), sync: sync, from: symjoin(from, 'before')) if kwargs[:before]
|
|
1341
1408
|
force = if (force = env('REVBUILD_FORCE', strict: true))
|
|
1342
1409
|
force != '0' && force != 'false'
|
|
1343
1410
|
elsif (force = ENV['GIT_FORCE'] || ENV['REVBUILD_FORCE'])
|
|
@@ -1352,7 +1419,7 @@ module Squared
|
|
|
1352
1419
|
end
|
|
1353
1420
|
end
|
|
1354
1421
|
start = time_epoch
|
|
1355
|
-
ret = build(*@output, sync: sync, from:
|
|
1422
|
+
ret = build(*@output, sync: sync, from: from)
|
|
1356
1423
|
rescue => e
|
|
1357
1424
|
print_error(e, pass: true)
|
|
1358
1425
|
else
|
|
@@ -1360,7 +1427,7 @@ module Squared
|
|
|
1360
1427
|
print_status('revbuild', subject: name, start: start, loglevel: Logger::WARN, from: :failed)
|
|
1361
1428
|
workspace.rev_timeutc name, 'build'
|
|
1362
1429
|
else
|
|
1363
|
-
run_p(*Array(kwargs[:after]), sync: sync, from:
|
|
1430
|
+
run_p(*Array(kwargs[:after]), sync: sync, from: symjoin(from, 'after')) if kwargs[:after] && ret != false
|
|
1364
1431
|
print_status('revbuild', subject: name, start: start)
|
|
1365
1432
|
workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
|
|
1366
1433
|
sync: sync, utc: 'build')
|
|
@@ -1458,7 +1525,7 @@ module Squared
|
|
|
1458
1525
|
out, banner, from = source(io: true)
|
|
1459
1526
|
print_item banner
|
|
1460
1527
|
ret = write_lines(out, grep: op.extras)
|
|
1461
|
-
list_result(ret, 'tags', grep: op.extras,
|
|
1528
|
+
list_result(ret, 'tags', grep: op.extras, from: from)
|
|
1462
1529
|
return
|
|
1463
1530
|
end
|
|
1464
1531
|
if (ret = source) && (remote ||= option('remote'))
|
|
@@ -1467,11 +1534,11 @@ module Squared
|
|
|
1467
1534
|
ret
|
|
1468
1535
|
end
|
|
1469
1536
|
|
|
1470
|
-
def
|
|
1537
|
+
def log_(flag, opts = [], range: [], index: [], grep: [])
|
|
1471
1538
|
cmd, opts = git_session('log', opts: opts)
|
|
1472
|
-
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
|
|
1473
|
-
|
|
1474
|
-
|
|
1539
|
+
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self, strict: strict?,
|
|
1540
|
+
no: collect_hash(OPT_GIT[:no][:log]),
|
|
1541
|
+
first: matchpathspec)
|
|
1475
1542
|
case flag
|
|
1476
1543
|
when :between, :contain
|
|
1477
1544
|
op.add_quote(range.join(flag == :between ? '..' : '...'))
|
|
@@ -1484,7 +1551,6 @@ module Squared
|
|
|
1484
1551
|
append_pathspec op.extras
|
|
1485
1552
|
source(exception: false)
|
|
1486
1553
|
end
|
|
1487
|
-
alias log_ log!
|
|
1488
1554
|
|
|
1489
1555
|
def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [], from: :diff)
|
|
1490
1556
|
cmd, opts = git_session(from, opts: opts)
|
|
@@ -1517,7 +1583,8 @@ module Squared
|
|
|
1517
1583
|
op.add_quote(branch) if branch
|
|
1518
1584
|
if !index.empty?
|
|
1519
1585
|
if op.arg?('cached')
|
|
1520
|
-
|
|
1586
|
+
raise message('single commit only', index.join(', '), hint: flag) unless index.size == 1
|
|
1587
|
+
|
|
1521
1588
|
op << index.first
|
|
1522
1589
|
else
|
|
1523
1590
|
op.merge(index)
|
|
@@ -1528,7 +1595,7 @@ module Squared
|
|
|
1528
1595
|
end
|
|
1529
1596
|
if (n = op.index('>'))
|
|
1530
1597
|
patch = op.slice!(n, 2)[1]
|
|
1531
|
-
elsif !op.
|
|
1598
|
+
elsif !op.exist?(op.last)
|
|
1532
1599
|
patch ||= op.pop
|
|
1533
1600
|
end
|
|
1534
1601
|
append_pathspec op.extras
|
|
@@ -1580,9 +1647,9 @@ module Squared
|
|
|
1580
1647
|
next if line.empty?
|
|
1581
1648
|
|
|
1582
1649
|
branch, origin, hint = line.split('...')
|
|
1583
|
-
if hint && !hint.match?(/^\[(\D+0,\D+0)\]$/)
|
|
1584
|
-
|
|
1585
|
-
|
|
1650
|
+
raise message('work tree is not usable', hint: hint[1..-2]) if hint && !hint.match?(/^\[(\D+0,\D+0)\]$/)
|
|
1651
|
+
|
|
1652
|
+
if (!origin || origin.empty?) && !dryrun?
|
|
1586
1653
|
return nil if pass
|
|
1587
1654
|
|
|
1588
1655
|
unless (origin = option('upstream', prefix: 'git', ignore: false))
|
|
@@ -1685,7 +1752,8 @@ module Squared
|
|
|
1685
1752
|
cmd << shell_quote(target)
|
|
1686
1753
|
cmd << shell_quote(ref) if ref
|
|
1687
1754
|
when :track
|
|
1688
|
-
|
|
1755
|
+
raise message('invalid upstream', hint: ref) unless ref.include?('/')
|
|
1756
|
+
|
|
1689
1757
|
if ref.delete_prefix!('^')
|
|
1690
1758
|
cmd << '--unset-upstream' << shell_quote(ref)
|
|
1691
1759
|
remote = false
|
|
@@ -1726,7 +1794,7 @@ module Squared
|
|
|
1726
1794
|
opt_style(color(:green), /^(\*\s+)(\S+)(.*)$/, 2),
|
|
1727
1795
|
opt_style(color(:red), %r{^(\s*)(remotes/\S+)(.*)$}, 2)
|
|
1728
1796
|
])
|
|
1729
|
-
list_result(ret, 'branches',
|
|
1797
|
+
list_result(ret, 'branches', from: from)
|
|
1730
1798
|
return
|
|
1731
1799
|
else
|
|
1732
1800
|
if (head = git_spawn('rev-parse --abbrev-ref HEAD').chomp).empty?
|
|
@@ -1735,7 +1803,7 @@ module Squared
|
|
|
1735
1803
|
git_spawn 'fetch --all --prune --quiet' if option('sync')
|
|
1736
1804
|
cmd << '-vv --no-abbrev --list'
|
|
1737
1805
|
out, banner, from = source(io: true)
|
|
1738
|
-
first =
|
|
1806
|
+
first = workspace.size > 1
|
|
1739
1807
|
grep = first ? [/^\*\s+#{Regexp.escape(head)}\s/] : []
|
|
1740
1808
|
ret = write_lines(out, grep: grep, banner: banner, first: first) do |line, index|
|
|
1741
1809
|
next line if stdin?
|
|
@@ -1743,15 +1811,15 @@ module Squared
|
|
|
1743
1811
|
data = line.sub(/^\*?\s+/, '').split(/\s+/, 3)
|
|
1744
1812
|
a = sub_style(data[0], theme[:inline], styles: (:underline if !first && line.start_with?('*')))
|
|
1745
1813
|
b = commitstyle data[1]
|
|
1746
|
-
|
|
1747
|
-
if (r1 =
|
|
1814
|
+
md = /\A(?:\[((?~\]\s))\]\s)?(.+)\z/m.match(data[2])
|
|
1815
|
+
if (r1 = md[1]) && r1 =~ /^(.+):(?: ([a-z]+) (\d+),)? ([a-z]+) (\d+)$/
|
|
1748
1816
|
write = ->(s1, s2) { "#{s1.capitalize.rjust(7)}: #{sub_style(s2, theme[:warn])}" }
|
|
1749
1817
|
r1 = $1
|
|
1750
1818
|
r2 = $2 && write.call($2, $3)
|
|
1751
1819
|
r3 = write.call($4, $5)
|
|
1752
1820
|
end
|
|
1753
1821
|
r1 = nil if r1 == "origin/#{data[0]}"
|
|
1754
|
-
["#{"\n" unless index == 0} Branch: #{a.subhint(r1)}", r2, r3, " Commit: #{b}", "Message: #{
|
|
1822
|
+
["#{"\n" unless index == 0} Branch: #{a.subhint(r1)}", r2, r3, " Commit: #{b}", "Message: #{md[2]}"]
|
|
1755
1823
|
.compact
|
|
1756
1824
|
.join("\n")
|
|
1757
1825
|
end
|
|
@@ -1808,7 +1876,9 @@ module Squared
|
|
|
1808
1876
|
|
|
1809
1877
|
def restore(flag, opts = [], commit: nil, files: nil)
|
|
1810
1878
|
cmd, opts = git_session('restore', shell_option(flag, commit, escape: false, force: false), opts: opts)
|
|
1811
|
-
op = OptionPartition.new(opts,
|
|
1879
|
+
op = OptionPartition.new(opts,
|
|
1880
|
+
OPT_GIT[:restore] + OPT_GIT[:log][:diff_context],
|
|
1881
|
+
cmd,
|
|
1812
1882
|
project: self, strict: strict?, no: OPT_GIT[:no][:restore], first: matchpathspec)
|
|
1813
1883
|
append_pathspec(op.extras + (files || []), pass: false)
|
|
1814
1884
|
source(sync: false, stderr: true)
|
|
@@ -1821,7 +1891,7 @@ module Squared
|
|
|
1821
1891
|
cmd << '--textconv'
|
|
1822
1892
|
append_value(files.flat_map { |val| Dir[val] }
|
|
1823
1893
|
.select { |val| projectpath?(val) }
|
|
1824
|
-
.map { |val| "HEAD:#{val}" })
|
|
1894
|
+
.map { |val| shell_quote("HEAD:#{val}") })
|
|
1825
1895
|
source(banner: false)
|
|
1826
1896
|
return
|
|
1827
1897
|
when :oneline
|
|
@@ -1835,11 +1905,12 @@ module Squared
|
|
|
1835
1905
|
else
|
|
1836
1906
|
opts << format if format
|
|
1837
1907
|
end
|
|
1838
|
-
list = OPT_GIT[:show] + OPT_GIT[:diff][:show] +
|
|
1908
|
+
list = OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context]
|
|
1839
1909
|
op = OptionPartition.new(opts, list, cmd,
|
|
1840
|
-
project: self,
|
|
1910
|
+
project: self,
|
|
1911
|
+
strict: strict?,
|
|
1841
1912
|
no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
|
|
1842
|
-
op.append
|
|
1913
|
+
op.append(delim: true)
|
|
1843
1914
|
source(exception: false, banner: flag != :oneline)
|
|
1844
1915
|
end
|
|
1845
1916
|
|
|
@@ -1862,8 +1933,8 @@ module Squared
|
|
|
1862
1933
|
cmd << '--sq-quote'
|
|
1863
1934
|
args = true
|
|
1864
1935
|
end
|
|
1865
|
-
OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd,
|
|
1866
|
-
|
|
1936
|
+
OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd,
|
|
1937
|
+
project: self, strict: strict?, no: OPT_GIT[:no][:rev_parse], args: args)
|
|
1867
1938
|
.append(escape: args)
|
|
1868
1939
|
end
|
|
1869
1940
|
source(banner: verbose?)
|
|
@@ -1890,8 +1961,8 @@ module Squared
|
|
|
1890
1961
|
op.add_quote(remote) if remote
|
|
1891
1962
|
out, banner, from = source(io: true)
|
|
1892
1963
|
print_item banner
|
|
1893
|
-
ret = write_lines(out, grep: op.extras)
|
|
1894
|
-
list_result(ret, flag.to_s, grep: op.extras,
|
|
1964
|
+
ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
|
|
1965
|
+
list_result(ret, flag.to_s, grep: op.extras, from: from)
|
|
1895
1966
|
end
|
|
1896
1967
|
|
|
1897
1968
|
def ls_files(flag, opts = [])
|
|
@@ -1901,12 +1972,12 @@ module Squared
|
|
|
1901
1972
|
out, banner, from = source(io: true)
|
|
1902
1973
|
print_item banner
|
|
1903
1974
|
ret = write_lines(out, grep: op.extras)
|
|
1904
|
-
list_result(ret, 'files', grep: op.extras,
|
|
1975
|
+
list_result(ret, 'files', grep: op.extras, from: from)
|
|
1905
1976
|
end
|
|
1906
1977
|
|
|
1907
|
-
def git(flag, opts = [])
|
|
1978
|
+
def git(flag, opts = [], extras: [])
|
|
1908
1979
|
cmd, opts = git_session(flag, opts: opts)
|
|
1909
|
-
list = OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, [])
|
|
1980
|
+
list = OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, []).yield_self { |a| a.is_a?(Array) ? a : [] }
|
|
1910
1981
|
case flag
|
|
1911
1982
|
when :add
|
|
1912
1983
|
list.concat(OPT_GIT[:log][:diff_context])
|
|
@@ -1915,7 +1986,8 @@ module Squared
|
|
|
1915
1986
|
when :'sparse-checkout'
|
|
1916
1987
|
cmd << 'set'
|
|
1917
1988
|
end
|
|
1918
|
-
op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?,
|
|
1989
|
+
op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?,
|
|
1990
|
+
no: OPT_GIT[:no][flag], single: /\A\d+\z/,
|
|
1919
1991
|
first: case flag
|
|
1920
1992
|
when :blame, :revert, :'sparse-checkout' then nil
|
|
1921
1993
|
else matchpathspec
|
|
@@ -1954,6 +2026,12 @@ module Squared
|
|
|
1954
2026
|
end
|
|
1955
2027
|
end
|
|
1956
2028
|
return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
|
|
2029
|
+
when :remote
|
|
2030
|
+
op.unshift(*extras)
|
|
2031
|
+
op.adjoin('add')
|
|
2032
|
+
.add_first(expect: 'missing name')
|
|
2033
|
+
.add_first(expect: 'missing URL', quote: true)
|
|
2034
|
+
.clear
|
|
1957
2035
|
when :mv
|
|
1958
2036
|
refs = projectmap op.extras
|
|
1959
2037
|
raise 'no source/destination' unless refs.size > 1
|
|
@@ -1982,7 +2060,7 @@ module Squared
|
|
|
1982
2060
|
when :revert, :mv, :rm
|
|
1983
2061
|
source(sync: false, stderr: true)
|
|
1984
2062
|
else
|
|
1985
|
-
success?(source,
|
|
2063
|
+
success?(source, %i[remote sparse-checkout].include?(flag) || (flag == :add && !op.arg?('verbose')))
|
|
1986
2064
|
end
|
|
1987
2065
|
end
|
|
1988
2066
|
|
|
@@ -1994,7 +2072,7 @@ module Squared
|
|
|
1994
2072
|
build? && !!workspace.revfile
|
|
1995
2073
|
end
|
|
1996
2074
|
|
|
1997
|
-
def enabled?(
|
|
2075
|
+
def enabled?(**kwargs)
|
|
1998
2076
|
super || (kwargs[:base] == false && !!clone?)
|
|
1999
2077
|
end
|
|
2000
2078
|
|
|
@@ -2069,13 +2147,13 @@ module Squared
|
|
|
2069
2147
|
end
|
|
2070
2148
|
end
|
|
2071
2149
|
|
|
2072
|
-
def list_result(size, type, action: 'found', grep: [],
|
|
2150
|
+
def list_result(size, type, action: 'found', grep: [], from: nil)
|
|
2073
2151
|
if size == 0
|
|
2074
2152
|
puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
|
|
2075
|
-
elsif stdout?
|
|
2153
|
+
elsif stdout?
|
|
2076
2154
|
styles = theme.fetch(:banner, []).reject { |val| val.to_s.end_with?('!') }
|
|
2077
2155
|
styles << :bold if styles.size <= 1
|
|
2078
|
-
puts print_footer("#{size} #{size == 1 ? type.sub(/(
|
|
2156
|
+
puts print_footer("#{size} #{size == 1 ? type.sub(/((?<!l)e)?s\z/, '') : type}",
|
|
2079
2157
|
sub: opt_style(styles, /^(\d+)(.+)$/))
|
|
2080
2158
|
end
|
|
2081
2159
|
on :last, from
|
|
@@ -2104,7 +2182,7 @@ module Squared
|
|
|
2104
2182
|
ret = choice_index('Choose a commit', git_spawn(cmd, stdout: false), column: /^(\S+)/, force: force, **kwargs)
|
|
2105
2183
|
case ret
|
|
2106
2184
|
when Array
|
|
2107
|
-
ret.map
|
|
2185
|
+
ret.map(&:stripstyle)
|
|
2108
2186
|
when String
|
|
2109
2187
|
ret.stripstyle
|
|
2110
2188
|
else
|
|
@@ -2141,8 +2219,8 @@ module Squared
|
|
|
2141
2219
|
append_submodules(target: target, from: from)
|
|
2142
2220
|
return if !remote && opts.empty?
|
|
2143
2221
|
|
|
2144
|
-
op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target,
|
|
2145
|
-
|
|
2222
|
+
op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, strict: strict?,
|
|
2223
|
+
no: no)
|
|
2146
2224
|
refspec = op.each_with_object([]) do |opt, out|
|
|
2147
2225
|
if opt =~ op.values
|
|
2148
2226
|
case $1
|
|
@@ -2189,9 +2267,9 @@ module Squared
|
|
|
2189
2267
|
end
|
|
2190
2268
|
end
|
|
2191
2269
|
|
|
2192
|
-
def append_pathspec(files = [], target: @session, expect: false,
|
|
2270
|
+
def append_pathspec(files = [], target: @session, expect: false, **kwargs)
|
|
2193
2271
|
if session_arg?('pathspec-from-file', target: target)
|
|
2194
|
-
OptionPartition.clear(target, files,
|
|
2272
|
+
OptionPartition.clear(target, files, styles: theme[:inline])
|
|
2195
2273
|
true
|
|
2196
2274
|
else
|
|
2197
2275
|
option('pathspec', target: target) { |val| files = split_escape(val) } if files.empty?
|
|
@@ -2282,7 +2360,21 @@ module Squared
|
|
|
2282
2360
|
stdout: stdout, banner: banner, **kwargs)
|
|
2283
2361
|
end
|
|
2284
2362
|
|
|
2285
|
-
def
|
|
2363
|
+
def git_grep(cmd, *grep, equals: true, **kwargs)
|
|
2364
|
+
ret = []
|
|
2365
|
+
git_spawn(cmd, **kwargs).lines(chomp: true).each do |line|
|
|
2366
|
+
if grep.any? { |val| val.is_a?(Regexp) ? val.match?(line) : equals ? line == val : line.include?(val) }
|
|
2367
|
+
ret << line
|
|
2368
|
+
end
|
|
2369
|
+
end
|
|
2370
|
+
ret
|
|
2371
|
+
end
|
|
2372
|
+
|
|
2373
|
+
def dryrun?(target: @session, prefix: target&.first, **)
|
|
2374
|
+
Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
|
|
2375
|
+
end
|
|
2376
|
+
|
|
2377
|
+
def quiet?(target: @session, **)
|
|
2286
2378
|
return silent? unless target
|
|
2287
2379
|
|
|
2288
2380
|
silent? || target.include?('--quiet') || (target.include?('-q') && target.first.stripext == 'git')
|
|
@@ -2294,7 +2386,8 @@ module Squared
|
|
|
2294
2386
|
|
|
2295
2387
|
def repotrack(origin, branch, quote: true)
|
|
2296
2388
|
n = origin&.index('/')
|
|
2297
|
-
|
|
2389
|
+
raise message("missing #{origin ? 'branch' : 'remote'} name", hint: origin) unless n && branch
|
|
2390
|
+
|
|
2298
2391
|
branch = "#{branch}:#{origin[n.succ..-1]}" unless origin.end_with?("/#{branch}")
|
|
2299
2392
|
ret = [origin[0..n.pred], branch]
|
|
2300
2393
|
ret.quote! if quote
|