squared 0.2.4 → 0.3.1

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.
@@ -72,23 +72,111 @@ module Squared
72
72
 
73
73
  module Project
74
74
  class Git < Base
75
- FOR_FETCH = %w[atomic multiple negotiate-only prefetch progress prune-tags refetch recurse-submodules=s].freeze
76
- NO_FETCH = %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
77
- FNO_FETCH = %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze
78
- OPT_FETCH = (FOR_FETCH + NO_FETCH + FNO_FETCH +
79
- %w[append dry-run force keep prune quiet set-upstream unshallow update-shallow verbose
80
- deepen=i depth=i jobs=i negotiation-tip=s refmap=s server-option=s shallow-exclude=s
81
- shallow-since=d upload-pack=s]).freeze
82
- NO_PULL = %w[allow-unrelated-histories autostash commit edit ff signoff squash stat verify verify-signatures
83
- gpg-sign=? log=? rebase=?].freeze
84
- OPT_PULL = (NO_PULL + %w[ff-only signoff=s strategy=s strategy-option=s]).freeze
85
- OPT_REBASE = %w[continue skip abort quit].freeze
86
- VAL_REBASE = %w[true false merges interactive].freeze
87
- NO_BRANCH = %w[abbrev=i color=? column=? track=?].freeze
88
- OPT_BRANCH = (NO_BRANCH + %w[all create-reflog ignore-case quiet remotes verbose
89
- contains=s format=s merged=s no-contains=s no-merged=s points-at=s sort=s]).freeze
90
- private_constant :FOR_FETCH, :NO_FETCH, :FNO_FETCH, :OPT_FETCH, :NO_PULL, :OPT_PULL, :OPT_REBASE, :VAL_REBASE,
91
- :NO_BRANCH, :OPT_BRANCH
75
+ OPT_GIT = {
76
+ branch: %w[a|all create-reflog i|ignore-case q|quiet r|remotes v|verbose abbrev=i color=b column=b
77
+ contains=e format=q merged=e no-contains=e no-merged=e points-at=e u|set-upstream-to=e sort=q
78
+ t|track=b].freeze,
79
+ checkout: %w[l d|detach f|force ignore-other-worktrees ignore-skip-worktree-bits m|merge p|patch
80
+ pathspec-file-nul q quiet orphan=e ours theirs conflict=b pathspec-from-file=p
81
+ t|track=b].freeze,
82
+ diff: {
83
+ base: %w[0 1|base 2|ours 3|theirs].freeze,
84
+ show: %w[s exit-code histogram].freeze
85
+ }.freeze,
86
+ fetch: {
87
+ base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok recurse-submodules=s
88
+ recurse-submodules-default=b].freeze,
89
+ pull: %w[4 6 n t a|append atomic dry-run f|force k|keep n|negotiate-only prefetch p|prune q|quiet
90
+ set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
91
+ refmap=q o|server-option=e shallow-exclude=e shallow-since=s upload-pack=e].freeze
92
+ }.freeze,
93
+ log: {
94
+ base: %w[all all-match alternate-refs author-date-order basic-regexp bisect boundary cherry cherry-mark
95
+ cherry-pick clear-decorations date-order dense do-walk exclude-first-parent-only E|extended-regexp
96
+ first-parent F|fixed-strings follow full-diff full-history ignore-missing invert-grep left-only
97
+ merge log-size no-max-parents no-min-parents not P|perl-regexp reflog i|regexp-ignore-case
98
+ remove-empty reverse right-only simplify-by-decoration simplify-merges single-worktree show-pulls
99
+ source sparse stdin topo-order g|walk-reflogs after=q ancestry-path=e? author=q before=q
100
+ branches=q? committer=q decorate=b decorate-refs=q decorate-refs-exclude=q exclude=q
101
+ exclude-hidden=b? glob=q grep=q grep-reflog=q L=q n|max-count=i max-parents=i min-parents=i
102
+ no-walk=b? remotes=q? since=q since-as-filter=q skip=i tags=q? until=q].freeze,
103
+ format: %w[t children combined-all-paths oneline left-right no-diff-merges parents relative-date
104
+ show-signature date=q diff-merges=b encoding=b expand-tabs=i format=q notes=q pretty=q?
105
+ show-linear-break=q?].freeze,
106
+ diff: %w[p R u z l=i G=q O=q S=q binary check compact-summary cumulative find-copies-harder full-index
107
+ W|function-context w|ignore-all-space ignore-blank-lines ignore-cr-at-eol ignore-space-at-eol
108
+ b|ignore-space-change D|irreversible-delete graph ita-invisible-in-index minimal name-only
109
+ name-status no-color-moved-ws no-prefix no-renames numstat patch-with-raw patch-with-stat patience
110
+ pickaxe-all pickaxe-regex raw shortstat summary a|text abbrev=i? anchored=q B|break-rewrites=e?
111
+ color=b color-moved=b color-moved-ws=b color-words=q? diff-algorithm=b diff-filter=e? X|dirstat=q?
112
+ dirstat-by-file=q? dst-prefix=q C|find-copies=i? find-object=e M|find-renames=i?
113
+ I|ignore-matching-lines=q ignore-submodules=b inter-hunk-context=i line-prefix=q output=p
114
+ output-indicator-context=q output-indicator-new=q output-indicator-old=q relative=p rotate-to=p
115
+ skip-to=p src-prefix=q stat=q? stat-width=i stat-name-width=i stat-count=i submodule=b? U|unified=i
116
+ word-diff=b? word-diff-regex=q ws-error-highligt=q].freeze
117
+ }.freeze,
118
+ ls_files: %w[z debug deduplicate directory eol error-unmatch exclude-standard full-name k|killed
119
+ no-empty-directory recurse-submodules sparse s|stage u|unmerged abbrev=i x|exclude=q
120
+ X|exclude-from=p exclude-per-directory=p format=q with-tree=q].freeze,
121
+ ls_remote: %w[exit-code get-url q|quiet o|server-option=e symref sort=q upload-pack=e].freeze,
122
+ pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=e log=i rebase=s s|strategy=b
123
+ X|strategy-option=e].freeze,
124
+ rebase: %w[n C=i allow-empty-message apply committer-date-is-author-date edit-todo f|force-rebase ignore-date
125
+ ignore-whitespace i|interactive keep-base m merge no-ff q|quiet quit r|rebase-merges=b?
126
+ reset-author-date root show-current-patch signoff v|verbose empty=b S|gpg-sign=b onto=e
127
+ s|strategy=b X|strategy-option=b whitespace=e].freeze,
128
+ reset: %w[N pathspec-file-nul q|quiet pathspec-from-file=p].freeze,
129
+ restore: %w[ignore-unmerged ignore-skip-worktree-bits m|merge ours p|patch pathspec-file-nul S|staged theirs
130
+ W|worktree conflict=b pathspec-from-file=p s|source=q].freeze,
131
+ rev_parse: {
132
+ output: %w[absolute-git-dir all flags git-common-dir git-dir is-bare-repository is-inside-git-dir
133
+ is-inside-work-tree is-shallow-repository local-env-vars no-flags no-revs not q|quiet sq
134
+ revs-only shared-index-path show-cdup show-prefix show-toplevel show-superproject-working-tree
135
+ sq-quote symbolic symbolic-full-name verify abbrev-ref=b? after=q before=q default=e
136
+ disambiguate=b exclude=q exclude-hidden=b glob=q git-path=p path-format=b? prefix=q branches=q?
137
+ remotes=q? resolve-git-dir=p short=i? show-object-format=b? since=q tags=q? until=q].freeze,
138
+ parseopt: %w[keep-dashdash stop-at-non-option stuck-long].freeze
139
+ }.freeze,
140
+ show: %w[t combined-all-paths no-diff-merges remerge-diff show-signature diff-merges=b encoding=b
141
+ expand-tabs=i notes=q show-notes=q?].freeze,
142
+ stash: {
143
+ common: %w[q|quiet].freeze,
144
+ push: %w[a|all u|include-untracked k|keep-index no-keep-index p|patch S|staged m|message=q
145
+ pathspec-from-file=p].freeze,
146
+ pop: %w[index].freeze,
147
+ apply: %w[index].freeze
148
+ }.freeze,
149
+ tag: %w[create-reflog column=b contains=e? format=q merged=e? n=i no-contains=e? no-merged=e? points-at=q
150
+ sort=q].freeze,
151
+ no: {
152
+ fetch: {
153
+ base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
154
+ pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
155
+ },
156
+ log: {
157
+ base: %w[decorate mailmap merges use-mailmap].freeze,
158
+ show: %w[abbrev-commit expand-tabs notes].freeze,
159
+ diff: %w[color color-moved ext-diff indent-heuristic patch relative rename-empty textconv].freeze
160
+ }.freeze,
161
+ pull: %w[autostash commit edit ff log signoff squash stat verify verify-signatures gpg-sign rebase].freeze,
162
+ tag: %w[column].freeze,
163
+ branch: %w[color-moved column color track].freeze,
164
+ checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
165
+ rebase: %w[autosquash autostash fork-point gpg-sign keep-empty reapply-cherry-picks reschedule-failed-exec
166
+ rerere-autoupdate stat update-refs verify].freeze,
167
+ reset: %w[refresh].freeze,
168
+ restore: %w[overlay progress recurse-submodules].freeze,
169
+ show: %w[standard-notes].freeze
170
+ }.freeze
171
+ }
172
+ VAL_GIT = {
173
+ rebase: {
174
+ send: %w[continue skip abort quit].freeze,
175
+ value: %w[true false merges interactive].freeze
176
+ }.freeze,
177
+ reset: %w[soft mixed hard merge keep recurse-submodules no-recurse-submodules].freeze
178
+ }
179
+ private_constant :OPT_GIT, :VAL_GIT
92
180
 
93
181
  class << self
94
182
  include Rake::DSL
@@ -134,21 +222,22 @@ module Squared
134
222
  end
135
223
 
136
224
  @@tasks[ref] = {
137
- 'checkout' => %i[branch track detach force merge].freeze,
138
- 'commit' => %i[add amend amend-orig all no-all].freeze,
139
- 'diff' => %i[head cached branch files between contain].freeze,
140
- 'pull' => %i[origin remote].freeze,
141
- 'fetch' => %i[origin remote].freeze,
142
- 'stash' => %i[push pop apply list clear].freeze,
143
- 'rebase' => %i[onto root send].freeze,
144
225
  'branch' => %i[create set delete move copy list edit current].freeze,
145
- 'refs' => %i[heads tags].freeze,
146
- 'files' => %i[cached modified deleted others].freeze,
147
- 'reset' => %i[head patch mode].freeze,
226
+ 'checkout' => %i[commit branch track detach path].freeze,
227
+ 'commit' => %i[add all amend amend-orig].freeze,
228
+ 'diff' => %i[head cached branch files view between contain].freeze,
229
+ 'fetch' => %i[origin remote].freeze,
230
+ 'files' => %i[cached modified deleted others ignored].freeze,
231
+ 'log' => %i[view between contain].freeze,
232
+ 'pull' => %i[origin remote].freeze,
233
+ 'rebase' => %i[branch onto send].freeze,
234
+ 'refs' => %i[heads tags remote].freeze,
235
+ 'reset' => %i[commit index patch mode].freeze,
148
236
  'restore' => %i[source worktree staged overlay].freeze,
149
- 'rev' => %i[commit branch].freeze,
237
+ 'rev' => %i[commit branch output parseopt].freeze,
150
238
  'show' => %i[format oneline].freeze,
151
- 'tag' => %i[add delete list merged].freeze
239
+ 'stash' => %i[push pop apply drop list].freeze,
240
+ 'tag' => %i[add delete list].freeze
152
241
  }.freeze
153
242
 
154
243
  def initialize(*, **)
@@ -173,93 +262,96 @@ module Squared
173
262
  case action
174
263
  when 'pull', 'fetch'
175
264
  if flag == :remote
176
- if @@task_desc
177
- format_desc(action, flag, ['refspec=s'] + (action == 'pull' ? OPT_PULL : OPT_FETCH),
178
- before: 'remote')
179
- end
265
+ format_desc(action, flag, 'remote,opts*')
180
266
  task flag, [:remote] do |_, args|
181
267
  remote = param_guard(action, flag, args: args, key: :remote)
182
- __send__(action, flag, remote: remote, opts: args.extras)
268
+ __send__(action, flag, args.extras, remote: remote)
183
269
  end
184
270
  else
185
- format_desc(action, flag, action == 'pull' ? OPT_PULL : OPT_FETCH)
271
+ format_desc action, flag, 'opts*'
186
272
  task flag do |_, args|
187
- __send__(action, flag, opts: args.to_a)
273
+ __send__ action, flag, args.to_a
188
274
  end
189
275
  end
190
- when 'commit', 'restore'
276
+ when 'commit'
191
277
  case flag
192
278
  when :all
193
279
  format_desc action, flag, 'message?'
194
280
  task flag, [:message] do |_, args|
195
281
  commit(flag, message: args.fetch(:message, nil))
196
282
  end
197
- when :source
198
- format_desc action, flag, 'tree,pathspec*'
283
+ else
284
+ format_desc action, flag, 'pathspec+'
285
+ task flag do |_, args|
286
+ refs = param_guard(action, flag, args: args.to_a)
287
+ commit(flag, refs: refs)
288
+ end
289
+ end
290
+ when 'restore'
291
+ if flag == :source
292
+ format_desc action, flag, 'tree,opts*,pathspec*'
199
293
  task flag, [:tree] do |_, args|
200
294
  tree = param_guard(action, flag, args: args, key: :tree)
201
295
  restore(flag, args.extras, tree: tree)
202
296
  end
203
297
  else
204
- format_desc action, flag, 'pathspec+'
298
+ format_desc action, flag, 'opts*,pathspec+'
205
299
  task flag do |_, args|
206
- files = param_guard(action, flag, args: args.to_a)
207
- __send__ action, flag, files
300
+ restore flag, args.to_a
208
301
  end
209
302
  end
210
303
  when 'tag'
211
304
  case flag
212
305
  when :list
213
- format_desc action, flag, 'pattern*'
306
+ format_desc action, flag, 'opts*,pattern*'
214
307
  task flag do |_, args|
215
308
  tag flag, args.to_a
216
309
  end
217
- when :merged
218
- format_desc action, flag, 'commit,pattern*'
219
- task flag, [:commit] do |_, args|
220
- commit = param_guard(action, flag, args: args, key: :commit)
221
- tag(flag, args.extras, commit: commit)
222
- end
223
310
  when :delete
224
311
  format_desc action, flag, 'name+'
225
312
  task flag do |_, args|
226
- name = param_guard(action, flag, args: args.to_a)
227
- tag flag, name
313
+ refs = param_guard(action, flag, args: args.to_a)
314
+ tag(flag, refs: refs)
228
315
  end
229
316
  when :add
230
317
  format_desc action, flag, 'name,message?,commit?'
231
318
  task flag, [:name, :message, :commit] do |_, args|
232
319
  name = param_guard(action, flag, args: args, key: :name)
233
- tag(flag, [name], message: args.message, commit: args.commit)
320
+ tag(flag, refs: [name], message: args.message, commit: args.commit)
234
321
  end
235
322
  end
236
323
  when 'stash'
237
- if flag == :push
238
- format_desc action, flag, 'pathspec*'
239
- task flag do |_, args|
240
- stash flag, args.to_a
241
- end
324
+ if flag == :list
325
+ format_desc action, flag
242
326
  else
243
- format_desc action, flag, 'commit?'
244
- task flag, [:commit] do |_, args|
245
- stash(flag, commit: args.commit)
246
- end
327
+ format_desc(action, flag, '*opts', after: flag == :push ? 'pathspec*' : 'commit?')
328
+ end
329
+ task flag do |_, args|
330
+ stash flag, args.to_a
247
331
  end
248
- when 'diff'
332
+ when 'log', 'diff'
249
333
  case flag
250
- when :head
251
- format_desc action, flag, 'index?=0,pathspec*'
252
- task flag do |_, args|
253
- files = args.to_a
254
- diff(flag, files, index: /\A\d+\z/.match?(files[0]) && !option('index') ? files.shift.to_i : 0)
334
+ when :view, :between, :contain
335
+ if flag == :view && action == 'log'
336
+ format_desc action, flag, '(^)commit*,pathspec*,opts*'
337
+ task flag do |_, args|
338
+ logx flag, args.to_a
339
+ end
340
+ else
341
+ format_desc action, flag, 'commit1,commit2,pathspec*,opts*'
342
+ task flag, [:commit1, :commit2] do |_, args|
343
+ commit1 = param_guard(action, flag, args: args, key: :commit1)
344
+ commit2 = param_guard(action, flag, args: args, key: :commit2)
345
+ __send__(action == 'log' ? :logx : :diff, flag, args.extras, range: [commit1, commit2])
346
+ end
255
347
  end
256
- when :cached
257
- format_desc action, flag, 'pathspec*'
348
+ when :head, :cached
349
+ format_desc action, flag, 'opts*,pathspec*'
258
350
  task flag do |_, args|
259
351
  diff flag, args.to_a
260
352
  end
261
353
  when :branch
262
- format_desc action, flag, 'name,pathspec*'
354
+ format_desc action, flag, 'name,opts*,pathspec*'
263
355
  task flag, [:name] do |_, args|
264
356
  branch = param_guard(action, flag, args: args, key: :name)
265
357
  diff(flag, args.extras, branch: branch)
@@ -269,14 +361,7 @@ module Squared
269
361
  task flag, [:path1, :path2] do |_, args|
270
362
  path1 = param_guard(action, flag, args: args, key: :path1)
271
363
  path2 = param_guard(action, flag, args: args, key: :path2)
272
- diff flag, [path1, path2]
273
- end
274
- else
275
- format_desc action, flag, 'commit1,commit2,pathspec*'
276
- task flag, [:commit1, :commit2] do |_, args|
277
- commit1 = param_guard(action, flag, args: args, key: :commit1)
278
- commit2 = param_guard(action, flag, args: args, key: :commit2)
279
- diff(flag, args.extras, range: [commit1, commit2])
364
+ diff(flag, refs: [path1, path2])
280
365
  end
281
366
  end
282
367
  when 'checkout'
@@ -310,13 +395,19 @@ module Squared
310
395
  origin = param_guard(action, flag, args: args, key: :origin)
311
396
  checkout(flag, branch: args.name, origin: origin)
312
397
  end
398
+ when :commit
399
+ format_desc action, flag, 'branch/commit,opts*'
400
+ task flag, [:commit] do |_, args|
401
+ commit = param_guard(action, flag, args: args, key: :commit)
402
+ checkout(flag, commit: commit)
403
+ end
313
404
  when :detach
314
405
  format_desc action, flag, 'branch/commit?'
315
406
  task flag, [:commit] do |_, args|
316
407
  checkout(flag, commit: args.commit)
317
408
  end
318
- else
319
- format_desc action, flag, 'pathspec*'
409
+ when :path
410
+ format_desc action, flag, 'opts*,pathspec*'
320
411
  task flag do |_, args|
321
412
  checkout flag, args.to_a
322
413
  end
@@ -326,11 +417,11 @@ module Squared
326
417
  when :create
327
418
  format_desc action, flag, 'name,ref?=HEAD'
328
419
  task flag, [:name, :ref] do |_, args|
329
- name = param_guard(action, flag, args: args, key: :name)
330
- branch(flag, target: name, ref: args.ref)
420
+ target = param_guard(action, flag, args: args, key: :name)
421
+ branch(flag, target: target, ref: args.ref)
331
422
  end
332
423
  when :set
333
- format_desc(action, flag, '(!)upstream,name?')
424
+ format_desc(action, flag, '(^)upstream,name?')
334
425
  task flag, [:upstream, :name] do |_, args|
335
426
  upstream = param_guard(action, flag, args: args, key: :upstream)
336
427
  branch(flag, target: args.name, ref: upstream)
@@ -338,8 +429,8 @@ module Squared
338
429
  when :delete
339
430
  format_desc action, flag, '(^~)name+'
340
431
  task flag, [:name] do |_, args|
341
- name = param_guard(action, flag, args: args.to_a)
342
- branch flag, name
432
+ refs = param_guard(action, flag, args: args.to_a)
433
+ branch(flag, refs: refs)
343
434
  end
344
435
  when :edit
345
436
  format_desc action, flag, 'name?'
@@ -347,9 +438,9 @@ module Squared
347
438
  branch(flag, target: args.name)
348
439
  end
349
440
  when :list
350
- format_desc(action, flag, OPT_BRANCH, before: 'pattern*')
441
+ format_desc action, flag, 'opts*,pattern*'
351
442
  task flag do |_, args|
352
- branch(flag, opts: args.to_a)
443
+ branch flag, args.to_a
353
444
  end
354
445
  when :current
355
446
  format_desc action, flag
@@ -357,74 +448,109 @@ module Squared
357
448
  branch flag
358
449
  end
359
450
  else
360
- format_desc action, flag, 'newbranch,oldbranch?'
361
- task flag, [:newbranch, :oldbranch] do |_, args|
362
- newbranch = param_guard(action, flag, args: args, key: :newbranch)
363
- branch flag, [args.oldbranch, newbranch]
451
+ format_desc action, flag, 'branch,oldbranch?'
452
+ task flag, [:branch, :oldbranch] do |_, args|
453
+ branch = param_guard(action, flag, args: args, key: :branch)
454
+ branch(flag, refs: [args.oldbranch, branch])
364
455
  end
365
456
  end
366
457
  when 'reset'
367
458
  case flag
368
- when :mode
369
- if @@task_desc
370
- format_desc(action, flag, %w[soft mixed hard merge keep {no-}submodules], after: 'ref?=HEAD',
371
- arg: false)
459
+ when :commit
460
+ format_desc action, flag, 'branch/commit,opts*'
461
+ task flag, [:commit] do |_, args|
462
+ commit = param_guard(action, flag, args: args, key: :commit)
463
+ reset(flag, args.extras, commit: commit)
372
464
  end
465
+ when :index
466
+ format_desc action, flag, 'opts*,pathspec*'
467
+ task flag do |_, args|
468
+ reset flag, args.to_a
469
+ end
470
+ when :mode
471
+ format_desc action, flag, 'mode,ref?=HEAD'
373
472
  task flag, [:mode, :ref] do |_, args|
374
473
  mode = param_guard(action, flag, args: args, key: :mode)
375
474
  reset(flag, mode: mode, ref: args.ref)
376
475
  end
377
- else
378
- format_desc action, flag, 'ref,pathspec+'
476
+ when :patch
477
+ format_desc action, flag, 'ref,pathspec*'
379
478
  task flag, [:ref] do |_, args|
380
- files = param_guard(action, flag, args: args.extras)
381
- reset(flag, files, ref: args.ref)
479
+ ref = param_guard(action, flag, args: args, key: :ref)
480
+ reset(flag, refs: args.extras, ref: ref)
382
481
  end
383
482
  end
384
483
  when 'show'
385
484
  case flag
386
485
  when :oneline
387
- format_desc action, flag, 'object*'
486
+ format_desc action, flag, 'opts*,object*'
388
487
  task flag do |_, args|
389
- show(args.to_a, format: 'oneline', opts: { 'abbrev-commit': true })
488
+ show 'oneline', args.to_a.push('abbrev-commit')
390
489
  end
391
490
  when :format
392
- format_desc action, flag, 'format?,object*'
491
+ format_desc action, flag, 'format?,opts*,object*'
393
492
  task flag, [:format] do |_, args|
394
- show(args.extras, format: args.format)
493
+ show args.format, args.extras
395
494
  end
396
495
  end
397
496
  when 'rebase'
398
497
  case flag
498
+ when :branch
499
+ format_desc action, flag, 'opts*,upstream?,branch?'
500
+ task flag do |_, args|
501
+ args = param_guard(action, flag, args: args.to_a)
502
+ rebase flag, args
503
+ end
399
504
  when :onto
400
- format_desc action, flag, 'commit,upstream,branch?=HEAD'
505
+ format_desc action, flag, 'branch/commit,upstream,branch?=HEAD'
401
506
  task flag, [:commit, :upstream, :branch] do |_, args|
402
507
  commit = param_guard(action, flag, args: args, key: :commit)
403
508
  upstream = param_guard(action, flag, args: args, key: :upstream)
404
509
  rebase(flag, commit: commit, upstream: upstream, branch: args.branch)
405
510
  end
406
- when :root
407
- format_desc action, flag, 'branch,onto?'
408
- task flag, [:branch, :onto] do |_, args|
409
- branch = param_guard(action, flag, args: args, key: :branch)
410
- rebase(flag, commit: args.onto, branch: branch)
411
- end
412
511
  when :send
413
- format_desc(action, flag, OPT_REBASE, arg: nil)
512
+ format_desc(action, flag, VAL_GIT[:rebase][:send], arg: nil)
414
513
  task flag, [:command] do |_, args|
415
514
  command = param_guard(action, flag, args: args, key: :command)
416
515
  rebase(flag, command: command)
417
516
  end
418
517
  end
419
518
  when 'rev'
420
- format_desc(action, flag, "ref?=HEAD#{flag == :commit ? ',size?' : ''}")
421
- task flag, [:ref, :size] do |_, args|
422
- rev_parse(flag, ref: args.ref, size: args.size)
519
+ case flag
520
+ when :commit
521
+ format_desc action, flag, 'ref?=HEAD,size?'
522
+ task flag, [:ref, :size] do |_, args|
523
+ ref = args.ref
524
+ size = args.size
525
+ if !size && ref.to_i > 0
526
+ size = ref
527
+ ref = nil
528
+ end
529
+ rev_parse(flag, ref: ref, size: size)
530
+ end
531
+ when :branch
532
+ format_desc action, flag, 'ref?=HEAD'
533
+ task flag, [:ref] do |_, args|
534
+ rev_parse(flag, ref: args.ref)
535
+ end
536
+ else
537
+ format_desc action, flag, 'opts*,args*'
538
+ task flag do |_, args|
539
+ rev_parse flag, args.to_a
540
+ end
423
541
  end
424
542
  when 'refs', 'files'
425
- format_desc action, flag, 'grep?=pattern'
426
- task flag, [:grep] do |_, args|
427
- __send__(action == 'refs' ? :ls_remote : :ls_files, flag, grep: args.fetch(:grep, nil))
543
+ if flag == :remote
544
+ format_desc action, flag, 'remote,opts*,pattern*'
545
+ task flag, [:remote] do |_, args|
546
+ remote = param_guard(action, flag, args: args, key: :remote)
547
+ ls_remote(flag, args.to_a.drop(1), remote: remote)
548
+ end
549
+ else
550
+ format_desc action, flag, 'opts*,pattern*'
551
+ task flag do |_, args|
552
+ __send__(action == 'refs' ? :ls_remote : :ls_files, flag, args.to_a)
553
+ end
428
554
  end
429
555
  end
430
556
  end
@@ -438,18 +564,18 @@ module Squared
438
564
  super
439
565
  end
440
566
 
441
- def pull(flag = nil, sync: invoked_sync?('pull', flag), remote: nil, opts: [])
567
+ def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
442
568
  cmd = git_session 'pull'
443
569
  if (val = option('rebase', ignore: false))
444
570
  cmd << case val
445
571
  when '0'
446
572
  '--no-rebase'
447
573
  else
448
- VAL_REBASE.include?(val) ? basic_option('rebase', val) : '--rebase'
574
+ VAL_GIT[:rebase][:value].include?(val) ? basic_option('rebase', val) : '--rebase'
449
575
  end
450
576
  end
451
- append_pull(opts, OPT_PULL + OPT_FETCH - (FOR_FETCH + FNO_FETCH), NO_PULL + NO_FETCH, remote: remote,
452
- flag: flag)
577
+ append_pull(opts, OPT_GIT[:pull] + OPT_GIT[:fetch][:pull],
578
+ no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag)
453
579
  source(sync: sync, sub: if verbose
454
580
  [
455
581
  { pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: :red, index: 4 },
@@ -458,39 +584,44 @@ module Squared
458
584
  end, **threadargs)
459
585
  end
460
586
 
461
- def rebase(flag = nil, sync: invoked_sync?('rebase', flag), command: nil, commit: nil, upstream: nil,
462
- branch: nil)
587
+ def rebase(flag = nil, opts = [], sync: invoked_sync?('rebase', flag), commit: nil, upstream: nil, branch: nil,
588
+ command: nil)
463
589
  return pull(:rebase, sync: sync) unless flag
464
590
 
465
591
  cmd = git_session 'rebase'
466
- cmd << '--interactive' unless flag == :send || !option('interactive', 'i')
467
592
  case flag
593
+ when :branch
594
+ branch = option_sanitize(opts, OPT_GIT[:rebase], no: OPT_GIT[:no][:rebase]).first
595
+ case branch.size
596
+ when 0
597
+ append_head
598
+ when 1, 2
599
+ append_value(branch, delim: true)
600
+ else
601
+ append_value([branch.pop, branch.pop].reverse, delim: true)
602
+ option_clear branch
603
+ end
468
604
  when :onto
469
605
  return unless upstream
470
606
 
471
- cmd << shell_option('onto', commit)
607
+ cmd << '--interactive' if option('interactive', 'i')
608
+ cmd << shell_option('onto', commit) if commit
472
609
  cmd << shell_escape(upstream)
473
610
  append_head branch
474
- when :root
475
- return unless branch
476
-
477
- cmd << shell_option('onto', commit) if commit
478
- cmd << '--root' << shell_escape(branch)
479
- when :send
480
- return unless OPT_REBASE.include?(command)
611
+ else
612
+ return unless VAL_GIT[:rebase][:send].include?(command)
481
613
 
482
614
  cmd << "--#{command}"
483
- else
484
- return
485
615
  end
486
616
  source
487
617
  end
488
618
 
489
- def fetch(flag = nil, sync: invoked_sync?('fetch', flag), remote: nil, opts: [])
619
+ def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
490
620
  cmd = git_session 'fetch'
491
621
  cmd << '--all' if !remote && !opts.include?('multiple') && option('all')
492
622
  cmd << '--verbose' if verbose && !opts.include?('quiet')
493
- append_pull(opts, OPT_FETCH, NO_FETCH + FNO_FETCH, remote: remote, flag: flag)
623
+ append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
624
+ remote: remote, flag: flag)
494
625
  source(sync: sync, **threadargs)
495
626
  end
496
627
 
@@ -511,30 +642,35 @@ module Squared
511
642
  opts[:local] = val != '0' if (val = option('local', strict: true))
512
643
  opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(:clone)
513
644
  append_hash opts
514
- if cmd.include?('--quiet') || cmd.include?('-q')
515
- quiet = true
516
- elsif verbose
517
- quiet = false
518
- else
519
- cmd << '--quiet'
520
- quiet = true
521
- end
522
- append_value([data[0], path], delim: true, escape: false)
523
- source(banner: sync && !quiet, multiple: !sync || quiet)
645
+ cmd << '--quiet' unless verbose
646
+ append_value(data[0], path, delim: true)
647
+ source(banner: sync && !quiet?, multiple: !sync || quiet?)
524
648
  end
525
649
 
526
- def stash(flag = nil, files = [], sync: invoked_sync?('stash', flag), commit: nil)
527
- cmd = git_session 'stash', flag || 'push'
528
- case flag
529
- when :apply, :pop
530
- cmd << '--index' if option('index')
531
- cmd << commit
650
+ def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
651
+ if flag
652
+ cmd = git_session 'stash', flag
653
+ list = OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, [])
654
+ refs = option_sanitize(opts, list).first
655
+ case flag
656
+ when :push
657
+ append_pathspec refs
658
+ when :pop, :apply, :drop
659
+ cmd << shell_quote(refs.pop)
660
+ option_clear refs
661
+ when :list
662
+ out, banner, from = source(io: true)
663
+ print_item banner
664
+ ret = write_lines(out)
665
+ list_result(ret, 'objects', from: from)
666
+ return
667
+ end
532
668
  else
533
- append_option %w[all staged include-untracked].freeze
669
+ git_session 'stash', 'push'
670
+ append_option(%w[all keep-index include-untracked staged].freeze, no: true, ignore: false)
534
671
  append_message option('message', 'm', ignore: false)
535
- append_pathspec files
536
672
  end
537
- source(sync: sync, **threadargs)
673
+ source(banner: !quiet?, sync: sync, **threadargs)
538
674
  end
539
675
 
540
676
  def status(*, sync: invoked_sync?('status'), **)
@@ -570,34 +706,41 @@ module Squared
570
706
  list_result(ret, 'files', from: from, action: 'modified')
571
707
  end
572
708
 
573
- def reset(flag, files = nil, mode: nil, ref: nil)
709
+ def reset(flag, opts = [], refs: nil, ref: nil, mode: nil, commit: nil)
574
710
  cmd = git_session 'reset'
575
711
  case flag
712
+ when :commit, :index
713
+ out = option_sanitize(opts, OPT_GIT[:reset] + VAL_GIT[:reset], no: OPT_GIT[:no][:reset]).first
714
+ if flag == :commit
715
+ append_value(commit, delim: true)
716
+ option_clear out
717
+ ref = false
718
+ else
719
+ (refs ||= []).concat(out)
720
+ end
576
721
  when :mode
577
- case mode
578
- when 'mixed'
579
- cmd << '--mixed'
722
+ return unless VAL_GIT[:reset].include?(mode)
723
+
724
+ cmd << "--#{mode}"
725
+ if mode == 'mixed'
580
726
  cmd << '-N' if option('n')
581
727
  cmd << '--no-refresh' if option('refresh', equals: '0')
582
- when 'soft', 'hard', 'merge', 'keep'
583
- cmd << "--#{mode}"
584
- when 'submodules'
585
- cmd << '--recurse-submodules'
586
- when 'no-submodules'
587
- cmd << '--no-recurse-submodules'
588
- else
589
- return
590
728
  end
591
729
  when :patch
592
730
  cmd << '--patch'
731
+ else
732
+ return
733
+ end
734
+ unless ref == false
735
+ append_commit ref
736
+ append_pathspec refs if refs
593
737
  end
594
- append_commit ref
595
- append_pathspec files if files
596
738
  source
597
739
  end
598
740
 
599
- def checkout(flag, files = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil)
741
+ def checkout(flag, opts = [], branch: nil, origin: nil, create: nil, commit: nil, detach: nil)
600
742
  cmd = git_session 'checkout'
743
+ append_option 'force', 'merge'
601
744
  case flag
602
745
  when :branch
603
746
  cmd << '--detach' if detach == 'd' || option('detach')
@@ -620,92 +763,122 @@ module Squared
620
763
  end
621
764
  cmd << '--track' << origin
622
765
  when :detach
623
- cmd << "--#{flag}" << commit
766
+ cmd << '--detach' << commit
624
767
  else
625
- cmd << "--#{flag}"
626
- append_first %w[ours theirs]
627
- append_head
628
- append_pathspec files
768
+ out = option_sanitize(opts, OPT_GIT[:checkout], no: OPT_GIT[:no][:checkout]).first
769
+ if flag == :commit
770
+ append_value(commit, delim: true)
771
+ option_clear out
772
+ else
773
+ append_head
774
+ append_pathspec out
775
+ end
629
776
  end
630
777
  source
631
778
  end
632
779
 
633
- def tag(flag, refs, message: nil, commit: nil)
780
+ def tag(flag, opts = [], refs: [], message: nil, commit: nil)
634
781
  cmd = git_session 'tag'
635
782
  case flag
636
783
  when :add
637
784
  if option('sign')
638
785
  cmd << '--sign'
639
- else
640
- out = cmd.to_s
641
- cmd << '--annotate' if %w[-s --sign -u --local-user].none? { |val| out.include?(" #{val}") }
786
+ elsif !session_arg?('s', 'sign', 'u', 'local-user')
787
+ cmd << '--annotate'
642
788
  end
643
789
  if !commit && message && (hash = commithash(message))
644
790
  commit = hash
645
791
  else
646
792
  append_message message
647
793
  end
648
- append_value(refs, escape: false)
794
+ append_value refs
649
795
  append_head commit
650
- when :delete, :list, :merged
796
+ when :list
797
+ cmd << '--list'
798
+ grep = option_sanitize(opts, OPT_GIT[:tag], no: OPT_GIT[:no][:tag]).first
799
+ out, banner, from = source(io: true)
800
+ print_item banner
801
+ ret = write_lines(out, grep: grep)
802
+ list_result(ret, 'tags', from: from, grep: grep)
803
+ return
804
+ when :delete
805
+ cmd << '--delete'
806
+ append_value refs
807
+ else
651
808
  cmd << shell_option(flag, commit)
652
- append_option(%w[contains sort] + (flag == :list ? ['merged'] : []), equals: true) unless flag == :delete
653
- append_value(refs, escape: false)
654
809
  end
655
810
  source
656
811
  end
657
812
 
658
- def diff(flag, files = [], branch: nil, index: 0, range: [])
813
+ def logx(flag, opts = [], range: [])
814
+ cmd = git_session 'log'
815
+ files = option_sanitize(opts, collect_hash(OPT_GIT[:log]), no: collect_hash(OPT_GIT[:no][:log])).first
816
+ case flag
817
+ when :between, :contain
818
+ cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
819
+ else
820
+ commit, files = files.partition do |val|
821
+ val.start_with?('^') || (!%r{^[.\\/]}.match?(val) && !%r{[\\/]$}.match?(val)) || commithash(val)
822
+ end
823
+ cmd.merge(commit.map { |val| commithash(val) || shell_quote(val) }) unless commit.empty?
824
+ end
825
+ append_nocolor
826
+ append_pathspec files
827
+ source(exception: false)
828
+ end
829
+
830
+ def diff(flag, opts = [], refs: [], branch: nil, range: [])
659
831
  cmd = git_session 'diff'
660
- sha = []
832
+ files = option_sanitize(opts, collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff],
833
+ no: OPT_GIT[:no][:log][:diff]).first
661
834
  case flag
662
- when :files, :between, :contain
835
+ when :files, :view, :between, :contain
663
836
  cmd.delete('--cached')
664
837
  else
665
838
  items = files.dup
839
+ sha = nil
666
840
  files.clear
667
841
  items.each do |val|
668
- if (hash = commithash(val))
669
- sha << hash
842
+ if (s = commithash(val))
843
+ (sha ||= []).push(s)
670
844
  else
671
845
  files << val
672
846
  end
673
847
  end
674
848
  end
675
- if (val = option('unified')).to_i > 0
676
- cmd << basic_option('unified', val)
677
- end
678
849
  append_nocolor
679
- case flag
680
- when :cached
681
- cmd << '--cached'
682
- cmd << '--merge-base' if option('merge-base')
683
- when :branch
684
- cmd << branch
685
- when :files
850
+ if flag == :files
686
851
  cmd << '--no-index'
687
- when :between, :contain
688
- cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
852
+ append_pathspec(refs, parent: true)
689
853
  else
690
- if (val = option('index')) || index > 0
691
- cmd << "HEAD~#{val || index}"
692
- elsif !sha.empty? && option('merge-base')
693
- cmd << '--merge-base'
694
- end
695
- end
696
- unless sha.empty?
697
- if cmd.include?('--cached')
698
- raise_error('diff', sha.join(', '), hint: 'one commit') if sha.size > 1
699
- cmd << sha.first
854
+ case flag
855
+ when :view
856
+ cmd << '--merge-base' if option('merge-base')
857
+ cmd << shell_quote(range.first, quote: true) << shell_quote(range.last, quote: true)
858
+ when :between, :contain
859
+ cmd.delete('--merge-base')
860
+ cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
700
861
  else
701
- cmd.merge(sha)
862
+ cmd << '--cached' if flag == :cached
863
+ cmd << '--merge-base' if option('merge-base')
864
+ cmd << shell_quote(branch) if branch
865
+ if sha
866
+ if session_arg?('cached')
867
+ raise_error('diff', sha.join(', '), hint: 'one commit') if sha.size > 1
868
+ cmd << sha.first
869
+ else
870
+ cmd.merge(sha)
871
+ end
872
+ elsif (n = option('index'))
873
+ cmd << "HEAD~#{n}"
874
+ end
702
875
  end
876
+ append_pathspec files
703
877
  end
704
- append_pathspec(files, parent: flag == :files)
705
- source(exception: cmd.include?('--exit-code'))
878
+ source(exception: session_arg?('exit-code'))
706
879
  end
707
880
 
708
- def commit(flag, files = [], message: nil, pass: false)
881
+ def commit(flag, *, refs: [], message: nil, pass: false)
709
882
  message ||= option('message', 'm', prefix: 'git', ignore: false)
710
883
  amend = flag.to_s.start_with?('amend')
711
884
  if !message && !amend
@@ -713,11 +886,12 @@ module Squared
713
886
 
714
887
  raise_error('commit', 'GIT_MESSAGE="description"', hint: 'missing')
715
888
  end
716
- pathspec = if flag == :all || (amend && files.size == 1 && files.first == '*')
889
+ pathspec = if flag == :all || (amend && refs.size == 1 && refs.first == '*')
717
890
  '--all'
891
+ elsif (refs = projectmap(refs)).empty?
892
+ raise_error('commit', 'pathspec', hint: 'missing')
718
893
  else
719
- raise_error('commit', 'pathspec', hint: 'missing') if (files = projectmap(files)).empty?
720
- "-- #{files.join(' ')}"
894
+ "-- #{refs.join(' ')}"
721
895
  end
722
896
  origin = nil
723
897
  branch = nil
@@ -727,22 +901,21 @@ module Squared
727
901
  next unless (data = /^\*\s(\S+)\s+(\h+)(?:\s\[(.+?)(?=\]\s)\])?\s/.match(val))
728
902
 
729
903
  branch = data[1]
730
- sha = data[2]
731
904
  if !data[3]
732
905
  unless (origin = option('repository', prefix: 'git', ignore: false))
733
906
  out = source(git_output('log -n1 --format=%h%d'), io: true, stdout: true, banner: false).first
734
- if (data = /^#{sha} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/.match(out))
735
- split_escape(data[1]).each do |val|
907
+ if out =~ /^#{data[2]} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/
908
+ split_escape($1).each do |val|
736
909
  next unless val.end_with?("/#{branch}")
737
910
 
738
- origin = val[0..val.size - branch.size - 2]
911
+ origin = val[0, val.size - branch.size - 1]
739
912
  break
740
913
  end
741
914
  end
742
915
  end
743
916
  upstream = true if origin
744
- elsif (data = Regexp.new("^(.+)/#{Regexp.escape(branch)}$").match(data[3]))
745
- origin = data[1]
917
+ elsif data[3] =~ %r{^(.+)/#{Regexp.escape(branch)}$}
918
+ origin = $1
746
919
  end
747
920
  break
748
921
  end
@@ -773,7 +946,7 @@ module Squared
773
946
  source b
774
947
  end
775
948
 
776
- def branch(flag, names = [], target: nil, ref: nil, opts: [])
949
+ def branch(flag, opts = [], refs: [], ref: nil, target: nil)
777
950
  cmd = git_session 'branch'
778
951
  stdout = false
779
952
  case flag
@@ -790,7 +963,9 @@ module Squared
790
963
  end
791
964
  cmd << '--force' if option('force')
792
965
  when :set
793
- if ref.start_with?('!')
966
+ return unless ref
967
+
968
+ if ref.start_with?('^')
794
969
  cmd << '--unset-upstream' << shell_escape(arg[1..-1])
795
970
  target = nil
796
971
  stdout = true
@@ -799,9 +974,9 @@ module Squared
799
974
  end
800
975
  ref = nil
801
976
  when :delete
802
- force, list = names.partition { |val| val =~ /^[\^~]/ }
977
+ force, list = refs.partition { |val| val =~ /^[\^~]/ }
803
978
  force.each do |val|
804
- dr = val[0..2]
979
+ dr = val[0, 3]
805
980
  d = dr.include?('^') ? '-D' : '-d'
806
981
  r = dr.include?('~') ? '-r' : nil
807
982
  source git_output('branch', d, r, shell_quote(val.sub(/^[\^~]+/, '')))
@@ -813,27 +988,18 @@ module Squared
813
988
  when :move, :copy
814
989
  flag = "-#{flag.to_s[0]}"
815
990
  cmd << (option('force') ? flag.upcase : flag)
816
- names.compact.each { |val| cmd << shell_quote(val) }
991
+ refs.compact.each { |val| cmd << shell_quote(val) }
817
992
  stdout = true
818
993
  when :edit
819
994
  cmd << '--edit-description'
820
995
  when :current
821
996
  cmd << '--show-current'
822
997
  else
823
- opts, pat = option_partition(opts, OPT_BRANCH, no: NO_BRANCH)
998
+ opts = option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch]).first
824
999
  grep = []
825
1000
  opts.each do |opt|
826
1001
  if opt =~ /^(v+)$/
827
1002
  cmd << "-#{$1}"
828
- elsif opt =~ pat
829
- case $1
830
- when 'column', 'format'
831
- cmd << quote_option($1, $2)
832
- when 'abbrev'
833
- cmd << basic_option($1, $2) if $2.to_i > 0
834
- else
835
- cmd << shell_option($1, $2)
836
- end
837
1003
  else
838
1004
  grep << opt
839
1005
  end
@@ -854,16 +1020,24 @@ module Squared
854
1020
  source(stdout: stdout)
855
1021
  end
856
1022
 
857
- def restore(flag, files, tree: nil)
858
- source = flag == :source
859
- cmd = git_session 'restore', source && files.empty? ? '--patch' : nil, shell_option(flag, tree)
860
- append_option %w[staged worktree]
861
- append_first %w[ours theirs]
862
- append_pathspec(files, expect: !cmd.include?('--patch'))
863
- source(stdout: !source)
1023
+ def restore(flag, opts = [], tree: nil)
1024
+ cmd = git_session 'restore'
1025
+ refs = option_sanitize(opts, OPT_GIT[:restore], no: OPT_GIT[:no][:restore]).first
1026
+ if flag == :source
1027
+ cmd << '--patch' if refs.empty?
1028
+ cmd << shell_option('source', tree)
1029
+ else
1030
+ cmd << "--#{flag}"
1031
+ end
1032
+ if session_arg?('p', 'patch')
1033
+ option_clear refs
1034
+ else
1035
+ append_pathspec(refs, expect: true)
1036
+ end
1037
+ source(sync: false, stderr: true)
864
1038
  end
865
1039
 
866
- def show(objs, format: nil, opts: nil)
1040
+ def show(format, opts = [])
867
1041
  cmd = git_session 'show'
868
1042
  if format
869
1043
  case (val = format.downcase)
@@ -873,41 +1047,54 @@ module Squared
873
1047
  if format =~ /^t?format:/ || format.include?('%')
874
1048
  cmd << quote_option('pretty', format)
875
1049
  else
876
- objs << format
1050
+ opts << format
877
1051
  end
878
1052
  end
879
1053
  end
880
- if opts
881
- append_hash opts
882
- banner = format != 'oneline'
883
- else
1054
+ refs = option_sanitize(opts, OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff],
1055
+ no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base])).first
1056
+ unless val == 'oneline' && session_arg?('abbrev-commit')
884
1057
  cmd << basic_option('abbrev', val) if (val = option('abbrev')) && val.to_i > 0
885
1058
  banner = true
886
1059
  end
887
- append_value(objs, delim: true)
1060
+ append_value(refs, delim: true)
888
1061
  source(exception: false, banner: banner)
889
1062
  end
890
1063
 
891
- def rev_parse(flag, ref: nil, size: nil)
892
- git_session 'rev-parse', if flag == :branch
893
- '--abbrev-ref'
894
- else
895
- (n = size.to_i) > 0 ? basic_option('short', [n, 5].max) : '--verify'
896
- end
897
- append_commit ref
898
- source
1064
+ def rev_parse(flag, opts = [], ref: nil, size: nil)
1065
+ cmd = git_session 'rev-parse', if flag == :parseopt
1066
+ '--parseopt'
1067
+ elsif opts.delete('sq-quote')
1068
+ '--sq-quote'
1069
+ end
1070
+ case flag
1071
+ when :commit
1072
+ cmd << ((n = size.to_i) > 0 ? basic_option('short', [n, 5].max) : '--verify')
1073
+ append_commit ref
1074
+ when :branch
1075
+ cmd << '--abbrev-ref'
1076
+ append_commit ref
1077
+ else
1078
+ args = option_sanitize(opts, OPT_GIT[:rev_parse][flag]).first
1079
+ append_value(args, escape: session_arg?('sq-quote'))
1080
+ end
1081
+ source(banner: verbose == 1)
899
1082
  end
900
1083
 
901
- def ls_remote(flag, grep: nil)
902
- git_session 'ls-remote', "--#{flag}", '--refs'
1084
+ def ls_remote(flag, opts = [], remote: nil)
1085
+ cmd = git_session 'ls-remote', '--refs'
1086
+ cmd << "--#{flag}" unless flag == :remote
1087
+ grep = option_sanitize(opts, OPT_GIT[:ls_remote]).first
1088
+ cmd << shell_quote(remote) if remote
903
1089
  out, banner, from = source(io: true)
904
1090
  print_item banner
905
1091
  ret = write_lines(out, grep: grep)
906
1092
  list_result(ret, flag.to_s, from: from, grep: grep)
907
1093
  end
908
1094
 
909
- def ls_files(flag, grep: nil)
1095
+ def ls_files(flag, opts = [])
910
1096
  git_session 'ls-files', "--#{flag}"
1097
+ grep = option_sanitize(opts, OPT_GIT[:ls_files]).first
911
1098
  out, banner, from = source(io: true)
912
1099
  print_item banner
913
1100
  ret = write_lines(out, grep: grep)
@@ -935,7 +1122,7 @@ module Squared
935
1122
  end
936
1123
  cmd = session_done(cmd)
937
1124
  log.info cmd
938
- on :first, from if from
1125
+ on :first, from
939
1126
  banner = if banner
940
1127
  format_banner((banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), ''), banner: true)
941
1128
  end
@@ -971,22 +1158,28 @@ module Squared
971
1158
  end
972
1159
  rescue StandardError => e
973
1160
  log.error e
974
- ret = on(:error, from, e) if from
1161
+ ret = on(:error, from, e)
975
1162
  raise if exception && ret != true
976
1163
 
977
1164
  warn log_message(Logger::WARN, e) if warning?
978
1165
  else
979
- on :last, from if from
1166
+ on :last, from
980
1167
  end
981
1168
  end
982
1169
 
983
1170
  def write_lines(data, banner: nil, loglevel: nil, grep: nil, sub: nil, pass: false)
984
- grep = Regexp.new(grep == '*' ? '.+' : grep) if grep.is_a?(String)
1171
+ grep = if grep && !grep.empty?
1172
+ as_a(grep).map do |val|
1173
+ next val if val.is_a?(Regexp)
1174
+
1175
+ Regexp.new(val == '*' ? '.+' : val.to_s)
1176
+ end
1177
+ end
985
1178
  sub = nil if stdin?
986
1179
  ret = 0
987
1180
  out = []
988
1181
  data.each do |line|
989
- next if grep && !line.match?(grep)
1182
+ next if grep&.none? { |pat| pat.match?(line) }
990
1183
 
991
1184
  if loglevel
992
1185
  log.add loglevel, line
@@ -1012,35 +1205,34 @@ module Squared
1012
1205
  puts print_footer("#{size} #{size == 1 ? type.sub(/s\z/, '') : type}",
1013
1206
  sub: { pat: /\A(\d+)(.+)\z/, styles: styles })
1014
1207
  else
1015
- puts empty_status("No #{type} were #{action}", 'grep', grep)
1208
+ puts empty_status("No #{type} were #{action}", 'grep', grep.is_a?(Array) ? case grep.size
1209
+ when 0
1210
+ nil
1211
+ else
1212
+ grep.join(', ')
1213
+ end : grep.to_s)
1016
1214
  end
1017
1215
  end
1018
- on :last, from if from
1216
+ on :last, from
1019
1217
  end
1020
1218
 
1021
- def append_pull(opts, list, no = [], target: @session, flag: nil, remote: nil)
1219
+ def append_pull(opts, list, target: @session, no: nil, flag: nil, remote: nil)
1022
1220
  cmd << '--force' if option('force')
1023
- modules = append_submodules(target: target)
1221
+ rsm = append_submodules(target: target)
1024
1222
  out = []
1025
1223
  refspec = []
1026
- opts, pat = option_partition(opts, remote ? list + ['refspec=s'] : list, target: target, no: no)
1224
+ opts, pat = option_sanitize(opts, remote ? list + ['refspec=s'] : list, target: target, no: no)
1027
1225
  opts.each do |opt|
1028
1226
  if opt =~ pat
1029
1227
  case $1
1030
1228
  when 'rebase'
1031
- target << basic_option($1, $2) if VAL_REBASE.include?($2)
1229
+ target << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
1032
1230
  when 'shallow-since'
1033
1231
  next unless (val = Date.parse($2))
1034
1232
 
1035
1233
  target << quote_option($1, val.strftime('%F %T'))
1036
1234
  when 'recurse-submodules'
1037
- target << basic_option($1, $2) unless modules
1038
- when 'shallow-exclude', 'gpg-sign', 'signoff', 'strategy', 'strategy-option'
1039
- target << shell_option($1, $2)
1040
- when 'refmap', 'negotiation-tip'
1041
- target << quote_option($1, $2)
1042
- when 'depth', 'deepen', 'log', 'jobs'
1043
- target << basic_option($1, $2) if $2.to_i > 0
1235
+ target << basic_option($1, $2) unless rsm
1044
1236
  when 'refspec'
1045
1237
  refspec << shell_escape($2, quote: true)
1046
1238
  end
@@ -1049,9 +1241,9 @@ module Squared
1049
1241
  end
1050
1242
  end
1051
1243
  if remote
1052
- append_value(remote, target: target, delim: true, quote: true)
1244
+ append_value(remote, target: target, delim: true)
1053
1245
  if (val = option('refspec', strict: true))
1054
- append_value(split_escape(val), target: target, escape: false)
1246
+ append_value(split_escape(val), target: target)
1055
1247
  else
1056
1248
  target.merge(refspec)
1057
1249
  end
@@ -1069,25 +1261,29 @@ module Squared
1069
1261
  end
1070
1262
 
1071
1263
  def append_pathspec(files = [], target: @session, expect: false, parent: false)
1072
- if files.empty? && (val = option('pathspec'))
1073
- files = split_escape(val)
1074
- end
1075
- files = projectmap(files, parent: parent)
1076
- if !files.empty?
1077
- target << "-- #{files.join(' ')}"
1078
- elsif expect
1079
- raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree', hint: 'invalid')
1264
+ if session_arg?('pathspec-from-file')
1265
+ option_clear files
1266
+ else
1267
+ if files.empty? && (val = option('pathspec'))
1268
+ files = split_escape(val)
1269
+ end
1270
+ files = projectmap(files, parent: parent)
1271
+ if !files.empty?
1272
+ target << "-- #{files.join(' ')}"
1273
+ elsif expect
1274
+ raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree', hint: 'invalid')
1275
+ end
1080
1276
  end
1081
1277
  end
1082
1278
 
1083
1279
  def append_message(val, target: @session)
1084
- target << "--message=\"#{double_quote(val)}\"" unless val.to_s.empty?
1280
+ target << quote_option('message', val) unless val.to_s.empty?
1085
1281
  end
1086
1282
 
1087
1283
  def append_head(val = nil, target: @session)
1088
1284
  return target << val if val
1089
1285
 
1090
- append_first(%w[head tree-ish object], target: target, flag: false, ignore: false)
1286
+ append_first('head', 'tree-ish', 'object', target: target, flag: false, ignore: false)
1091
1287
  end
1092
1288
 
1093
1289
  def append_submodules(from = nil, target: @session)
@@ -1119,8 +1315,14 @@ module Squared
1119
1315
  git_session(*cmd, main: false, options: false, **kwargs)
1120
1316
  end
1121
1317
 
1122
- def dryrun?(*)
1123
- !!@session&.include?('--dry-run')
1318
+ def dryrun?(*, target: @session, **)
1319
+ !!target&.include?('--dry-run')
1320
+ end
1321
+
1322
+ def quiet?(target: @session)
1323
+ return false unless target
1324
+
1325
+ target.include?('--quiet') || (target.include?('-q') && target.first == 'git')
1124
1326
  end
1125
1327
 
1126
1328
  def gitpath
@@ -1128,7 +1330,7 @@ module Squared
1128
1330
  end
1129
1331
 
1130
1332
  def commithash(val)
1131
- (data = /\A#\{(\h{5,40})\}\z/.match(val)) ? data[1] : nil
1333
+ val =~ /\A#\{(\h{5,40})\}\z/ ? $1 : nil
1132
1334
  end
1133
1335
 
1134
1336
  def threadargs