squared 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -143,7 +143,6 @@ module Squared
143
143
  end
144
144
  File.write(@revfile, JSON.pretty_generate(@revdoc))
145
145
  rescue => e
146
- log&.debug e
147
146
  warn log_warn(e, pass: true) if warning
148
147
  ensure
149
148
  @revlock = false
@@ -165,6 +164,16 @@ module Squared
165
164
  sort=q t|track=b].freeze,
166
165
  checkout: %w[l d|detach f|force ignore-other-worktrees ignore-skip-worktree-bits m|merge p|patch
167
166
  pathspec-file-nul q|quiet ours theirs conflict=b orphan=b pathspec-from-file=p t|track=b].freeze,
167
+ clone: %w[also-filter-submodules bare dissociate l|local mirror no-hardlinks n|no-checkout no-tags o|origin=b
168
+ progress q|quiet s|shared sparse v|verbose b|branch=b bundle-uri=q c|config=q depth=i filter=q
169
+ j|jobs=i reference=q reference-if-able=q o|origin=b recurse-submodules=p? ref-format=b
170
+ separate-git-dir=p server-option=q shallow-exclude=b shallow-since=v template=p
171
+ u|upload-pack=q].freeze,
172
+ commit: %w[e n s S=bm? u=bm? a|all allow-empty allow-empty-message amend branch dry-run i|include long
173
+ no-post-rewrite o|only pathspec-file-nul z|null p|patch porcelain q|quiet reset-author short
174
+ v|verbose trailer=q author=q cleanup=b date=q fixup=b f|file=p gpg-sign=b c|reedit-message=b
175
+ C|reuse-message=b m|message=q pathspec-from-file=p squash=b t|template=p
176
+ untracked-files=b?].freeze,
168
177
  diff: {
169
178
  base: %w[0 1|base 2|ours 3|theirs cached merge-base].freeze,
170
179
  show: %w[s exit-code histogram].freeze
@@ -172,9 +181,10 @@ module Squared
172
181
  fetch: {
173
182
  base: %w[multiple porcelain progress P|prune-tags refetch stdin u|update-head-ok
174
183
  recurse-submodules-default=b?].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
184
+ pull: %w[n t 4|ipv4 6|ipv6 a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
185
+ set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
186
+ recurse-submodules=v refmap=q o|server-option=q shallow-exclude=b shallow-since=v
187
+ upload-pack=q].freeze
178
188
  }.freeze,
179
189
  git: {
180
190
  add: %w[N|intent-to-add].freeze,
@@ -230,6 +240,9 @@ module Squared
230
240
  gpg-sign=b? into-name=b log=i s|strategy=b X|strategy-option=b].freeze,
231
241
  pull: %w[e n S=bm? allow-unrelated-histories compact-summary ff-only cleanup=b gpg-sign=b? log=i r|rebase=v?
232
242
  s|strategy=b X|strategy-option=b].freeze,
243
+ push: %w[4|ipv4 6|ipv6 d|delete f|force n|dry-run follow-tags mirror no-recurse-submodules porcelain progress
244
+ prune q|quiet u|set-upstream tags v|verbose exec=q force-with-lease=b o|push-option=q receive-pack=q
245
+ recurse-submodules=b repo=q signed=b].freeze,
233
246
  range_diff: %w[left-only no-dual-color no-notes remerge-diff right-only creation-factor=i diff-merges=b
234
247
  notes=q?].freeze,
235
248
  rebase: %w[n C=im S=bm? allow-empty-message apply committer-date-is-author-date edit-todo empty=b
@@ -288,9 +301,11 @@ module Squared
288
301
  blame: %w[progress].freeze,
289
302
  branch: %w[color color-moved column track].freeze,
290
303
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
304
+ clone: %w[reject-shallow remote-submodules single-branch shallow-submodules].freeze,
305
+ commit: %w[edit gpg-sign signoff status verify].freeze,
291
306
  fetch: {
292
307
  base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
293
- pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
308
+ pull: %w[all recurse-submodules show-forced-updates tags].freeze
294
309
  },
295
310
  grep: %w[color exclude-standard recursive textconv].freeze,
296
311
  log: {
@@ -301,6 +316,7 @@ module Squared
301
316
  merge: %w[autostash edit ff gpg-sign log overwrite-ignore progress rerere-autoupdate signoff squash stat
302
317
  verify verify-signatures].freeze,
303
318
  pull: %w[autostash commit edit gpg-sign ff log rebase signoff squash stat verify verify-signatures].freeze,
319
+ push: %w[atomic force-if-includes force-with-lease signed thin verify].freeze,
304
320
  rebase: %w[autosquash autostash fork-point gpg-sign keep-empty reapply-cherry-picks rebase-merges
305
321
  rerere-autoupdate reschedule-failed-exec stat update-refs verify].freeze,
306
322
  reset: %w[refresh].freeze,
@@ -323,7 +339,7 @@ module Squared
323
339
  }.freeze,
324
340
  rebase: {
325
341
  send: %w[continue skip abort quit].freeze,
326
- value: %w[true false merges interactive].freeze
342
+ value: %w[false true merges interactive].freeze
327
343
  }.freeze,
328
344
  reset: %w[soft mixed hard merge keep recurse-submodules no-recurse-submodules].freeze,
329
345
  revbuild: %w[untracked-files ignore-submodules ignored].freeze
@@ -347,7 +363,8 @@ module Squared
347
363
  subtasks({
348
364
  'branch' => %i[create track delete move copy list all current].freeze,
349
365
  'checkout' => %i[commit branch track detach path].freeze,
350
- 'commit' => %i[add all amend amend-orig fixup].freeze,
366
+ 'commit' => %i[head add all amend amend-orig fixup].freeze,
367
+ 'clone' => %i[branch tag].freeze,
351
368
  'diff' => %i[head branch files view between contain].freeze,
352
369
  'range-diff' => %i[view between contain].freeze,
353
370
  'fetch' => %i[origin remote all].freeze,
@@ -356,6 +373,7 @@ module Squared
356
373
  'log' => %i[grep view between contain].freeze,
357
374
  'merge' => %i[commit no-commit send].freeze,
358
375
  'pull' => %i[origin remote all].freeze,
376
+ 'push' => %i[origin remote commit all tags].freeze,
359
377
  'rebase' => %i[branch onto send].freeze,
360
378
  'refs' => %i[heads tags remote].freeze,
361
379
  'remote' => %i[add select].freeze,
@@ -395,7 +413,7 @@ module Squared
395
413
  if flag == :remote
396
414
  format_desc action, flag, 'remote?,opts*'
397
415
  task flag, [:remote] do |_, args|
398
- args = if (remote = args.remote)
416
+ args = if (remote = args.remote) && !git_grep('remote', remote).empty?
399
417
  args.extras
400
418
  else
401
419
  remote = choice_remote
@@ -409,6 +427,44 @@ module Squared
409
427
  __send__ action, flag, args.to_a
410
428
  end
411
429
  end
430
+ when 'push'
431
+ case flag
432
+ when :origin, :remote
433
+ format_desc(action, flag, 'branch/::,opts*', before: ('origin/:' if flag == :remote))
434
+ task flag, (flag == :remote ? %i[origin branch] : %i[branch]) do |_, args|
435
+ if flag == :remote
436
+ origin = param_guard(action, flag, args: args, key: :origin)
437
+ origin = choice_remote(force: true) if origin == ':' || !git_grep('remote', origin).empty?
438
+ else
439
+ origin = remotetrack
440
+ end
441
+ branch = param_guard(action, flag, args: args, key: :branch)
442
+ if branch == '::'
443
+ branch = choice_refs('Choose a branch', 'heads', series: true, accept: 'Push?')
444
+ end
445
+ push(flag, args.extras, origin: origin, branch: branch)
446
+ end
447
+ when :commit
448
+ format_desc action, flag, 'commit?|:,opts*'
449
+ task flag, [:commit] do |_, args|
450
+ ref = args.commit
451
+ if !ref || ref == ':'
452
+ ref = choice_commit('@{u}..', empty: log_message('No pending commits', hint: remotetrack))
453
+ end
454
+ push(flag, args.extras, ref: ref)
455
+ end
456
+ else
457
+ format_desc(action, flag, 'origin?,opts*', after: ('refs*' unless flag == :all))
458
+ task flag do |_, args|
459
+ args = args.to_a
460
+ if (origin = args.first) && !git_grep('remote', origin).empty?
461
+ args.shift
462
+ else
463
+ origin = nil
464
+ end
465
+ push(flag, args, origin: origin)
466
+ end
467
+ end
412
468
  when 'submodule'
413
469
  break unless @submodule
414
470
 
@@ -435,10 +491,14 @@ module Squared
435
491
  end
436
492
  when 'commit'
437
493
  case flag
438
- when :all
439
- format_desc action, flag, 'message?'
494
+ when :head, :all
495
+ format_desc(action, flag, 'message?|:', after: ('opts*,pathspec*' if flag == :head))
440
496
  task flag, [:message] do |_, args|
441
- commit(flag, message: args.message)
497
+ message = args.message
498
+ if message == ':' || (!message && flag == :head)
499
+ message = readline('Enter message', force: true)
500
+ end
501
+ commit(flag, flag == :head ? args.extras : [], message: message)
442
502
  end
443
503
  else
444
504
  format_desc(action, flag, 'pathspec+', before: ('opts*' if flag == :add))
@@ -534,7 +594,7 @@ module Squared
534
594
  format_desc action, flag, '(^)commit*|:,opts*,pathspec*'
535
595
  task flag do |_, args|
536
596
  args = args.to_a
537
- if args.first == ':'
597
+ if args.empty? || args.first == ':'
538
598
  args.shift
539
599
  index = choice_commit(multiple: true)
540
600
  else
@@ -578,7 +638,7 @@ module Squared
578
638
  format_desc action, flag, 'commit*|:,opts*,pathspec*'
579
639
  task flag do |_, args|
580
640
  args = args.to_a
581
- if args.first == ':'
641
+ if args.empty? || args.first == ':'
582
642
  args.shift
583
643
  index = choice_commit(multiple: true)
584
644
  else
@@ -672,13 +732,14 @@ module Squared
672
732
  else
673
733
  origin, branch = choice_refs('Choose a remote', 'remotes', values: 'Enter branch name')
674
734
  end
675
- checkout(flag, branch: branch, origin: origin)
735
+ checkout(flag, origin: origin, branch: branch)
676
736
  end
677
737
  when :commit
678
- format_desc action, flag, 'ref,opts*'
738
+ format_desc action, flag, 'commit?|:,opts*'
679
739
  task flag, [:commit] do |_, args|
680
740
  commit = commithead args.commit
681
741
  args = if commit
742
+ commit = choice_commit if commit == ':'
682
743
  args.extras
683
744
  else
684
745
  commit, opts = choice_commit(values: 'Options')
@@ -687,7 +748,7 @@ module Squared
687
748
  checkout(flag, args, commit: commit)
688
749
  end
689
750
  when :detach
690
- format_desc action, flag, 'ref?'
751
+ format_desc action, flag, 'commit?'
691
752
  task flag, [:commit] do |_, args|
692
753
  commit = commithead args.commit
693
754
  unless commit
@@ -705,7 +766,7 @@ module Squared
705
766
  when 'branch'
706
767
  case flag
707
768
  when :create
708
- format_desc action, flag, 'name,ref/:'
769
+ format_desc action, flag, 'name,ref?|:'
709
770
  task flag, [:name, :ref] do |_, args|
710
771
  target = param_guard(action, flag, args: args, key: :name)
711
772
  ref = commithead args.ref
@@ -767,10 +828,19 @@ module Squared
767
828
  branch flag
768
829
  end
769
830
  end
831
+ when 'clone'
832
+ format_desc(action, flag, flag == :tag ? 'dir,tag/:' : 'dir,branch/:', after: 'opts*')
833
+ task flag, [:dir, :ref] do |_, args|
834
+ dir = emptypath(param_guard(action, flag, args: args, key: :dir), create: false)
835
+ unless (ref = args.ref) && ref != ':'
836
+ ref = flag == :tag ? choice_refs('Choose a tag', 'tags') : choice_refs('Choose a branch')
837
+ end
838
+ clone(flag, args.extras, dir: dir, ref: ref)
839
+ end
770
840
  when 'switch'
771
841
  case flag
772
842
  when :create
773
- format_desc action, flag, '(^)name,ref/:'
843
+ format_desc action, flag, '(^)name,commit?|:'
774
844
  task flag, [:name, :commit] do |_, args|
775
845
  branch = param_guard(action, flag, args: args, key: :name)
776
846
  commit = commithead args.commit
@@ -778,9 +848,10 @@ module Squared
778
848
  switch(flag, branch: branch, commit: commit, track: track)
779
849
  end
780
850
  when :detach
781
- format_desc action, flag, 'ref?'
851
+ format_desc action, flag, 'commit?|:'
782
852
  task flag, [:commit] do |_, args|
783
- commit = commithead(args.commit) || choice_commit(force: false)
853
+ commit = commithead args.commit
854
+ commit = choice_commit(force: false) if commit == ':'
784
855
  switch(flag, commit: commit)
785
856
  end
786
857
  when :branch
@@ -798,7 +869,7 @@ module Squared
798
869
  when 'reset'
799
870
  case flag
800
871
  when :commit
801
- format_desc action, flag, 'ref/:,opts*'
872
+ format_desc action, flag, 'commit?|:,opts*'
802
873
  task flag, [:commit] do |_, args|
803
874
  commit = commithead args.commit
804
875
  args = if commit && commit != ':'
@@ -860,7 +931,7 @@ module Squared
860
931
  when 'rebase', 'merge'
861
932
  case flag
862
933
  when :branch
863
- format_desc action, flag, 'upstream,branch?,opts*'
934
+ format_desc action, flag, 'upstream?,opts*'
864
935
  task flag, [:upstream] do |_, args|
865
936
  args = if (upstream = args.upstream)
866
937
  args.extras
@@ -871,11 +942,12 @@ module Squared
871
942
  rebase(flag, args, upstream: upstream)
872
943
  end
873
944
  when :onto
874
- format_desc action, flag, 'ref,upstream,branch?'
945
+ format_desc action, flag, 'commit|:,upstream,branch?'
875
946
  task flag, [:commit, :upstream, :branch] do |_, args|
876
947
  commit = commithead args.commit
877
948
  args = if commit
878
949
  upstream = param_guard(action, flag, args: args, key: :upstream)
950
+ commit = choice_commit if commit == ':'
879
951
  branch = args.branch
880
952
  []
881
953
  else
@@ -949,9 +1021,16 @@ module Squared
949
1021
  end
950
1022
  when 'refs', 'files'
951
1023
  if flag == :remote
952
- format_desc action, flag, 'remote?,opts*,pattern*'
1024
+ format_desc action, flag, 'remote?|:,opts*,pattern*'
953
1025
  task flag, [:remote] do |_, args|
954
- ls_remote(flag, args.extras, remote: args.remote)
1026
+ args = if (remote = args.remote) && (remote == ':' || !git_grep('remote', remote).empty?)
1027
+ remote = choice_remote(force: true) if remote == ':'
1028
+ args.extras
1029
+ else
1030
+ remote = remotetrack
1031
+ args.to_a
1032
+ end
1033
+ ls_remote(flag, args, remote: remote)
955
1034
  end
956
1035
  else
957
1036
  format_desc(action, flag, 'opts*,pattern*', after: ('pathspec*' if action == 'files'))
@@ -962,10 +1041,11 @@ module Squared
962
1041
  when 'restore'
963
1042
  case flag
964
1043
  when :source
965
- format_desc action, flag, 'ref,opts*,pathspec*'
1044
+ format_desc action, flag, 'commit?|:,opts*,pathspec*'
966
1045
  task flag, [:commit] do |_, args|
967
1046
  commit = commithead args.commit
968
1047
  args = if commit
1048
+ commit = choice_commit if commit == ':'
969
1049
  args.extras
970
1050
  else
971
1051
  commit, opts, files = choice_commit(values: ['Options', ['Pathspec', true]])
@@ -1204,45 +1284,62 @@ module Squared
1204
1284
  end
1205
1285
  end
1206
1286
 
1207
- def clone(*, sync: invoked_sync?('clone'), **)
1208
- return unless clone? && (data = workspace.git_repo(name))
1287
+ def clone(flag = nil, opts = [], sync: invoked_sync?('clone'), dir: nil, ref: nil, **)
1288
+ if flag
1289
+ return unless dir && ref
1290
+
1291
+ url = git_spawn("config --get remote.#{remotetrack}.url")
1292
+ cmd, opts = git_session('clone', worktree: false, opts: opts)
1293
+ op = OptionPartition.new(opts, OPT_GIT[:clone], cmd, project: self, strict: strict?,
1294
+ no: OPT_GIT[:no][:clone])
1295
+ op.add_option('b', ref)
1296
+ .delim
1297
+ .add_quote(url.chomp)
1298
+ .add_path(dir)
1299
+ .clear
1300
+ source
1301
+ else
1302
+ return unless clone? && (data = workspace.git_repo(name))
1209
1303
 
1210
- cmd = git_session('clone', worktree: false)
1211
- opts = data[1].dup
1212
- option('depth', ignore: false) do |val|
1213
- if (n = val.to_i) > 0
1214
- opts[:depth] = n
1304
+ cmd = git_session('clone', worktree: false)
1305
+ opts = data[1].dup
1306
+ option('depth', ignore: false) do |val|
1307
+ if (n = val.to_i) > 0
1308
+ opts[:depth] = n
1309
+ else
1310
+ opts.delete(:depth)
1311
+ end
1312
+ end
1313
+ option('origin', ignore: false) { |val| opts[:origin] = val }
1314
+ if (branch = option('branch', strict: true))
1315
+ opts[:branch] = branch
1316
+ opts.delete(:revision)
1215
1317
  else
1216
- opts.delete(:depth)
1318
+ option('revision', strict: true) do |val|
1319
+ opts[:revision] = val
1320
+ opts.delete(:branch)
1321
+ opts.delete(:mirror)
1322
+ end
1217
1323
  end
1218
- end
1219
- option('origin', ignore: false) { |val| opts[:origin] = val }
1220
- if (branch = option('branch', strict: true))
1221
- opts[:branch] = branch
1222
- opts.delete(:revision)
1223
- else
1224
- option('revision', strict: true) do |val|
1225
- opts[:revision] = val
1226
- opts.delete(:branch)
1227
- opts.delete(:mirror)
1324
+ option('local', strict: true) { |val| opts[:local] = val != '0' }
1325
+ option('bare') { |val| opts[:bare] = val }
1326
+ option('single-branch', ignore: false) do |val|
1327
+ opts[:'single-branch'] = val != '0' && val != 'false'
1328
+ opts.delete(:'no-single-branch')
1228
1329
  end
1330
+ option('no-checkout') do
1331
+ opts[:'no-checkout'] = true
1332
+ opts.delete(:n)
1333
+ end
1334
+ option('no-tags') { opts[:'no-tags'] = true }
1335
+ if append_submodules(from: :clone)
1336
+ opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules')
1337
+ end
1338
+ append_hash opts
1339
+ cmd << '--quiet' if quiet? || option('quiet')
1340
+ append_value(data[0], path, delim: true)
1341
+ source(sync: sync, banner: sync && !quiet?, multiple: !sync || quiet?)
1229
1342
  end
1230
- option('local', strict: true) { |val| opts[:local] = val != '0' }
1231
- option('bare') { |val| opts[:bare] = val }
1232
- option('single-branch', ignore: false) do |val|
1233
- opts[:'single-branch'] = val != '0' && val != 'false'
1234
- opts.delete(:'no-single-branch')
1235
- end
1236
- option('no-checkout') do
1237
- opts[:'no-checkout'] = true
1238
- opts.delete(:n)
1239
- end
1240
- option('no-tags') { opts[:'no-tags'] = true }
1241
- opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(from: :clone)
1242
- append_hash opts
1243
- cmd << '--quiet' if quiet? || option('quiet')
1244
- append_value(data[0], path, delim: true)
1245
- source(sync: sync, banner: sync && !quiet?, multiple: !sync || quiet?)
1246
1343
  end
1247
1344
 
1248
1345
  def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
@@ -1272,7 +1369,11 @@ module Squared
1272
1369
  first: (matchpathspec if flag == :push))
1273
1370
  case flag
1274
1371
  when :push
1275
- op.readline('Enter message', option: 'message', quote: true) if op.remove(':')
1372
+ if op.remove(':')
1373
+ op.readline('Enter message', option: 'message', quote: true)
1374
+ else
1375
+ append_message
1376
+ end
1276
1377
  append_pathspec op.extras
1277
1378
  when :pop, :apply, :drop, :branch
1278
1379
  if op.remove(':')
@@ -1434,6 +1535,55 @@ module Squared
1434
1535
  end
1435
1536
  end
1436
1537
 
1538
+ def push(flag = nil, opts = [], origin: nil, branch: nil, ref: nil)
1539
+ cmd, opts = git_session('push', opts: opts)
1540
+ op = OptionPartition.new(opts, OPT_GIT[:push], cmd, project: self, strict: strict?, no: OPT_GIT[:no][:push])
1541
+ force = op.arg?('f', 'force', 'force-with-lease')
1542
+ case flag
1543
+ when :origin, :remote
1544
+ exit 1 unless origin && branch
1545
+ unless force
1546
+ repofetch(origin, branch: branch)
1547
+ exit 1 if (branch.start_with?(':') || op.arg?('d', 'delete')) && !confirm_basic('Delete?', branch, 'N')
1548
+ end
1549
+ op.append(origin, branch)
1550
+ .clear(pass: false)
1551
+ when :commit
1552
+ exit 1 unless ref
1553
+ branch ||= git_spawn('name-rev --name-only', ref).chomp
1554
+ raise ArgumentError, message('could not resolve upstream branch', hint: ref) if branch.empty?
1555
+
1556
+ op.append(remotetrack, "#{ref}:#{branch}")
1557
+ .clear(pass: false)
1558
+ when :all
1559
+ op << '--all'
1560
+ op.add_quote(origin) if origin ||= option('origin')
1561
+ op.clear
1562
+ else
1563
+ op << "--#{flag}" if flag
1564
+ op.concat(Array(branch)) if branch
1565
+ origin ||= option('origin')
1566
+ if !op.empty?
1567
+ origin ||= remotetrack
1568
+ unless force
1569
+ i = -1
1570
+ op.each do |val|
1571
+ if !val.include?(':') && repofetch(origin, branch: val, sync: (i += 1).zero?).first.nil?
1572
+ op.errors << val
1573
+ else
1574
+ op.found << val
1575
+ end
1576
+ end
1577
+ end
1578
+ op.add_quote(origin, *op.found)
1579
+ .clear(errors: !force, pass: false)
1580
+ elsif origin
1581
+ op.add_quote(origin)
1582
+ end
1583
+ end
1584
+ source
1585
+ end
1586
+
1437
1587
  def reset(flag, opts = [], refs: nil, ref: nil, mode: nil, commit: nil)
1438
1588
  cmd, opts = git_session('reset', opts: opts)
1439
1589
  case flag
@@ -1469,7 +1619,7 @@ module Squared
1469
1619
  source
1470
1620
  end
1471
1621
 
1472
- def checkout(flag, opts = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil, merge: false)
1622
+ def checkout(flag, opts = [], origin: nil, branch: nil, create: nil, commit: nil, detach: nil, merge: false)
1473
1623
  cmd, opts = git_session('checkout', opts: opts)
1474
1624
  append_option 'f', 'force', 'merge'
1475
1625
  case flag
@@ -1612,10 +1762,29 @@ module Squared
1612
1762
  end
1613
1763
 
1614
1764
  def commit(flag, opts = [], refs: [], ref: nil, squash: nil, pick: nil, message: nil, pass: false)
1615
- fixup = flag == :fixup
1616
- amend = flag.match?(/^amend/) && !fixup
1617
- unless flag == :add || pick == 'reword'
1618
- pathspec = if flag == :all || ((fixup || amend) && refs.size == 1 && refs.first == '*')
1765
+ case flag
1766
+ when :head
1767
+ cmd, opts = git_session('commit', opts: opts)
1768
+ op = OptionPartition.new(opts, OPT_GIT[:commit], cmd, project: self, strict: strict?,
1769
+ no: OPT_GIT[:no][:commit], first: matchpathspec)
1770
+ append_message message
1771
+ if op.arg?('p', 'patch', 'i', 'interactive')
1772
+ op.clear
1773
+ else
1774
+ append_pathspec op.extras
1775
+ end
1776
+ return source
1777
+ when :all
1778
+ pathspec = '--all'
1779
+ when :add
1780
+ pathspec = false
1781
+ when :amend, :'amend-orig'
1782
+ amend = true
1783
+ else
1784
+ pathspec = false if pick == 'reword'
1785
+ end
1786
+ if pathspec.nil?
1787
+ pathspec = if (flag == :fixup || amend) && refs.size == 1 && refs.first == '*'
1619
1788
  '--all'
1620
1789
  elsif (refs = projectmap(refs)).empty?
1621
1790
  raise 'no qualified pathspec'
@@ -1623,8 +1792,8 @@ module Squared
1623
1792
  "-- #{refs.join(' ')}"
1624
1793
  end
1625
1794
  end
1626
- if fixup
1627
- ret = source(git_session('commit', basic_option('fixup', pick ? "#{pick}:#{ref}" : ref), pathspec))
1795
+ if flag == :fixup
1796
+ ret = source(git_session('commit', basic_option('fixup', pick ? task_join(pick, ref) : ref), pathspec))
1628
1797
  source git_output('rebase --autosquash', squash) if ret && squash.is_a?(String)
1629
1798
  return ret
1630
1799
  end
@@ -1634,34 +1803,23 @@ module Squared
1634
1803
 
1635
1804
  message = readline('Enter message', force: true)
1636
1805
  end
1637
- branch = nil
1638
- origin = nil
1639
- upstream = nil
1640
1806
  cmd, opts = git_session('add', opts: opts)
1641
1807
  op = OptionPartition.new(opts, OPT_GIT[:add] + OPT_GIT[:log][:diff_context], cmd,
1642
1808
  project: self, strict: strict?, no: OPT_GIT[:no][:add], first: matchpathspec)
1643
1809
  op << '--verbose' unless silent?
1644
- format = '%(if)%(HEAD)%(then)%(refname:short)...%(upstream:short)...%(upstream:track)%(end)'
1645
- git_spawn 'fetch --no-tags --quiet'
1646
- foreachref('heads', format: format).each do |line|
1647
- next if line.empty?
1648
-
1649
- branch, origin, hint = line.split('...')
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?
1653
- return nil if pass
1810
+ origin, branch = repofetch
1811
+ unless origin || dryrun?
1812
+ return if pass
1654
1813
 
1655
- unless (origin = option('upstream', prefix: 'git', ignore: false))
1656
- if (origin = choice_refs('Choose an upstream', 'remotes', attempts: 1, force: false))
1657
- git_spawn 'branch', quote_option('set-upstream-to', origin)
1658
- break
1659
- end
1814
+ upstream = true
1815
+ unless (origin = option('origin', 'upstream', prefix: 'git', ignore: false))
1816
+ if (origin = choice_refs('Choose an upstream', 'remotes', attempts: 1, force: false))
1817
+ git_spawn 'branch', quote_option('set-upstream-to', origin)
1818
+ upstream = false
1819
+ else
1660
1820
  origin = readline('Enter an upstream', force: true)
1661
1821
  end
1662
- upstream = true
1663
1822
  end
1664
- break
1665
1823
  end
1666
1824
  if pathspec
1667
1825
  op << pathspec
@@ -1958,7 +2116,7 @@ module Squared
1958
2116
  op.add_quote(remote) if remote
1959
2117
  out, banner, from = source(io: true)
1960
2118
  print_item banner
1961
- ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
2119
+ ret = write_lines(out, grep: op.extras)
1962
2120
  list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1963
2121
  end
1964
2122
 
@@ -2171,15 +2329,15 @@ module Squared
2171
2329
  choice_index(msg, foreachref(type, *args, format: format), trim: trim, **kwargs)
2172
2330
  end
2173
2331
 
2174
- def choice_commit(count: true, reflog: true, force: true, **kwargs)
2332
+ def choice_commit(range = nil, count: true, reflog: true, force: true, **kwargs)
2175
2333
  kwargs[:attempts] ||= 1 unless force
2176
- cmd = git_output(reflog && env('GIT_REFLOG') ? 'reflog' : 'log')
2334
+ cmd = git_output(reflog && env('GIT_REFLOG') ? 'reflog' : 'log', range)
2177
2335
  cmd << quote_option('format', "#{commitstyle('%h')} %s")
2178
2336
  cmd << basic_option('max-count', env('GIT_COUNT', ARG[:CHOICE])) if count
2179
2337
  ret = choice_index('Choose a commit', git_spawn(cmd, stdout: false), column: /^(\S+)/, force: force, **kwargs)
2180
2338
  case ret
2181
2339
  when Array
2182
- ret.map(&:stripstyle)
2340
+ ret.map { |val| val&.stripstyle }
2183
2341
  when String
2184
2342
  ret.stripstyle
2185
2343
  else
@@ -2264,9 +2422,9 @@ module Squared
2264
2422
  end
2265
2423
  end
2266
2424
 
2267
- def append_pathspec(files = [], target: @session, expect: false, **kwargs)
2425
+ def append_pathspec(files = [], target: @session, expect: false, strict: strict?, **kwargs)
2268
2426
  if session_arg?('pathspec-from-file', target: target)
2269
- OptionPartition.clear(target, files, styles: theme[:inline])
2427
+ OptionPartition.clear(target, files, strict: strict, styles: theme[:inline])
2270
2428
  true
2271
2429
  else
2272
2430
  option('pathspec', target: target) { |val| files = split_escape(val) } if files.empty?
@@ -2308,7 +2466,7 @@ module Squared
2308
2466
  end
2309
2467
  else
2310
2468
  target << case val
2311
- when 'no', '0', 'false'
2469
+ when '0', 'false', 'no'
2312
2470
  '--no-recurse-submodules'
2313
2471
  when 'yes', 'on-demand'
2314
2472
  "--recurse-submodules=#{val}"
@@ -2367,10 +2525,6 @@ module Squared
2367
2525
  ret
2368
2526
  end
2369
2527
 
2370
- def dryrun?(target: @session, prefix: target&.first, **)
2371
- Array(target).include?('--dry-run') || !option('dry-run', target: target, prefix: prefix).nil?
2372
- end
2373
-
2374
2528
  def quiet?(target: @session, **)
2375
2529
  return silent? unless target
2376
2530
 
@@ -2381,6 +2535,25 @@ module Squared
2381
2535
  basepath('.git', *args)
2382
2536
  end
2383
2537
 
2538
+ def repofetch(origin = 'HEAD', branch: nil, sync: true)
2539
+ format = if branch
2540
+ "%(if:equals=#{origin}/#{branch})%(upstream:short)"
2541
+ else
2542
+ "%(if)%(#{origin})"
2543
+ end
2544
+ format += '%(then)%(refname:short)...%(upstream:short)...%(upstream:track)%(end)'
2545
+ git_spawn 'fetch --no-tags --quiet' if sync
2546
+ foreachref('heads', format: format).each do |line|
2547
+ next if line.empty?
2548
+
2549
+ branch, origin, hint = line.split('...')
2550
+ raise message('work tree is not usable', hint: hint[1..-2]) if hint && !hint.match?(/^\[(\D+0,\D+0)\]$/)
2551
+
2552
+ return [origin.empty? ? nil : origin, branch]
2553
+ end
2554
+ []
2555
+ end
2556
+
2384
2557
  def repotrack(origin, branch, quote: true)
2385
2558
  n = origin&.index('/')
2386
2559
  raise message("missing #{origin ? 'branch' : 'remote'} name", hint: origin) unless n && branch
@@ -2391,6 +2564,10 @@ module Squared
2391
2564
  ret
2392
2565
  end
2393
2566
 
2567
+ def remotetrack
2568
+ git_spawn('rev-parse --abbrev-ref @{u}').split('/', 2).first
2569
+ end
2570
+
2394
2571
  def commithash(val)
2395
2572
  val[/\A:(\h{5,40})\z/, 1]
2396
2573
  end