squared 0.7.3 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -164,27 +164,27 @@ module Squared
164
164
  checkout: %w[l d|detach f|force ignore-other-worktrees ignore-skip-worktree-bits m|merge p|patch
165
165
  pathspec-file-nul q|quiet ours theirs conflict=b orphan=b pathspec-from-file=p t|track=b].freeze,
166
166
  diff: {
167
- base: %w[0 1|base 2|ours 3|theirs].freeze,
167
+ base: %w[0 1|base 2|ours 3|theirs cached merge-base].freeze,
168
168
  show: %w[s exit-code histogram].freeze
169
169
  }.freeze,
170
170
  fetch: {
171
171
  base: %w[multiple porcelain progress P|prune-tags refetch stdin u|update-head-ok
172
- recurse-submodules-default=b].freeze,
172
+ recurse-submodules-default=b?].freeze,
173
173
  pull: %w[4 6 n t a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet set-upstream
174
174
  unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q recurse-submodules=v
175
175
  refmap=q o|server-option=q shallow-exclude=b shallow-since=v upload-pack=q].freeze
176
176
  }.freeze,
177
177
  git: {
178
- add: %w[N|intent-to-add refresh].freeze,
178
+ add: %w[N|intent-to-add].freeze,
179
179
  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
180
180
  p|porcelain root score-debug f|show-name e|show-email n|show-number show-stats abbrev=i contents=p
181
- date=q encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
181
+ date=q diff-algorithm=b encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
182
182
  clean: %w[d x X f|force n|dry-run i|interactive q|quiet e|exclude=q].freeze,
183
183
  grep: %w[e f=p h H I O=bm r all-match and G|basic-regexp break cached column c|count E|extended-regexp
184
184
  l|files-with-matches L|files-without-match F|fixed-strings full-name W|function-context heading
185
185
  i|ignore-case v|invert-match n|line-number name-only no-index not z|null o|only-matching or
186
186
  P|perl-regexp q|quiet recurse-submodules p|show-function a|text untracked w|word-regexp
187
- A|after-context=i B|before-context=i color=b C|context=i m|max-count=n max-depth=i
187
+ A|after-context=i B|before-context=i color=b C|context=i m|max-count=n max-depth=n
188
188
  open-files-in-pager=b threads=n].freeze,
189
189
  mv: %w[k f|force n|dry-run v|verbose].freeze,
190
190
  revert: %w[e S=bm? n|no-commit reference cleanup=b gpg-sign=b? m|mainline=i s|signoff strategy=b
@@ -197,26 +197,26 @@ module Squared
197
197
  base: %w[L=qm all all-match alternate-refs author-date-order basic-regexp bisect boundary cherry cherry-mark
198
198
  cherry-pick clear-decorations date-order dense do-walk exclude-first-parent-only E|extended-regexp
199
199
  first-parent F|fixed-strings follow full-diff full-history ignore-missing invert-grep left-only
200
- log-size merge no-max-parents no-min-parents not P|perl-regexp reflog i|regexp-ignore-case
201
- remove-empty reverse right-only simplify-by-decoration simplify-merges single-worktree show-pulls
202
- source sparse stdin topo-order g|walk-reflogs after=q ancestry-path=b? author=q before=q
203
- branches=q? committer=q decorate=b decorate-refs=q decorate-refs-exclude=q exclude=q
204
- exclude-hidden=b glob=q grep=q grep-reflog=q n|max-count=i max-parents=i min-parents=i no-walk=b?
205
- remotes=q? since=q since-as-filter=q skip=i tags=q? until=q].freeze,
200
+ log-size maximal-only merge no-max-parents no-min-parents not P|perl-regexp reflog
201
+ i|regexp-ignore-case remove-empty reverse right-only simplify-by-decoration simplify-merges
202
+ single-worktree show-pulls source sparse stdin topo-order g|walk-reflogs after=q ancestry-path=b?
203
+ author=q before=q branches=q? committer=q decorate=b decorate-refs=q decorate-refs-exclude=q
204
+ exclude=q exclude-hidden=b glob=q grep=q grep-reflog=q n|max-count=i max-parents=i min-parents=i
205
+ no-walk=b? remotes=q? since=q since-as-filter=q skip=i tags=q? until=q].freeze,
206
206
  format: %w[t children combined-all-paths dd oneline left-right no-diff-merges parents relative-date
207
207
  show-notes-by-default show-signature date=q diff-merges=b encoding=b expand-tabs=i format=q
208
208
  notes=b pretty=q? show-linear-break=q?].freeze,
209
209
  diff: %w[p R u z B=bm? C=bm? l=im G=qm I=qm M=bm? O=qm S=qm binary check compact-summary cumulative
210
- find-copies-harder full-index W|function-context w|ignore-all-space ignore-blank-lines
211
- ignore-cr-at-eol ignore-space-at-eol b|ignore-space-change D|irreversible-delete graph
212
- ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames numstat
213
- patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary a|text
214
- abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
210
+ default-prefix find-copies-harder full-index W|function-context w|ignore-all-space
211
+ ignore-blank-lines ignore-cr-at-eol ignore-space-at-eol b|ignore-space-change D|irreversible-delete
212
+ graph ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames
213
+ numstat patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary
214
+ a|text abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
215
215
  diff-algorithm=b diff-filter=e? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
216
- find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? line-prefix=q output=p
217
- output-indicator-context=q output-indicator-new=q output-indicator-old=q relative=p rotate-to=p
218
- skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i submodule=b?
219
- word-diff=b? word-diff-regex=q ws-error-highlight=b].freeze,
216
+ find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? line-prefix=q
217
+ max-depth=n output=p output-indicator-context=q output-indicator-new=q output-indicator-old=q
218
+ relative=p rotate-to=p skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i
219
+ submodule=b? word-diff=b? word-diff-regex=q ws-error-highlight=b].freeze,
220
220
  diff_context: %w[U=im inter-hunk-context=i unified=i].freeze
221
221
  }.freeze,
222
222
  ls_files: %w[f t v z debug deduplicate directory eol error-unmatch exclude-standard full-name i|ignored
@@ -227,10 +227,12 @@ module Squared
227
227
  gpg-sign=b? into-name=b log=i s|strategy=b X|strategy-option=b].freeze,
228
228
  pull: %w[e n S=bm? allow-unrelated-histories compact-summary ff-only cleanup=b gpg-sign=b? log=i r|rebase=v?
229
229
  s|strategy=b X|strategy-option=b].freeze,
230
+ range_diff: %w[left-only no-dual-color no-notes remerge-diff right-only creation-factor=i diff-merges=b
231
+ notes=q?].freeze,
230
232
  rebase: %w[n C=im S=bm? allow-empty-message apply committer-date-is-author-date edit-todo empty=b
231
233
  f|force-rebase ignore-date ignore-whitespace i|interactive keep-base m|merge no-ff q|quiet quit
232
234
  reset-author-date root show-current-patch signoff v|verbose empty=b x|exec=q gpg-sign=b? onto=b
233
- r|rebase-merges=b s|strategy=b X|strategy-option=b whitespace=b].freeze,
235
+ r|rebase-merges=b s|strategy=b X|strategy-option=b trailer=q whitespace=b].freeze,
234
236
  reset: %w[N pathspec-file-nul q|quiet pathspec-from-file=p].freeze,
235
237
  restore: %w[ignore-skip-worktree-bits ignore-unmerged m|merge ours p|patch pathspec-file-nul q|quiet S|staged
236
238
  theirs W|worktree conflict=b pathspec-from-file=p s|source=b].freeze,
@@ -258,8 +260,9 @@ module Squared
258
260
  ignored=b? porcelain=b? untracked-files=b?].freeze,
259
261
  submodule: {
260
262
  status: %w[cached recursive].freeze,
261
- update: %w[checkout f|force init merge N|no-fetch no-recommend-shallow no-single-branch recommend-shallow
262
- rebase recursive remote single-branch depth=i filter=q jobs=i reference=b ref-format=q].freeze,
263
+ update: %w[checkout f|force init merge progress N|no-fetch no-recommend-shallow no-single-branch
264
+ recommend-shallow rebase recursive remote single-branch depth=i filter=q jobs=i name=q
265
+ reference=q ref-format=q].freeze,
263
266
  branch: %w[b|branch d|default].freeze,
264
267
  sync: %w[recursive].freeze
265
268
  }.freeze,
@@ -333,10 +336,11 @@ module Squared
333
336
  'checkout' => %i[commit branch track detach path].freeze,
334
337
  'commit' => %i[add all amend amend-orig fixup].freeze,
335
338
  'diff' => %i[head branch files view between contain].freeze,
339
+ 'range-diff' => %i[view between contain].freeze,
336
340
  'fetch' => %i[origin remote all].freeze,
337
341
  'files' => %i[cached modified deleted others].freeze,
338
342
  'git' => %i[add blame clean grep mv revert rm sparse-checkout status].freeze,
339
- 'log' => %i[view grep between contain].freeze,
343
+ 'log' => %i[grep view between contain].freeze,
340
344
  'merge' => %i[commit no-commit send].freeze,
341
345
  'pull' => %i[origin remote all].freeze,
342
346
  'rebase' => %i[branch onto send].freeze,
@@ -503,7 +507,7 @@ module Squared
503
507
  task flag do |_, args|
504
508
  stash flag, args.to_a
505
509
  end
506
- when 'log', 'diff'
510
+ when 'log', 'diff', 'range-diff'
507
511
  case flag
508
512
  when :view, :between, :contain
509
513
  if action == 'log' && flag == :view
@@ -529,22 +533,25 @@ module Squared
529
533
  end
530
534
  log!(flag, args, index: index)
531
535
  end
532
- else
533
- format_desc action, flag, 'commit1,commit2,opts*,pathspec*'
534
- task flag, [:commit1, :commit2] do |_, args|
535
- commit1 = commithead args.commit1
536
- range = if commit1
537
- commit2 = commithead param_guard(action, flag, args: args, key: :commit2)
538
- args = args.extras
539
- [commit1, commit2]
540
- else
541
- range, opts, refs = choice_commit(multiple: flag == :view ? true : 2,
542
- values: %w[Options Pathspec])
543
- args = OptionPartition.strip(opts)
544
- args.concat(refs.shellsplit) if refs
545
- range.reverse
546
- end
547
- __send__(action == 'log' ? :log! : :diff, flag, args, range: range)
536
+ next
537
+ end
538
+ format_desc action, flag, 'commit1,commit2,opts*,pathspec*'
539
+ task flag, [:commit1, :commit2] do |_, args|
540
+ commit1 = commithead args.commit1
541
+ if commit1
542
+ range = [commit1, commithead(param_guard(action, flag, args: args, key: :commit2))]
543
+ opts = args.extras
544
+ else
545
+ range, opts, refs = choice_commit(multiple: flag == :view ? true : 2,
546
+ values: %w[Options Pathspec])
547
+ range.reverse!
548
+ opts = OptionPartition.strip(opts)
549
+ opts.concat(refs.shellsplit) if refs
550
+ end
551
+ if action == 'log'
552
+ log!(flag, opts, range: range)
553
+ else
554
+ diff(flag, opts, range: range, from: action.to_sym)
548
555
  end
549
556
  end
550
557
  when :head
@@ -615,7 +622,6 @@ module Squared
615
622
  format_desc action, flag, 'name,create?=[bB],commit?,d/etach?'
616
623
  task flag, [:name, :create, :commit, :detach] do |_, args|
617
624
  if (branch = args.name)
618
- branch = param_guard(action, flag, args: args, key: :name)
619
625
  create = args.create
620
626
  detach = if args.commit == 'd'
621
627
  commit = nil
@@ -632,7 +638,7 @@ module Squared
632
638
  commit = commithead args.commit
633
639
  args.detach
634
640
  end
635
- param_guard(action, flag, args: { create: create }, key: :create, pat: /\A[Bb]\z/) if create
641
+ param_guard(action, flag, args: { create: create }, key: :create, pat: /^[Bb]$/) if create
636
642
  else
637
643
  branch = choice_refs 'Choose a branch to switch'
638
644
  end
@@ -798,15 +804,13 @@ module Squared
798
804
  task flag, [:mode, :ref] do |_, args|
799
805
  mode = param_guard(action, flag, args: args, key: :mode)
800
806
  ref = commithead args.ref
801
- ref = choice_commit(reflog: false) if ref == ':'
802
- reset(flag, mode: mode, ref: ref)
807
+ reset(flag, mode: mode, ref: ref == ':' ? choice_commit(reflog: false) : ref)
803
808
  end
804
809
  when :patch
805
810
  format_desc action, flag, 'ref/:,pathspec*'
806
811
  task flag, [:ref] do |_, args|
807
812
  ref = commithead args.ref
808
- ref = choice_commit(reflog: false) unless ref && ref != ':'
809
- reset(flag, refs: args.extras, ref: ref)
813
+ reset(flag, refs: args.extras, ref: !ref || ref == ':' ? choice_commit(reflog: false) : ref)
810
814
  end
811
815
  end
812
816
  when 'show'
@@ -858,15 +862,25 @@ module Squared
858
862
  rebase(flag, args, commit: commit, upstream: upstream, branch: branch)
859
863
  end
860
864
  when :commit, :'no-commit'
861
- format_desc action, flag, 'refs+,opts*'
862
- task flag do |_, args|
863
- args = args.to_a
864
- if args.empty?
865
- accept = "Merge with #{`#{git_output('branch --show-current')}`.chomp}?"
866
- branch, opts = choice_refs('Choose a branch', values: 'Options', accept: accept)
867
- args = OptionPartition.strip(opts)
865
+ format_desc action, flag, 'branch|:,ours|theirs?,opts*'
866
+ task flag, [:branch] do |_, args|
867
+ current = `#{git_output('branch --show-current')}`.chomp
868
+ if (branch = args.branch)
869
+ branch = choice_refs('Choose a branch', accept: "#{action.capitalize}?") if branch == ':'
870
+ opts = args.extras
871
+ if has_value!(opts, 'ours')
872
+ opts << 's=ort' << 'X=ours'
873
+ elsif has_value!(opts, 'theirs')
874
+ opts << 's=ort' << 'X=theirs'
875
+ end
876
+ else
877
+ branch, opts = choice_refs('Choose a branch', values: 'Options',
878
+ accept: "Merge with #{current}?")
879
+ opts = OptionPartition.strip(opts)
868
880
  end
869
- merge(flag, args, branch: branch)
881
+ raise ArgumentError, 'nothing to merge' if current == branch
882
+
883
+ merge(flag, opts, branch: branch)
870
884
  end
871
885
  when :send
872
886
  format_desc(action, flag, VAL_GIT[action.to_sym][:send], arg: nil)
@@ -930,7 +944,7 @@ module Squared
930
944
  args.extras
931
945
  else
932
946
  commit, opts, files = choice_commit(values: ['Options', ['Pathspec', true]])
933
- files = files&.shellsplit
947
+ files &&= files.shellsplit
934
948
  OptionPartition.strip(opts)
935
949
  end
936
950
  restore(flag, args, commit: commit, files: files)
@@ -1031,13 +1045,10 @@ module Squared
1031
1045
  end
1032
1046
  printsucc
1033
1047
  end
1034
- op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, no: OPT_GIT[:no][:pull])
1035
- reg = if op.empty?
1036
- []
1037
- else
1038
- opts = op.uniq(opts)
1039
- matchmap op
1040
- end
1048
+ op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, strict: strict?,
1049
+ no: OPT_GIT[:no][:pull])
1050
+ opts -= op.extras
1051
+ reg = matchmap op
1041
1052
  session_done op.target
1042
1053
  heads = []
1043
1054
  cur = nil
@@ -1081,7 +1092,8 @@ module Squared
1081
1092
  when :branch
1082
1093
  return unless upstream
1083
1094
 
1084
- op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
1095
+ op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, strict: strict?,
1096
+ no: OPT_GIT[:no][:rebase])
1085
1097
  op << upstream
1086
1098
  append_head op.shift&.delete_prefix(':')
1087
1099
  op.clear(pass: false)
@@ -1185,10 +1197,11 @@ module Squared
1185
1197
  list.concat(collect_hash(OPT_GIT[:log]))
1186
1198
  no = collect_hash OPT_GIT[:no][:log]
1187
1199
  end
1188
- op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: (matchpathspec if flag == :push))
1200
+ op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?, no: no,
1201
+ first: (matchpathspec if flag == :push))
1189
1202
  case flag
1190
1203
  when :push
1191
- op.append?('message', readline('Enter message', force: true), force: true) if op.remove(':')
1204
+ op.readline('Enter message', option: 'message', quote: true) if op.remove(':')
1192
1205
  append_pathspec op.extras
1193
1206
  when :pop, :apply, :drop, :branch
1194
1207
  if op.remove(':')
@@ -1209,7 +1222,7 @@ module Squared
1209
1222
  elsif !op.empty?
1210
1223
  op.add_first(prefix: ':')
1211
1224
  elsif flag == :branch
1212
- raise_error ArgumentError, 'no branch name'
1225
+ raise ArgumentError, 'no branch name'
1213
1226
  end
1214
1227
  op.clear
1215
1228
  when :clear
@@ -1239,7 +1252,8 @@ module Squared
1239
1252
  def status(flag = nil, opts = [])
1240
1253
  cmd, opts = git_session('status', opts: opts)
1241
1254
  if flag
1242
- op = OptionPartition.new(opts, OPT_GIT[:status], cmd, project: self, no: OPT_GIT[:no][:status])
1255
+ op = OptionPartition.new(opts, OPT_GIT[:status], cmd, project: self, strict: strict?,
1256
+ no: OPT_GIT[:no][:status])
1243
1257
  append_pathspec op.extras
1244
1258
  else
1245
1259
  cmd << (option('long') ? '--long' : '--short')
@@ -1309,7 +1323,7 @@ module Squared
1309
1323
  kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? kw.call : @revbuild || { pass: true }
1310
1324
  case flag
1311
1325
  when :build
1312
- op = OptionPartition.new(opts, VAL_GIT[:revbuild].map { |key| "#{key}=b?" }, project: self)
1326
+ op = OptionPartition.new(opts, VAL_GIT[:revbuild].map { |key| "#{key}=b?" }, project: self, strict: strict?)
1313
1327
  op.clear(append: true)
1314
1328
  args = op.to_a
1315
1329
  else
@@ -1354,7 +1368,8 @@ module Squared
1354
1368
  case flag
1355
1369
  when :commit, :index
1356
1370
  op = OptionPartition.new(opts, OPT_GIT[:reset] + VAL_GIT[:reset] + OPT_GIT[:log][:diff_context], cmd,
1357
- project: self, no: OPT_GIT[:no][:reset], first: (matchpathspec if flag == :index))
1371
+ project: self, strict: strict?, no: OPT_GIT[:no][:reset],
1372
+ first: (matchpathspec if flag == :index))
1358
1373
  if flag == :commit
1359
1374
  op.append(commit)
1360
1375
  .clear(pass: false)
@@ -1399,7 +1414,7 @@ module Squared
1399
1414
  cmd << '--detach' << commit
1400
1415
  else
1401
1416
  op = OptionPartition.new(opts, OPT_GIT[:checkout] + OPT_GIT[:log][:diff_context], cmd,
1402
- project: self, no: OPT_GIT[:no][:checkout],
1417
+ project: self, strict: strict?, no: OPT_GIT[:no][:checkout],
1403
1418
  first: (matchpathspec if flag == :path))
1404
1419
  if flag == :path
1405
1420
  append_head
@@ -1422,6 +1437,7 @@ module Squared
1422
1437
  cmd << '--annotate'
1423
1438
  end
1424
1439
  cmd << '--force' if option('f', 'force')
1440
+ option('trailer') { |val| cmd << quote_option('trailer', val) }
1425
1441
  if !commit && message && (sha = commithash(message))
1426
1442
  commit = sha
1427
1443
  message = nil
@@ -1433,7 +1449,8 @@ module Squared
1433
1449
  cmd << '--delete'
1434
1450
  append_value refs
1435
1451
  else
1436
- op = OptionPartition.new(opts, OPT_GIT[:tag], cmd << '--list', project: self, no: OPT_GIT[:no][:tag])
1452
+ op = OptionPartition.new(opts, OPT_GIT[:tag], cmd << '--list', project: self, strict: strict?,
1453
+ no: OPT_GIT[:no][:tag])
1437
1454
  out, banner, from = source(io: true)
1438
1455
  print_item banner
1439
1456
  ret = write_lines(out, grep: op.extras)
@@ -1448,7 +1465,7 @@ module Squared
1448
1465
 
1449
1466
  def log!(flag, opts = [], range: [], index: [], grep: [])
1450
1467
  cmd, opts = git_session('log', opts: opts)
1451
- op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self,
1468
+ op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self, strict: strict?,
1452
1469
  no: collect_hash(OPT_GIT[:no][:log]),
1453
1470
  first: matchpathspec)
1454
1471
  case flag
@@ -1464,13 +1481,16 @@ module Squared
1464
1481
  source(exception: false)
1465
1482
  end
1466
1483
 
1467
- def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [])
1468
- cmd, opts = git_session('diff', opts: opts)
1469
- op = OptionPartition.new(opts,
1470
- collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context],
1471
- cmd,
1472
- project: self, no: OPT_GIT[:no][:log][:diff],
1473
- first: (matchpathspec unless flag == :files))
1484
+ def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [], from: :diff)
1485
+ cmd, opts = git_session(from, opts: opts)
1486
+ list = if from == :'range-diff'
1487
+ OPT_GIT[:range_diff]
1488
+ else
1489
+ no = OPT_GIT[:no][:log][:diff]
1490
+ collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context]
1491
+ end
1492
+ op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?, no: no,
1493
+ first: (matchpathspec unless flag == :files))
1474
1494
  case flag
1475
1495
  when :files, :view, :between, :contain
1476
1496
  op.delete('--cached')
@@ -1512,10 +1532,10 @@ module Squared
1512
1532
  patch = basepath patch.delete_prefix('>')
1513
1533
  exit 1 if patch.exist? && !confirm_basic('Overwrite?', patch)
1514
1534
  op << '>' << shell_quote(patch)
1515
- source(banner: false)
1535
+ source(banner: false, from: from)
1516
1536
  puts patch.read if patch.exist? && (stdin? || verbose?)
1517
1537
  else
1518
- source(exception: op.arg?('exit-code'))
1538
+ source(exception: op.arg?('exit-code'), from: from)
1519
1539
  end
1520
1540
  end
1521
1541
 
@@ -1526,7 +1546,7 @@ module Squared
1526
1546
  pathspec = if flag == :all || ((fixup || amend) && refs.size == 1 && refs.first == '*')
1527
1547
  '--all'
1528
1548
  elsif (refs = projectmap(refs)).empty?
1529
- raise_error 'no qualified pathspec'
1549
+ raise 'no qualified pathspec'
1530
1550
  else
1531
1551
  "-- #{refs.join(' ')}"
1532
1552
  end
@@ -1547,7 +1567,7 @@ module Squared
1547
1567
  upstream = nil
1548
1568
  cmd, opts = git_session('add', opts: opts)
1549
1569
  op = OptionPartition.new(opts, OPT_GIT[:add] + OPT_GIT[:log][:diff_context], cmd,
1550
- project: self, no: OPT_GIT[:no][:add], first: matchpathspec)
1570
+ project: self, strict: strict?, no: OPT_GIT[:no][:add], first: matchpathspec)
1551
1571
  op << '--verbose' unless silent?
1552
1572
  format = '%(if)%(HEAD)%(then)%(refname:short)...%(upstream:short)...%(upstream:track)%(end)'
1553
1573
  git_spawn 'fetch --no-tags --quiet'
@@ -1616,14 +1636,16 @@ module Squared
1616
1636
  display = false
1617
1637
  case flag
1618
1638
  when :commit, :'no-commit'
1619
- op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
1639
+ op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, strict: strict?,
1640
+ no: OPT_GIT[:no][:merge])
1620
1641
  op << "--#{flag}"
1621
1642
  op.delim
1622
1643
  if branch
1623
1644
  op << branch
1624
1645
  op.clear(pass: false)
1625
1646
  else
1626
- raise_error ArgumentError, 'no branch/commit' if op.empty?
1647
+ raise ArgumentError, 'no branch/commit' if op.empty?
1648
+
1627
1649
  append_commit(*op.extras)
1628
1650
  end
1629
1651
  else
@@ -1691,7 +1713,7 @@ module Squared
1691
1713
  return
1692
1714
  when :list
1693
1715
  op = OptionPartition.new(opts, OPT_GIT[:branch], cmd << '--list',
1694
- project: self, no: OPT_GIT[:no][:branch], single: /\Av+\z/)
1716
+ project: self, strict: strict?, no: OPT_GIT[:no][:branch], single: /\Av+\z/)
1695
1717
  op.each { |val| op.add_quote(val) }
1696
1718
  out, banner, from = source(io: true)
1697
1719
  print_item banner
@@ -1742,7 +1764,7 @@ module Squared
1742
1764
  cmd, opts = git_session('switch', opts: opts)
1743
1765
  cmd << '--force' if option('f', 'force')
1744
1766
  if flag == :branch
1745
- OptionPartition.new(opts, OPT_GIT[:switch], cmd, project: self, no: OPT_GIT[:no][:switch])
1767
+ OptionPartition.new(opts, OPT_GIT[:switch], cmd, project: self, strict: strict?, no: OPT_GIT[:no][:switch])
1746
1768
  .add_quote(branch)
1747
1769
  else
1748
1770
  case flag
@@ -1766,7 +1788,7 @@ module Squared
1766
1788
 
1767
1789
  def submodule(flag, opts = [], branch: nil, path: nil, url: nil)
1768
1790
  cmd, opts = git_session('submodule', opts: opts)
1769
- op = OptionPartition.new(opts, OPT_GIT[:submodule].fetch(flag, []), cmd, project: self)
1791
+ op = OptionPartition.new(opts, OPT_GIT[:submodule].fetch(flag, []), cmd, project: self, strict: strict?)
1770
1792
  case flag
1771
1793
  when :branch, :url
1772
1794
  op.adjoin("set-#{flag}")
@@ -1784,7 +1806,7 @@ module Squared
1784
1806
  op = OptionPartition.new(opts,
1785
1807
  OPT_GIT[:restore] + OPT_GIT[:log][:diff_context],
1786
1808
  cmd,
1787
- project: self, no: OPT_GIT[:no][:restore], first: matchpathspec)
1809
+ project: self, strict: strict?, no: OPT_GIT[:no][:restore], first: matchpathspec)
1788
1810
  append_pathspec(op.extras + (files || []), pass: false)
1789
1811
  source(sync: false, stderr: true)
1790
1812
  end
@@ -1813,6 +1835,7 @@ module Squared
1813
1835
  list = OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff] + OPT_GIT[:log][:diff_context]
1814
1836
  op = OptionPartition.new(opts, list, cmd,
1815
1837
  project: self,
1838
+ strict: strict?,
1816
1839
  no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
1817
1840
  op.append(delim: true)
1818
1841
  source(exception: false, banner: flag != :oneline)
@@ -1837,7 +1860,8 @@ module Squared
1837
1860
  cmd << '--sq-quote'
1838
1861
  args = true
1839
1862
  end
1840
- OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd, project: self, no: OPT_GIT[:no][:rev_parse], args: args)
1863
+ OptionPartition.new(opts, OPT_GIT[:rev_parse], cmd,
1864
+ project: self, strict: strict?, no: OPT_GIT[:no][:rev_parse], args: args)
1841
1865
  .append(escape: args)
1842
1866
  end
1843
1867
  source(banner: verbose?)
@@ -1846,7 +1870,7 @@ module Squared
1846
1870
  def sparse_checkout(flag, opts = [])
1847
1871
  cmd, opts = git_session('sparse-checkout', flag, opts: opts)
1848
1872
  op = OptionPartition.new(opts, OPT_GIT[:sparse_checkout].fetch(flag, []), cmd,
1849
- project: self, no: OPT_GIT[:no][:sparse_checkout][flag])
1873
+ project: self, strict: strict?, no: OPT_GIT[:no][:sparse_checkout][flag])
1850
1874
  case flag
1851
1875
  when :add
1852
1876
  append_pathspec(op.detach, expect: true, resolve: false, pass: false)
@@ -1860,7 +1884,7 @@ module Squared
1860
1884
  def ls_remote(flag, opts = [], remote: nil)
1861
1885
  cmd, opts = git_session('ls-remote --refs', opts: opts)
1862
1886
  cmd << "--#{flag}" unless flag == :remote
1863
- op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self)
1887
+ op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self, strict: strict?)
1864
1888
  op.add_quote(remote) if remote
1865
1889
  out, banner, from = source(io: true)
1866
1890
  print_item banner
@@ -1870,7 +1894,7 @@ module Squared
1870
1894
 
1871
1895
  def ls_files(flag, opts = [])
1872
1896
  cmd, opts = git_session("ls-files --#{flag}", opts: opts)
1873
- op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self)
1897
+ op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self, strict: strict?)
1874
1898
  op.splice(path: true, pattern: true)
1875
1899
  out, banner, from = source(io: true)
1876
1900
  print_item banner
@@ -1889,35 +1913,38 @@ module Squared
1889
1913
  when :'sparse-checkout'
1890
1914
  cmd << 'set'
1891
1915
  end
1892
- op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GIT[:no][flag], single: /\A\d+\z/,
1916
+ op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?,
1917
+ no: OPT_GIT[:no][flag], single: /\A\d+\z/,
1893
1918
  first: case flag
1894
1919
  when :blame, :revert, :'sparse-checkout' then nil
1895
1920
  else matchpathspec
1896
1921
  end)
1897
1922
  case flag
1898
1923
  when :blame
1899
- raise_error Errno::ENOENT, 'no file target' unless (n = op.index { |s| basepath(s).file? })
1924
+ raise Errno::ENOENT, 'no file target' unless (n = op.index { |s| basepath(s).file? })
1925
+
1900
1926
  op.append(basepath(op.remove_at(n)), delim: true)
1901
1927
  .clear
1902
1928
  when :revert
1903
1929
  if op.arg?(*VAL_GIT[:rebase][:send])
1904
1930
  op.clear
1905
1931
  elsif op.empty?
1906
- raise_error 'no commit target'
1932
+ raise 'no commit target'
1907
1933
  else
1908
1934
  append_commit(*op.extras)
1909
1935
  end
1910
1936
  when :add
1911
- if flag == :add && !op.arg?('pathspec-from-file')
1937
+ unless op.arg?('pathspec-from-file')
1912
1938
  grep, pathspec = op.partition { |val| OptionPartition.pattern?(val) }
1913
1939
  unless grep.empty? && !pathspec.empty?
1914
1940
  grep.map! { |val| Regexp.new(val[1..-2]) }
1915
- files = status_data.map do |a, b|
1916
- next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1941
+ files = status_data
1942
+ .map do |a, b|
1943
+ next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1917
1944
 
1918
- "#{sub_style(b, color(:red))} #{a}"
1919
- end
1920
- .compact
1945
+ "#{sub_style(b, color(:red))} #{a}"
1946
+ end
1947
+ .compact
1921
1948
  unless files.empty?
1922
1949
  files = choice_index('Select files', files, multiple: true, trim: /^\S+\s/,
1923
1950
  accept: [accept_y('Add?')])
@@ -1928,15 +1955,21 @@ module Squared
1928
1955
  return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
1929
1956
  when :mv
1930
1957
  refs = projectmap op.extras
1931
- raise_error 'no source/destination' unless refs.size > 1
1958
+ raise 'no source/destination' unless refs.size > 1
1959
+
1932
1960
  op.merge(refs)
1933
1961
  when :rm, :clean, :'sparse-checkout'
1934
1962
  append_pathspec(op.extras, expect: flag != :clean, resolve: flag != :'sparse-checkout')
1935
1963
  when :grep
1964
+ delim = false
1936
1965
  op.each do |val|
1937
- if op.include?('--')
1966
+ if val == '--'
1967
+ delim = true
1968
+ op.delim
1969
+ elsif delim
1938
1970
  op.add_path(val)
1939
1971
  elsif op.exist?(val, glob: true)
1972
+ delim = true
1940
1973
  op.delim
1941
1974
  .add_path(val)
1942
1975
  else
@@ -2103,7 +2136,8 @@ module Squared
2103
2136
  append_submodules(target: target, from: from)
2104
2137
  return if !remote && opts.empty?
2105
2138
 
2106
- op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, no: no)
2139
+ op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, strict: strict?,
2140
+ no: no)
2107
2141
  refspec = op.each_with_object([]) do |opt, out|
2108
2142
  if opt =~ op.values
2109
2143
  case $1
@@ -2161,11 +2195,11 @@ module Squared
2161
2195
  target << '--' << files.join(' ')
2162
2196
  true
2163
2197
  elsif expect
2164
- raise_error(if expect.is_a?(String)
2165
- expect
2166
- else
2167
- kwargs[:parent] ? 'pathspec not present' : 'pathspec not within worktree'
2168
- end)
2198
+ raise(if expect.is_a?(String)
2199
+ expect
2200
+ else
2201
+ kwargs[:parent] ? 'pathspec not present' : 'pathspec not within worktree'
2202
+ end)
2169
2203
  else
2170
2204
  false
2171
2205
  end
@@ -2222,7 +2256,7 @@ module Squared
2222
2256
  dir = worktree ? [quote_option('work-tree', path), quote_option('git-dir', gitpath)] : []
2223
2257
  return session('git', *dir, *cmd, **kwargs) unless opts
2224
2258
 
2225
- op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self)
2259
+ op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self, strict: strict?)
2226
2260
  [session('git', *op.to_a, *cmd, **kwargs), op.extras]
2227
2261
  end
2228
2262