squared 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/README.ruby.md +52 -32
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/class.rb +20 -5
- data/lib/squared/common/format.rb +30 -22
- data/lib/squared/common/prompt.rb +39 -1
- data/lib/squared/common/shell.rb +14 -10
- data/lib/squared/common/system.rb +3 -3
- data/lib/squared/common/utils.rb +17 -10
- data/lib/squared/config.rb +1 -2
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +39 -23
- data/lib/squared/workspace/project/base.rb +242 -243
- data/lib/squared/workspace/project/docker.rb +119 -72
- data/lib/squared/workspace/project/git.rb +252 -214
- data/lib/squared/workspace/project/node.rb +65 -67
- data/lib/squared/workspace/project/python.rb +69 -57
- data/lib/squared/workspace/project/ruby.rb +297 -98
- data/lib/squared/workspace/project/support/class.rb +199 -0
- data/lib/squared/workspace/project/support.rb +3 -0
- data/lib/squared/workspace/project.rb +1 -0
- data/lib/squared/workspace/repo.rb +6 -8
- data/lib/squared/workspace/series.rb +7 -6
- data/lib/squared/workspace.rb +1 -8
- metadata +3 -1
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'date'
|
4
|
-
require 'time'
|
5
|
-
require 'digest'
|
6
|
-
|
7
3
|
module Squared
|
8
4
|
module Workspace
|
9
5
|
module Git
|
@@ -18,14 +14,14 @@ module Squared
|
|
18
14
|
check = ->(proj) { proj.is_a?(Project::Git) && !proj.exclude?(Project::Git.ref) && git_clone?(proj.path) }
|
19
15
|
if uri.is_a?(Array)
|
20
16
|
base = name
|
21
|
-
uri.each { |val| repo << proj if (proj = @project[val.to_s]) && check.(proj) }
|
17
|
+
uri.each { |val| repo << proj if (proj = @project[val.to_s]) && check.call(proj) }
|
22
18
|
elsif uri
|
23
19
|
data[name.to_s] = uri
|
24
20
|
elsif name.is_a?(Enumerable)
|
25
21
|
data = name.to_h
|
26
22
|
elsif name.is_a?(String) && name.match?(GIT_PROTO)
|
27
23
|
base = name
|
28
|
-
@project.each_value { |proj| repo << proj if !proj.parent && check.(proj) }
|
24
|
+
@project.each_value { |proj| repo << proj if !proj.parent && check.call(proj) }
|
29
25
|
else
|
30
26
|
warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid', pass: true) if warning
|
31
27
|
return self
|
@@ -141,7 +137,7 @@ module Squared
|
|
141
137
|
private
|
142
138
|
|
143
139
|
def rev_timenow
|
144
|
-
|
140
|
+
Time.now.utc.strftime('%s%L').to_i
|
145
141
|
end
|
146
142
|
end
|
147
143
|
Application.include Git
|
@@ -163,11 +159,12 @@ module Squared
|
|
163
159
|
show: %w[s exit-code histogram].freeze
|
164
160
|
}.freeze,
|
165
161
|
fetch: {
|
166
|
-
base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok
|
162
|
+
base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok
|
167
163
|
recurse-submodules-default=b].freeze,
|
168
164
|
pull: %w[4 6 n t a|append atomic dry-run f|force k|keep n|negotiate-only prefetch p|prune q|quiet
|
169
165
|
set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
|
170
|
-
refmap=q o|server-option=q shallow-exclude=e shallow-since=
|
166
|
+
recurse-submodules=v refmap=q o|server-option=q shallow-exclude=e shallow-since=v
|
167
|
+
upload-pack=q].freeze
|
171
168
|
}.freeze,
|
172
169
|
log: {
|
173
170
|
base: %w[all all-match alternate-refs author-date-order basic-regexp bisect boundary cherry cherry-mark
|
@@ -199,7 +196,7 @@ module Squared
|
|
199
196
|
X|exclude-from=p exclude-per-directory=p format=q with-tree=q].freeze,
|
200
197
|
ls_remote: %w[exit-code get-url q|quiet o|server-option=q symref sort=q upload-pack=q].freeze,
|
201
198
|
mv: %w[k f|force n|dry-run v|verbose].freeze,
|
202
|
-
pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=qq log=i r|rebase=
|
199
|
+
pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=qq log=i r|rebase=v? s|strategy=b
|
203
200
|
X|strategy-option=b].freeze,
|
204
201
|
merge: %w[e n allow-unrelated-histories ff-only m=q q|quiet v|verbose cleanup=b F|file=p S|gpg-sign=qq
|
205
202
|
into-name=e log=i s|strategy=b X|strategy-option=b].freeze,
|
@@ -300,7 +297,7 @@ module Squared
|
|
300
297
|
end
|
301
298
|
|
302
299
|
def tasks
|
303
|
-
%i[pull rebase fetch clone stash status branch revbuild].freeze
|
300
|
+
%i[pull rebase autostash fetch clone stash status branch revbuild].freeze
|
304
301
|
end
|
305
302
|
|
306
303
|
def config?(val)
|
@@ -328,7 +325,7 @@ module Squared
|
|
328
325
|
'rev' => %i[commit branch output parseopt build].freeze,
|
329
326
|
'show' => %i[format oneline textconv].freeze,
|
330
327
|
'stash' => %i[push pop apply drop clear list].freeze,
|
331
|
-
'tag' => %i[add delete list].freeze
|
328
|
+
'tag' => %i[add sign delete list].freeze
|
332
329
|
})
|
333
330
|
|
334
331
|
def initialize(*, **)
|
@@ -345,7 +342,7 @@ module Squared
|
|
345
342
|
return unless ref?(Git.ref)
|
346
343
|
|
347
344
|
namespace name do
|
348
|
-
|
345
|
+
Git.subtasks do |action, flags|
|
349
346
|
next if @pass.include?(action)
|
350
347
|
|
351
348
|
namespace action do
|
@@ -386,12 +383,14 @@ module Squared
|
|
386
383
|
tag flag, args.to_a
|
387
384
|
end
|
388
385
|
when :delete
|
389
|
-
format_desc action, flag, 'name
|
386
|
+
format_desc action, flag, 'name+?'
|
390
387
|
task flag do |_, args|
|
391
|
-
refs =
|
388
|
+
if (refs = args.to_a).empty?
|
389
|
+
refs = choice_refs('Choose a tag', 'tags', multiple: true, accept: 'Delete?')
|
390
|
+
end
|
392
391
|
tag(flag, refs: refs)
|
393
392
|
end
|
394
|
-
when :add
|
393
|
+
when :add, :sign
|
395
394
|
format_desc action, flag, 'name,message?,commit?'
|
396
395
|
task flag, [:name, :message, :commit] do |_, args|
|
397
396
|
name = param_guard(action, flag, args: args, key: :name)
|
@@ -411,7 +410,7 @@ module Squared
|
|
411
410
|
case flag
|
412
411
|
when :view, :between, :contain
|
413
412
|
if flag == :view && action == 'log'
|
414
|
-
format_desc action, flag, '(^)commit/H0*,pathspec
|
413
|
+
format_desc action, flag, '(^)commit/H0*,opts*,pathspec*'
|
415
414
|
task flag do |_, args|
|
416
415
|
index = []
|
417
416
|
args.to_a.each do |val|
|
@@ -419,18 +418,18 @@ module Squared
|
|
419
418
|
index << "HEAD~#{$1}"
|
420
419
|
elsif (sha = commithash(val))
|
421
420
|
index << sha
|
422
|
-
elsif val.start_with?('^')
|
421
|
+
elsif val.start_with?('^')
|
423
422
|
index << shell_quote(val)
|
424
423
|
end
|
425
424
|
end
|
426
|
-
|
425
|
+
log!(flag, args.to_a.drop(index.size), index: index)
|
427
426
|
end
|
428
427
|
else
|
429
|
-
format_desc action, flag, 'commit1,commit2,pathspec
|
428
|
+
format_desc action, flag, 'commit1,commit2,opts*,pathspec*'
|
430
429
|
task flag, [:commit1, :commit2] do |_, args|
|
431
430
|
commit1 = param_guard(action, flag, args: args, key: :commit1)
|
432
431
|
commit2 = param_guard(action, flag, args: args, key: :commit2)
|
433
|
-
__send__(action == 'log' ? :
|
432
|
+
__send__(action == 'log' ? :log! : :diff, flag, args.extras, range: [commit1, commit2])
|
434
433
|
end
|
435
434
|
end
|
436
435
|
when :head
|
@@ -461,33 +460,41 @@ module Squared
|
|
461
460
|
when 'checkout'
|
462
461
|
case flag
|
463
462
|
when :branch
|
464
|
-
format_desc action, flag, 'name
|
463
|
+
format_desc action, flag, 'name?,create?=[bB],commit?,detach?=d'
|
465
464
|
task flag, [:name, :create, :commit, :detach] do |_, args|
|
466
|
-
branch =
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
create
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
465
|
+
if (branch = args.name)
|
466
|
+
branch = param_guard(action, flag, args: args, key: :name)
|
467
|
+
create = args.create
|
468
|
+
if args.commit == 'd'
|
469
|
+
detach = 'd'
|
470
|
+
commit = nil
|
471
|
+
elsif create == 'd'
|
472
|
+
create = nil
|
473
|
+
commit = nil
|
474
|
+
detach = 'd'
|
475
|
+
elsif create && create.size > 1
|
476
|
+
commit = create
|
477
|
+
create = nil
|
478
|
+
detach = args.commit
|
479
|
+
else
|
480
|
+
detach = args.detach
|
481
|
+
commit = args.commit
|
482
|
+
end
|
483
|
+
param_guard(action, flag, args: { create: create }, key: :create, pat: /\Ab\z/i) if create
|
479
484
|
else
|
480
|
-
|
481
|
-
commit = args.commit
|
485
|
+
branch = choice_refs 'Choose a branch to switch', 'heads'
|
482
486
|
end
|
483
|
-
param_guard(action, flag, args: { create: create }, key: :create, pat: /\Ab\z/i) if create
|
484
487
|
checkout(flag, branch: branch, create: create, commit: commit, detach: detach)
|
485
488
|
end
|
486
489
|
when :track
|
487
|
-
format_desc action, flag, 'origin
|
490
|
+
format_desc action, flag, 'origin?,(^)name?'
|
488
491
|
task flag, [:origin, :name] do |_, args|
|
489
|
-
origin =
|
490
|
-
|
492
|
+
if (origin = args.origin)
|
493
|
+
branch = args.name
|
494
|
+
else
|
495
|
+
origin, branch = choice_refs('Choose a remote', 'remotes', values: ['Enter branch name'])
|
496
|
+
end
|
497
|
+
checkout(flag, branch: branch, origin: origin)
|
491
498
|
end
|
492
499
|
when :commit
|
493
500
|
format_desc action, flag, 'branch/commit,opts*'
|
@@ -515,15 +522,21 @@ module Squared
|
|
515
522
|
branch(flag, target: target, ref: args.ref)
|
516
523
|
end
|
517
524
|
when :set
|
518
|
-
format_desc(action, flag, '(^)upstream
|
525
|
+
format_desc(action, flag, '(^)upstream?,name?')
|
519
526
|
task flag, [:upstream, :name] do |_, args|
|
520
|
-
|
521
|
-
|
527
|
+
if (ref = args.upstream)
|
528
|
+
target = args.name
|
529
|
+
else
|
530
|
+
ref, target = choice_refs('Choose a remote', 'remotes', values: ['Enter branch name'])
|
531
|
+
end
|
532
|
+
branch(flag, target: target, ref: ref)
|
522
533
|
end
|
523
534
|
when :delete
|
524
|
-
format_desc action, flag, '(^~)name
|
535
|
+
format_desc action, flag, '(^~)name+?'
|
525
536
|
task flag do |_, args|
|
526
|
-
refs =
|
537
|
+
if (refs = args.to_a).empty?
|
538
|
+
refs = choice_refs('Choose a branch', 'heads', multiple: true, accept: 'Delete?')
|
539
|
+
end
|
527
540
|
branch(flag, refs: refs)
|
528
541
|
end
|
529
542
|
when :edit
|
@@ -699,16 +712,20 @@ module Squared
|
|
699
712
|
end
|
700
713
|
|
701
714
|
def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
|
702
|
-
cmd, opts = git_session('pull',
|
715
|
+
cmd, opts = git_session('pull', opts: opts)
|
703
716
|
if flag == :rebase
|
717
|
+
cmd << '--rebase'
|
704
718
|
cmd << '--autostash' if option('autostash')
|
705
|
-
|
706
|
-
cmd <<
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
719
|
+
else
|
720
|
+
cmd << '--autostash' if flag == :autostash
|
721
|
+
if (val = option('rebase', ignore: false))
|
722
|
+
cmd << case val
|
723
|
+
when '0', 'false'
|
724
|
+
'--no-rebase'
|
725
|
+
else
|
726
|
+
VAL_GIT[:rebase][:value].include?(val) ? basic_option('rebase', val) : '--rebase'
|
727
|
+
end
|
728
|
+
end
|
712
729
|
end
|
713
730
|
append_pull(opts, OPT_GIT[:pull] + OPT_GIT[:fetch][:pull],
|
714
731
|
no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag)
|
@@ -727,15 +744,15 @@ module Squared
|
|
727
744
|
cmd, opts = git_session('rebase', opts: opts)
|
728
745
|
case flag
|
729
746
|
when :branch
|
730
|
-
|
731
|
-
case
|
747
|
+
op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
|
748
|
+
case op.size
|
732
749
|
when 0
|
733
750
|
append_head
|
734
751
|
when 1, 2
|
735
|
-
|
752
|
+
op.append(delim: true)
|
736
753
|
else
|
737
|
-
|
738
|
-
|
754
|
+
op.append(op.pop(2), delim: true)
|
755
|
+
.clear(pass: false)
|
739
756
|
end
|
740
757
|
when :onto
|
741
758
|
return unless upstream
|
@@ -752,12 +769,16 @@ module Squared
|
|
752
769
|
source
|
753
770
|
end
|
754
771
|
|
772
|
+
def autostash(*, sync: invoked_sync?('autostash'), **)
|
773
|
+
pull(:autostash, sync: sync)
|
774
|
+
end
|
775
|
+
|
755
776
|
def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
|
756
777
|
cmd, opts = git_session('fetch', opts: opts)
|
757
|
-
append_pull(opts, collect_hash(OPT_GIT[:fetch]),
|
758
|
-
|
778
|
+
append_pull(opts, collect_hash(OPT_GIT[:fetch]),
|
779
|
+
no: collect_hash(OPT_GIT[:no][:fetch]), remote: remote, flag: flag)
|
759
780
|
cmd << '--all' if !remote && !session_arg?('multiple') && option('all')
|
760
|
-
cmd << '--verbose' if verbose && !session_arg('quiet')
|
781
|
+
cmd << '--verbose' if verbose && !session_arg?('quiet')
|
761
782
|
source(sync: sync, **threadargs)
|
762
783
|
end
|
763
784
|
|
@@ -786,25 +807,25 @@ module Squared
|
|
786
807
|
def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
|
787
808
|
if flag
|
788
809
|
cmd, opts = git_session('stash', flag, opts: opts)
|
789
|
-
|
810
|
+
op = OptionPartition.new(opts, OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, []), cmd,
|
811
|
+
project: self)
|
790
812
|
case flag
|
791
813
|
when :push
|
792
|
-
append_pathspec
|
814
|
+
append_pathspec op.extras
|
793
815
|
when :pop, :apply, :drop
|
794
|
-
unless
|
795
|
-
|
796
|
-
|
816
|
+
unless op.empty?
|
817
|
+
op << shell_escape(op.pop)
|
818
|
+
op.clear
|
797
819
|
end
|
798
820
|
when :clear
|
799
|
-
if confirm("Remove #{sub_style('all', styles: theme[:active])}
|
821
|
+
if confirm("Remove #{sub_style('all', styles: theme[:active])} stash entries? [y/N] ", 'N')
|
800
822
|
source(stdout: true)
|
801
823
|
end
|
802
824
|
return
|
803
825
|
when :list
|
804
826
|
out, banner, from = source(io: true)
|
805
827
|
print_item banner
|
806
|
-
|
807
|
-
list_result(ret, 'objects', from: from)
|
828
|
+
list_result(write_lines(out), 'objects', from: from)
|
808
829
|
return
|
809
830
|
end
|
810
831
|
else
|
@@ -855,22 +876,23 @@ module Squared
|
|
855
876
|
end
|
856
877
|
unless workspace.closed
|
857
878
|
if @revbuild
|
858
|
-
statusargs.
|
879
|
+
statusargs.call.each { |key, val| @revbuild[key] += val }
|
859
880
|
else
|
860
|
-
@revbuild = statusargs.
|
881
|
+
@revbuild = statusargs.call
|
861
882
|
end
|
862
883
|
return
|
863
884
|
end
|
864
|
-
sha = git_spawn('rev-parse --verify HEAD').
|
885
|
+
sha = git_spawn('rev-parse --verify HEAD').chomp
|
865
886
|
return if sha.empty?
|
866
887
|
|
867
|
-
|
868
|
-
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.() : @revbuild || {}
|
888
|
+
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.call : @revbuild || {}
|
869
889
|
case flag
|
870
890
|
when :build
|
871
|
-
|
872
|
-
|
891
|
+
op = OptionPartition.new(opts, OPT_GIT[:status], project: self)
|
892
|
+
op.clear(append: true)
|
893
|
+
args = op.to_a
|
873
894
|
else
|
895
|
+
args = []
|
874
896
|
args << basic_option('untracked-files', flag) if (flag = option('untracked-files', prefix: 'git'))
|
875
897
|
args << basic_option('ignore-submodules', flag) if (flag = option('ignore-submodules', prefix: 'git'))
|
876
898
|
args << basic_option('ignored', flag) if (flag = option('ignored', prefix: 'git'))
|
@@ -904,13 +926,14 @@ module Squared
|
|
904
926
|
cmd, opts = git_session('reset', opts: opts)
|
905
927
|
case flag
|
906
928
|
when :commit, :index
|
907
|
-
|
929
|
+
op = OptionPartition.new(opts, OPT_GIT[:reset] + VAL_GIT[:reset], cmd,
|
930
|
+
project: self, no: OPT_GIT[:no][:reset])
|
908
931
|
if flag == :commit
|
909
|
-
|
910
|
-
|
932
|
+
op.append(commit, delim: true)
|
933
|
+
.clear(pass: false)
|
911
934
|
ref = false
|
912
935
|
else
|
913
|
-
(refs ||= []).concat(
|
936
|
+
(refs ||= []).concat(op.extras)
|
914
937
|
end
|
915
938
|
when :mode
|
916
939
|
return unless VAL_GIT[:reset].include?(mode)
|
@@ -922,8 +945,6 @@ module Squared
|
|
922
945
|
end
|
923
946
|
when :patch
|
924
947
|
cmd << '--patch'
|
925
|
-
else
|
926
|
-
return
|
927
948
|
end
|
928
949
|
unless ref == false
|
929
950
|
append_commit(ref, head: true)
|
@@ -939,26 +960,26 @@ module Squared
|
|
939
960
|
when :branch
|
940
961
|
cmd << '--detach' if detach == 'd' || option('detach')
|
941
962
|
append_option('track', equals: true)
|
942
|
-
cmd << (create ?
|
963
|
+
cmd << (create ? quote_option(create, branch) : branch) << commit
|
943
964
|
when :track
|
944
965
|
if branch
|
945
966
|
if branch.start_with?('^')
|
946
967
|
opt = 'B'
|
947
968
|
branch = branch[1..-1]
|
948
969
|
end
|
949
|
-
cmd <<
|
970
|
+
cmd << quote_option(opt || 'b', branch)
|
950
971
|
end
|
951
|
-
cmd << '--track' << origin
|
972
|
+
cmd << '--track' << shell_quote(origin)
|
952
973
|
when :detach
|
953
974
|
cmd << '--detach' << commit
|
954
975
|
else
|
955
|
-
|
976
|
+
op = OptionPartition.new(opts, OPT_GIT[:checkout], cmd, project: self, no: OPT_GIT[:no][:checkout])
|
956
977
|
if flag == :commit
|
957
|
-
|
958
|
-
|
978
|
+
op.append(commit, delim: true)
|
979
|
+
.clear(pass: false)
|
959
980
|
else
|
960
981
|
append_head
|
961
|
-
append_pathspec
|
982
|
+
append_pathspec op.extras
|
962
983
|
end
|
963
984
|
end
|
964
985
|
source
|
@@ -967,12 +988,13 @@ module Squared
|
|
967
988
|
def tag(flag, opts = [], refs: [], message: nil, commit: nil)
|
968
989
|
cmd, opts = git_session('tag', opts: opts)
|
969
990
|
case flag
|
970
|
-
when :add
|
971
|
-
if option('sign')
|
991
|
+
when :add, :sign
|
992
|
+
if flag == :sign || option('sign')
|
972
993
|
cmd << '--sign'
|
973
994
|
elsif !session_arg?('s', 'sign', 'u', 'local-user')
|
974
995
|
cmd << '--annotate'
|
975
996
|
end
|
997
|
+
cmd << '--force' if option('force')
|
976
998
|
if !commit && message && (sha = commithash(message))
|
977
999
|
commit = sha
|
978
1000
|
else
|
@@ -981,12 +1003,11 @@ module Squared
|
|
981
1003
|
append_value refs
|
982
1004
|
append_head commit
|
983
1005
|
when :list
|
984
|
-
cmd << '--list'
|
985
|
-
grep = option_sanitize(opts, OPT_GIT[:tag], no: OPT_GIT[:no][:tag]).first
|
1006
|
+
op = OptionPartition.new(opts, OPT_GIT[:tag], cmd << '--list', project: self, no: OPT_GIT[:no][:tag])
|
986
1007
|
out, banner, from = source(io: true)
|
987
1008
|
print_item banner
|
988
|
-
ret = write_lines(out, grep:
|
989
|
-
list_result(ret, 'tags', from: from, grep:
|
1009
|
+
ret = write_lines(out, grep: op.extras)
|
1010
|
+
list_result(ret, 'tags', from: from, grep: op.extras)
|
990
1011
|
return
|
991
1012
|
when :delete
|
992
1013
|
cmd << '--delete'
|
@@ -997,57 +1018,58 @@ module Squared
|
|
997
1018
|
source
|
998
1019
|
end
|
999
1020
|
|
1000
|
-
def
|
1021
|
+
def log!(flag, opts = [], range: [], index: [])
|
1001
1022
|
cmd, opts = git_session('log', opts: opts)
|
1002
|
-
|
1023
|
+
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
|
1024
|
+
project: self, no: collect_hash(OPT_GIT[:no][:log]))
|
1003
1025
|
case flag
|
1004
1026
|
when :between, :contain
|
1005
|
-
|
1027
|
+
op << shell_quote(range.join(flag == :between ? '..' : '...'))
|
1006
1028
|
else
|
1007
|
-
|
1029
|
+
op.merge(index)
|
1008
1030
|
end
|
1009
1031
|
append_nocolor
|
1010
|
-
append_pathspec
|
1032
|
+
append_pathspec op.extras
|
1011
1033
|
source(exception: false)
|
1012
1034
|
end
|
1013
1035
|
|
1014
1036
|
def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [])
|
1015
1037
|
cmd, opts = git_session('diff', opts: opts)
|
1016
|
-
|
1017
|
-
|
1038
|
+
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff], cmd,
|
1039
|
+
project: self, no: OPT_GIT[:no][:log][:diff])
|
1018
1040
|
case flag
|
1019
1041
|
when :files, :view, :between, :contain
|
1020
|
-
|
1042
|
+
op.delete('--cached')
|
1021
1043
|
end
|
1022
1044
|
append_nocolor
|
1023
1045
|
if flag == :files
|
1024
|
-
|
1046
|
+
op << '--no-index'
|
1025
1047
|
append_pathspec(refs, parent: true)
|
1026
1048
|
else
|
1027
1049
|
case flag
|
1028
1050
|
when :view
|
1029
|
-
|
1030
|
-
|
1051
|
+
op << '--merge-base' if option('merge-base')
|
1052
|
+
op << shell_quote(range.first, quote: true) << shell_quote(range.last, quote: true)
|
1031
1053
|
when :between, :contain
|
1032
|
-
|
1033
|
-
|
1054
|
+
op.delete('--merge-base')
|
1055
|
+
op << shell_quote(range.join(flag == :between ? '..' : '...'))
|
1034
1056
|
else
|
1035
|
-
|
1036
|
-
|
1057
|
+
op << '--merge-base' if option('merge-base')
|
1058
|
+
op << shell_quote(branch) if branch
|
1037
1059
|
if !index.empty?
|
1038
|
-
if
|
1060
|
+
if op.arg?('cached')
|
1039
1061
|
raise_error("one commit only: #{index.join(', ')}", hint: '--cached') if index.size > 1
|
1040
|
-
|
1062
|
+
op << index.first
|
1041
1063
|
else
|
1042
|
-
|
1064
|
+
op.merge(index)
|
1043
1065
|
end
|
1044
1066
|
elsif (n = option('index', ignore: false))
|
1045
|
-
|
1067
|
+
op << "HEAD~#{n}"
|
1046
1068
|
end
|
1047
1069
|
end
|
1048
|
-
append_pathspec
|
1070
|
+
append_pathspec op.extras
|
1049
1071
|
end
|
1050
|
-
source(exception:
|
1072
|
+
source(exception: op.arg?('exit-code'))
|
1051
1073
|
end
|
1052
1074
|
|
1053
1075
|
def commit(flag, *, refs: [], message: nil, pass: false)
|
@@ -1069,7 +1091,7 @@ module Squared
|
|
1069
1091
|
branch = nil
|
1070
1092
|
upstream = nil
|
1071
1093
|
git_spawn 'fetch --no-tags --quiet'
|
1072
|
-
git_spawn('branch -vv --list', stdout: false).
|
1094
|
+
git_spawn('branch -vv --list', stdout: false).each do |val|
|
1073
1095
|
next unless (r = /^\*\s(\S+)\s+(\h+)(?:\s\[(.+?)(?=\]\s)\])?\s/.match(val))
|
1074
1096
|
|
1075
1097
|
branch = r[1]
|
@@ -1077,7 +1099,7 @@ module Squared
|
|
1077
1099
|
origin = r[3][%r{^(.+)/#{Regexp.escape(branch)}$}, 1]
|
1078
1100
|
else
|
1079
1101
|
unless (origin = option('repository', prefix: 'git', ignore: false))
|
1080
|
-
out = git_spawn
|
1102
|
+
out = git_spawn 'log -n1 --format=%h%d'
|
1081
1103
|
if out =~ /^#{r[2]} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/
|
1082
1104
|
split_escape($1).each do |s|
|
1083
1105
|
next unless s.end_with?("/#{branch}")
|
@@ -1122,10 +1144,10 @@ module Squared
|
|
1122
1144
|
cmd, opts = git_session('merge', opts: opts)
|
1123
1145
|
case flag
|
1124
1146
|
when :commit, :'no-commit'
|
1125
|
-
|
1126
|
-
raise_error 'no branch/commit' if
|
1127
|
-
|
1128
|
-
append_commit(*
|
1147
|
+
op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
|
1148
|
+
raise_error 'no branch/commit' if op.empty?
|
1149
|
+
op << "--#{flag}" << '--'
|
1150
|
+
append_commit(*op.extras)
|
1129
1151
|
else
|
1130
1152
|
return unless VAL_GIT[:merge][:send].include?(command)
|
1131
1153
|
|
@@ -1141,7 +1163,7 @@ module Squared
|
|
1141
1163
|
when :create
|
1142
1164
|
if (arg = option('track', ignore: false))
|
1143
1165
|
cmd << case arg
|
1144
|
-
when '0'
|
1166
|
+
when '0', 'false'
|
1145
1167
|
'--no-track'
|
1146
1168
|
when 'direct', 'inherit'
|
1147
1169
|
basic_option('track', arg)
|
@@ -1162,17 +1184,17 @@ module Squared
|
|
1162
1184
|
end
|
1163
1185
|
ref = nil
|
1164
1186
|
when :delete
|
1165
|
-
force, list = refs.partition { |val| val.match?(/^[
|
1187
|
+
force, list = refs.partition { |val| val.match?(/^[~^]/) }
|
1166
1188
|
force.each do |val|
|
1167
1189
|
dr = val[0, 3]
|
1168
1190
|
d = dr.include?('^') ? '-D' : '-d'
|
1169
|
-
r = dr.include?('~')
|
1191
|
+
r = '-r' if dr.include?('~')
|
1170
1192
|
source git_output('branch', d, r, shell_quote(val.sub(/^[\^~]+/, '')))
|
1171
1193
|
end
|
1172
1194
|
return if list.empty?
|
1173
1195
|
|
1174
1196
|
cmd << '-d'
|
1175
|
-
list
|
1197
|
+
append_value list
|
1176
1198
|
when :move, :copy
|
1177
1199
|
flag = "-#{flag.to_s[0]}"
|
1178
1200
|
cmd << (option('force') ? flag.upcase : flag)
|
@@ -1182,20 +1204,22 @@ module Squared
|
|
1182
1204
|
cmd << '--edit-description'
|
1183
1205
|
when :current
|
1184
1206
|
cmd << '--show-current'
|
1207
|
+
source(banner: verbosetype > 1, stdout: true)
|
1208
|
+
return
|
1185
1209
|
when :list
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1210
|
+
op = OptionPartition.new(opts, OPT_GIT[:branch], cmd << '--list',
|
1211
|
+
project: self, no: OPT_GIT[:no][:branch], single: /^v+$/)
|
1212
|
+
op.each { |val| op << shell_quote(val) }
|
1189
1213
|
out, banner, from = source(io: true)
|
1190
1214
|
print_item banner
|
1191
1215
|
ret = write_lines(out, sub: [
|
1192
|
-
{ pat: /^(\*\s+)(\S+)(
|
1216
|
+
{ pat: /^(\*\s+)(\S+)(.*)$/, styles: color(:green), index: 2 },
|
1193
1217
|
{ pat: %r{^(\s*)(remotes/\S+)(.*)$}, styles: color(:red), index: 2 }
|
1194
1218
|
])
|
1195
1219
|
list_result(ret, 'branches', from: from)
|
1196
1220
|
return
|
1197
1221
|
else
|
1198
|
-
head = git_spawn('rev-parse --abbrev-ref HEAD').
|
1222
|
+
head = git_spawn('rev-parse --abbrev-ref HEAD').chomp
|
1199
1223
|
if head.empty?
|
1200
1224
|
ret = 0
|
1201
1225
|
else
|
@@ -1211,8 +1235,8 @@ module Squared
|
|
1211
1235
|
if (r1 = r[1]) && r1 =~ /^(.+):(?: ([a-z]+) (\d+),)? ([a-z]+) (\d+)$/
|
1212
1236
|
write = ->(s1, s2) { "#{s1.capitalize.rjust(7)}: #{sub_style(s2, styles: theme[:warn])}" }
|
1213
1237
|
r1 = $1
|
1214
|
-
r2 = $2 && write.($2, $3)
|
1215
|
-
r3 = write.($4, $5)
|
1238
|
+
r2 = $2 && write.call($2, $3)
|
1239
|
+
r3 = write.call($4, $5)
|
1216
1240
|
end
|
1217
1241
|
r1 = nil if r1 == "origin/#{data[0]}"
|
1218
1242
|
[" Branch: #{a + (r1 ? " (#{r1})" : '')}", r2, r3, " Commit: #{b}", "Message: #{r[2]}"]
|
@@ -1232,9 +1256,9 @@ module Squared
|
|
1232
1256
|
end
|
1233
1257
|
|
1234
1258
|
def restore(flag, opts = [])
|
1235
|
-
opts = git_session('restore', "--#{flag}", opts: opts)
|
1236
|
-
|
1237
|
-
append_pathspec(
|
1259
|
+
cmd, opts = git_session('restore', "--#{flag}", opts: opts)
|
1260
|
+
op = OptionPartition.new(opts, OPT_GIT[:restore], cmd, project: self, no: OPT_GIT[:no][:restore])
|
1261
|
+
append_pathspec(op.extras, pass: false)
|
1238
1262
|
source(sync: false, stderr: true)
|
1239
1263
|
end
|
1240
1264
|
|
@@ -1264,13 +1288,14 @@ module Squared
|
|
1264
1288
|
end
|
1265
1289
|
end
|
1266
1290
|
end
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1291
|
+
op = OptionPartition.new(opts, OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff], cmd,
|
1292
|
+
project: self,
|
1293
|
+
no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
|
1294
|
+
unless val == 'oneline' && op.arg?('abbrev-commit')
|
1295
|
+
op << basic_option('abbrev', val) if (val = option('abbrev')) && val.to_i > 0
|
1271
1296
|
banner = true
|
1272
1297
|
end
|
1273
|
-
|
1298
|
+
op.append(delim: true)
|
1274
1299
|
source(exception: false, banner: banner)
|
1275
1300
|
end
|
1276
1301
|
|
@@ -1289,60 +1314,60 @@ module Squared
|
|
1289
1314
|
cmd << '--abbrev-ref'
|
1290
1315
|
append_commit(ref, head: true)
|
1291
1316
|
else
|
1292
|
-
|
1293
|
-
|
1317
|
+
op = OptionPartition.new(opts, OPT_GIT[:rev_parse][flag], cmd, project: self)
|
1318
|
+
op.append(escape: op.arg?('sq-quote'))
|
1294
1319
|
end
|
1295
|
-
source(banner:
|
1320
|
+
source(banner: verbosetype > 1)
|
1296
1321
|
end
|
1297
1322
|
|
1298
1323
|
def ls_remote(flag, opts = [], remote: nil)
|
1299
1324
|
cmd, opts = git_session('ls-remote', '--refs', opts: opts)
|
1300
1325
|
cmd << "--#{flag}" unless flag == :remote
|
1301
|
-
|
1302
|
-
|
1326
|
+
op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self)
|
1327
|
+
op << shell_quote(remote) if remote
|
1303
1328
|
out, banner, from = source(io: true)
|
1304
1329
|
print_item banner
|
1305
|
-
ret = write_lines(out, grep:
|
1306
|
-
list_result(ret, flag.to_s, from: from, grep:
|
1330
|
+
ret = write_lines(out, grep: op.extras)
|
1331
|
+
list_result(ret, flag.to_s, from: from, grep: op.extras)
|
1307
1332
|
end
|
1308
1333
|
|
1309
1334
|
def ls_files(flag, opts = [])
|
1310
|
-
opts = git_session('ls-files', "--#{flag}", opts: opts)
|
1311
|
-
|
1335
|
+
cmd, opts = git_session('ls-files', "--#{flag}", opts: opts)
|
1336
|
+
op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self)
|
1312
1337
|
out, banner, from = source(io: true)
|
1313
1338
|
print_item banner
|
1314
|
-
ret = write_lines(out, grep:
|
1315
|
-
list_result(ret, 'files', from: from, grep:
|
1339
|
+
ret = write_lines(out, grep: op.extras)
|
1340
|
+
list_result(ret, 'files', from: from, grep: op.extras)
|
1316
1341
|
end
|
1317
1342
|
|
1318
1343
|
def git(flag, opts = [])
|
1319
1344
|
cmd, opts = git_session(flag, opts: opts)
|
1320
|
-
|
1345
|
+
op = OptionPartition.new(opts, OPT_GIT[flag], cmd, project: self, no: OPT_GIT[:no][flag])
|
1321
1346
|
sync = false
|
1322
1347
|
stderr = true
|
1323
1348
|
case flag
|
1324
1349
|
when :clean
|
1325
|
-
refs = projectmap(
|
1350
|
+
refs = projectmap(op.extras)
|
1326
1351
|
unless refs.empty?
|
1327
|
-
|
1328
|
-
|
1352
|
+
op << '--'
|
1353
|
+
op.merge(refs)
|
1329
1354
|
end
|
1330
1355
|
sync = true
|
1331
1356
|
stderr = false
|
1332
1357
|
when :revert
|
1333
|
-
if VAL_GIT[:rebase][:send].any? { |val|
|
1334
|
-
|
1335
|
-
elsif
|
1358
|
+
if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
|
1359
|
+
op.clear
|
1360
|
+
elsif op.empty?
|
1336
1361
|
raise_error 'no commit given'
|
1337
1362
|
else
|
1338
|
-
append_commit(*
|
1363
|
+
append_commit(*op.extras)
|
1339
1364
|
end
|
1340
1365
|
when :mv
|
1341
|
-
refs = projectmap(
|
1366
|
+
refs = projectmap(op.extras)
|
1342
1367
|
raise_error 'no source/destination' unless refs.size > 1
|
1343
|
-
|
1368
|
+
op.merge(refs)
|
1344
1369
|
when :rm
|
1345
|
-
append_pathspec(
|
1370
|
+
append_pathspec(op.extras, expect: true)
|
1346
1371
|
end
|
1347
1372
|
source(sync: sync, stderr: stderr)
|
1348
1373
|
end
|
@@ -1379,8 +1404,11 @@ module Squared
|
|
1379
1404
|
format_banner((banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), ''), banner: true)
|
1380
1405
|
end
|
1381
1406
|
begin
|
1382
|
-
|
1407
|
+
if io
|
1408
|
+
return `#{cmd}` if stdout
|
1383
1409
|
|
1410
|
+
return banner ? [IO.popen(cmd), banner, from] : IO.popen(cmd)
|
1411
|
+
end
|
1384
1412
|
if stdin? ? sync : stdout
|
1385
1413
|
print_item banner unless multiple
|
1386
1414
|
ret = `#{cmd}`
|
@@ -1469,19 +1497,35 @@ module Squared
|
|
1469
1497
|
on :last, from
|
1470
1498
|
end
|
1471
1499
|
|
1472
|
-
def
|
1500
|
+
def choice_refs(msg, type, format: nil, sort: '-creatordate', count: ARG[:CHOICE], short: true, **kwargs)
|
1501
|
+
unless format
|
1502
|
+
format = +"%(refname#{short ? ':short' : ''})"
|
1503
|
+
case type
|
1504
|
+
when 'heads', 'tags'
|
1505
|
+
format += '%(if)%(HEAD)%(then) *%(end)'
|
1506
|
+
trim = /\s+\*\z/
|
1507
|
+
end
|
1508
|
+
end
|
1509
|
+
cmd = git_output 'for-each-ref', quote_option('format', format)
|
1510
|
+
cmd << quote_option('sort', sort) if sort
|
1511
|
+
cmd << shell_option('count', count) if count
|
1512
|
+
cmd << "refs/#{type}"
|
1513
|
+
choice_index(msg, source(cmd, io: true, banner: false), trim: trim, **kwargs)
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
def status_digest(*args, algorithm: nil, **kwargs)
|
1517
|
+
require 'digest'
|
1518
|
+
algorithm ||= Digest::SHA256
|
1473
1519
|
glob = kwargs.fetch(:include, [])
|
1474
1520
|
pass = kwargs.fetch(:exclude, [])
|
1475
1521
|
ret = {}
|
1476
|
-
git_spawn('status -s --porcelain', *args, stdout: false)
|
1477
|
-
|
1478
|
-
.
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
ret[file] = algorithm.hexdigest(File.read(basepath(file)))
|
1484
|
-
end
|
1522
|
+
git_spawn('status -s --porcelain', *args, stdout: false).each do |line|
|
1523
|
+
next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
|
1524
|
+
next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1525
|
+
next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
|
1526
|
+
|
1527
|
+
ret[file] = algorithm.hexdigest(File.read(basepath(file)))
|
1528
|
+
end
|
1485
1529
|
ret
|
1486
1530
|
end
|
1487
1531
|
|
@@ -1489,43 +1533,46 @@ module Squared
|
|
1489
1533
|
source(git_output(*cmd), io: true, banner: false, stdout: stdout)
|
1490
1534
|
end
|
1491
1535
|
|
1492
|
-
def append_pull(opts, list, target: @session,
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1536
|
+
def append_pull(opts, list, target: @session, flag: nil, no: nil, remote: nil)
|
1537
|
+
target << '--force' if option('force', target: target)
|
1538
|
+
append_submodules(target: target)
|
1539
|
+
return if !remote && opts.empty?
|
1540
|
+
|
1496
1541
|
refspec = []
|
1497
|
-
|
1498
|
-
|
1499
|
-
if opt =~
|
1542
|
+
op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, no: no)
|
1543
|
+
op.each do |opt|
|
1544
|
+
if opt =~ op.values
|
1500
1545
|
case $1
|
1501
1546
|
when 'rebase'
|
1502
|
-
|
1547
|
+
op << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
|
1503
1548
|
when 'shallow-since'
|
1504
1549
|
next unless (val = Date.parse($2))
|
1505
1550
|
|
1506
|
-
|
1551
|
+
op << quote_option($1, val.strftime('%F %T'))
|
1507
1552
|
when 'recurse-submodules'
|
1508
|
-
|
1553
|
+
op << basic_option($1, $2) unless op.arg?('recurse-submodules')
|
1509
1554
|
when 'refspec'
|
1510
1555
|
refspec << shell_escape($2, quote: true)
|
1511
1556
|
end
|
1557
|
+
elsif op.arg?('--multiple')
|
1558
|
+
op.found << opt
|
1512
1559
|
else
|
1513
|
-
|
1560
|
+
op.errors << opt
|
1514
1561
|
end
|
1515
1562
|
end
|
1516
1563
|
if remote
|
1517
|
-
|
1518
|
-
if (val = option('refspec', strict: true))
|
1519
|
-
|
1564
|
+
op.append(remote, delim: true)
|
1565
|
+
if (val = option('refspec', target: target, strict: true))
|
1566
|
+
op.append(*split_escape(val))
|
1520
1567
|
else
|
1521
|
-
|
1568
|
+
op.merge(refspec)
|
1522
1569
|
end
|
1523
|
-
|
1524
|
-
elsif
|
1525
|
-
|
1570
|
+
op.delete('--all')
|
1571
|
+
elsif op.arg?('--multiple')
|
1572
|
+
op.swap.merge(op.map! { |opt| shell_escape(opt, quote: true) })
|
1526
1573
|
return
|
1527
1574
|
end
|
1528
|
-
|
1575
|
+
op.clear(errors: true, subject: flag.to_s) if flag
|
1529
1576
|
end
|
1530
1577
|
|
1531
1578
|
def append_commit(*val, target: @session, head: false)
|
@@ -1538,10 +1585,10 @@ module Squared
|
|
1538
1585
|
end
|
1539
1586
|
|
1540
1587
|
def append_pathspec(files = [], target: @session, expect: false, parent: false, pass: true)
|
1541
|
-
if session_arg?('pathspec-from-file')
|
1588
|
+
if session_arg?('pathspec-from-file', target: target)
|
1542
1589
|
option_clear files
|
1543
1590
|
else
|
1544
|
-
if files.empty? && (val = option('pathspec'))
|
1591
|
+
if files.empty? && (val = option('pathspec', target: target))
|
1545
1592
|
files = split_escape(val)
|
1546
1593
|
end
|
1547
1594
|
files = projectmap(files, parent: parent, pass: pass)
|
@@ -1564,7 +1611,7 @@ module Squared
|
|
1564
1611
|
end
|
1565
1612
|
|
1566
1613
|
def append_submodules(from = nil, target: @session)
|
1567
|
-
return unless (val = option('recurse-submodules', ignore: false))
|
1614
|
+
return unless (val = option('recurse-submodules', target: target, ignore: false))
|
1568
1615
|
|
1569
1616
|
if from == :clone
|
1570
1617
|
projectmap(split_escape(val)).each do |path|
|
@@ -1573,7 +1620,7 @@ module Squared
|
|
1573
1620
|
target
|
1574
1621
|
else
|
1575
1622
|
target << case val
|
1576
|
-
when 'no', '0'
|
1623
|
+
when 'no', '0', 'false'
|
1577
1624
|
'--no-recurse-submodules'
|
1578
1625
|
when 'yes', 'on-demand'
|
1579
1626
|
"--recurse-submodules#{from == :reset ? '' : "=#{val}"}"
|
@@ -1587,9 +1634,9 @@ module Squared
|
|
1587
1634
|
dir = worktree ? ["--work-tree=#{shell_quote(path)}", "--git-dir=#{shell_quote(gitpath)}"] : []
|
1588
1635
|
return session('git', *dir, *cmd, **kwargs) unless opts
|
1589
1636
|
|
1590
|
-
|
1591
|
-
ret = session('git', *
|
1592
|
-
[ret,
|
1637
|
+
op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self)
|
1638
|
+
ret = session('git', *op.to_a, *cmd, **kwargs)
|
1639
|
+
[ret, op.extras]
|
1593
1640
|
end
|
1594
1641
|
|
1595
1642
|
def git_output(*cmd, **kwargs)
|
@@ -1597,24 +1644,15 @@ module Squared
|
|
1597
1644
|
end
|
1598
1645
|
|
1599
1646
|
def dryrun?(*, target: @session, **)
|
1600
|
-
|
1647
|
+
return false unless target
|
1648
|
+
|
1649
|
+
target.include?('--dry-run')
|
1601
1650
|
end
|
1602
1651
|
|
1603
1652
|
def quiet?(target: @session)
|
1604
1653
|
return false unless target
|
1605
1654
|
|
1606
|
-
target.include?('--quiet') || (target.include?('-q') && target.first == 'git')
|
1607
|
-
end
|
1608
|
-
|
1609
|
-
def verbosity
|
1610
|
-
case verbose
|
1611
|
-
when true
|
1612
|
-
0
|
1613
|
-
when Numeric
|
1614
|
-
verbose
|
1615
|
-
else
|
1616
|
-
-1
|
1617
|
-
end
|
1655
|
+
target.include?('--quiet') || (target.include?('-q') && stripext(target.first) == 'git')
|
1618
1656
|
end
|
1619
1657
|
|
1620
1658
|
def gitpath
|