git_ls 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +82 -0
- data/.gitignore +1 -0
- data/.leftovers.yml +1 -0
- data/.rubocop.yml +26 -3
- data/.simplecov +4 -0
- data/.spellr.yml +1 -0
- data/.spellr_wordlists/english.txt +6 -0
- data/.spellr_wordlists/ruby.txt +2 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +17 -2
- data/README.md +14 -8
- data/Rakefile +20 -11
- data/git_index.gemspec +1 -10
- data/lib/git_ls/version.rb +1 -1
- data/lib/git_ls.rb +97 -84
- metadata +6 -135
- data/.travis.yml +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 723546fbde74cd69c51631aafbb7fee4b4dbe12915f969855dcc6d1b577834bf
|
4
|
+
data.tar.gz: 3b9d5b1c58209e1a799864a71a875b059eef1e315c53e56351c44026f4c07931
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4d9fb5d7c4f84057007dbc9052c011f165e191c0c7e4bfc533cf9319ce61f8103d65b936abc884e44fd1ecae666d665c160f9ab39a2f35ec1f115a871a8fd9c
|
7
|
+
data.tar.gz: 71a87a2b4946e2a499dba2c673507951a95eb4fb8a499f3737d037ed428121314d2c5e7fef0356bc8ea7070f4877e69f6b0ed13bd4cffaecacd8a0b757b26d56
|
@@ -0,0 +1,82 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- main
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
rspec:
|
13
|
+
strategy:
|
14
|
+
fail-fast: false
|
15
|
+
matrix:
|
16
|
+
ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, 3.3, 3.4, ruby-head, jruby, jruby-head]
|
17
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') }}
|
18
|
+
runs-on: ubuntu-latest
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@v4
|
21
|
+
- uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby }}
|
24
|
+
bundler-cache: true
|
25
|
+
- run: bundle exec rspec
|
26
|
+
|
27
|
+
coverage:
|
28
|
+
runs-on: ubuntu-latest
|
29
|
+
steps:
|
30
|
+
- uses: actions/checkout@v4
|
31
|
+
- uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: 3.4
|
34
|
+
bundler-cache: true
|
35
|
+
- run: COVERAGE=1 bundle exec rspec
|
36
|
+
|
37
|
+
- uses: actions/upload-artifact@v4
|
38
|
+
with:
|
39
|
+
name: coverage-report
|
40
|
+
path: 'coverage/*'
|
41
|
+
retention-days: 1
|
42
|
+
if: ${{ failure() }}
|
43
|
+
|
44
|
+
rubocop:
|
45
|
+
runs-on: ubuntu-latest
|
46
|
+
steps:
|
47
|
+
- uses: actions/checkout@v4
|
48
|
+
- uses: ruby/setup-ruby@v1
|
49
|
+
with:
|
50
|
+
ruby-version: 3.4
|
51
|
+
bundler-cache: true
|
52
|
+
- run: bundle exec rubocop
|
53
|
+
|
54
|
+
spellr:
|
55
|
+
runs-on: ubuntu-latest
|
56
|
+
steps:
|
57
|
+
- uses: actions/checkout@v4
|
58
|
+
- uses: ruby/setup-ruby@v1
|
59
|
+
with:
|
60
|
+
ruby-version: 3.4
|
61
|
+
bundler-cache: true
|
62
|
+
- run: bundle exec spellr
|
63
|
+
|
64
|
+
leftovers:
|
65
|
+
runs-on: ubuntu-latest
|
66
|
+
steps:
|
67
|
+
- uses: actions/checkout@v4
|
68
|
+
- uses: ruby/setup-ruby@v1
|
69
|
+
with:
|
70
|
+
ruby-version: 3.4
|
71
|
+
bundler-cache: true
|
72
|
+
- run: bundle exec leftovers
|
73
|
+
|
74
|
+
build:
|
75
|
+
runs-on: ubuntu-latest
|
76
|
+
steps:
|
77
|
+
- uses: actions/checkout@v4
|
78
|
+
- uses: ruby/setup-ruby@v1
|
79
|
+
with:
|
80
|
+
ruby-version: 3.4
|
81
|
+
bundler-cache: true
|
82
|
+
- run: bundle exec rake build
|
data/.gitignore
CHANGED
data/.leftovers.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require:
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
- rubocop-rake
|
2
4
|
|
3
5
|
# Reference:
|
4
6
|
# https://rubocop.readthedocs.io/en/latest/
|
@@ -113,11 +115,12 @@ Metrics:
|
|
113
115
|
CountComments: false
|
114
116
|
|
115
117
|
Metrics/BlockLength:
|
116
|
-
|
118
|
+
AllowedMethods:
|
117
119
|
- configure
|
118
120
|
- describe
|
119
121
|
- context
|
120
122
|
- shared_examples
|
123
|
+
- benchmark
|
121
124
|
|
122
125
|
Metrics/CyclomaticComplexity:
|
123
126
|
Enabled: false
|
@@ -125,6 +128,9 @@ Metrics/CyclomaticComplexity:
|
|
125
128
|
Metrics/PerceivedComplexity:
|
126
129
|
Enabled: false
|
127
130
|
|
131
|
+
Metrics/ClassLength:
|
132
|
+
Enabled: false
|
133
|
+
|
128
134
|
RSpec:
|
129
135
|
Enabled: true
|
130
136
|
Include:
|
@@ -140,7 +146,7 @@ RSpec/ExampleLength:
|
|
140
146
|
RSpec/ExpectActual:
|
141
147
|
Enabled: false
|
142
148
|
|
143
|
-
RSpec/
|
149
|
+
RSpec/SpecFilePathFormat:
|
144
150
|
Enabled: false
|
145
151
|
|
146
152
|
# Multiple expectations are useful
|
@@ -224,3 +230,20 @@ Style/HashTransformValues:
|
|
224
230
|
|
225
231
|
Style/CommentedKeyword:
|
226
232
|
Enabled: false
|
233
|
+
|
234
|
+
Style/CaseLikeIf:
|
235
|
+
Enabled: false
|
236
|
+
|
237
|
+
Style/NumericPredicate:
|
238
|
+
Enabled: false
|
239
|
+
|
240
|
+
Style/Semicolon:
|
241
|
+
Exclude:
|
242
|
+
- bin/benchmark
|
243
|
+
|
244
|
+
Naming/VariableNumber:
|
245
|
+
Enabled: false
|
246
|
+
|
247
|
+
Lint/Void:
|
248
|
+
Exclude:
|
249
|
+
- bin/benchmark
|
data/.simplecov
CHANGED
data/.spellr.yml
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
baz
|
2
|
+
bitshift
|
2
3
|
changelog
|
3
4
|
codebase
|
4
5
|
cov
|
@@ -20,6 +21,7 @@ params
|
|
20
21
|
pwd
|
21
22
|
quotepath
|
22
23
|
rdoc
|
24
|
+
readme
|
23
25
|
rspec
|
24
26
|
rubo
|
25
27
|
rubocop
|
@@ -27,7 +29,11 @@ rvm
|
|
27
29
|
sharedindex
|
28
30
|
sherson
|
29
31
|
simplecov
|
32
|
+
srb
|
30
33
|
sudo
|
31
34
|
tmp
|
35
|
+
txt
|
32
36
|
usr
|
37
|
+
utf
|
38
|
+
warmup
|
33
39
|
yardoc
|
data/.spellr_wordlists/ruby.txt
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -5,5 +5,20 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in git_index.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
|
9
|
-
gem '
|
8
|
+
group(:development) do
|
9
|
+
gem 'benchmark', require: false
|
10
|
+
gem 'benchmark-ips', require: false
|
11
|
+
gem 'bundler', '>= 2', require: false
|
12
|
+
gem 'fast_ignore', '>= 0.15.1', require: false
|
13
|
+
gem 'leftovers', '>= 0.4.0', require: false
|
14
|
+
gem 'pry', require: false
|
15
|
+
gem 'rake', '>= 12.3.3', require: false
|
16
|
+
gem 'rspec', require: false
|
17
|
+
gem 'rubocop', '>= 0.93.1', require: false
|
18
|
+
gem 'rubocop-performance', '>= 1.8.1', require: false
|
19
|
+
gem 'rubocop-rake', require: false
|
20
|
+
gem 'rubocop-rspec', '>= 1.44.1', require: false
|
21
|
+
gem 'simplecov', '>= 0.18.5', require: false
|
22
|
+
gem 'simplecov-console', require: false
|
23
|
+
gem 'spellr', require: false, platforms: :ruby
|
24
|
+
end
|
data/README.md
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
|
3
3
|
Parses the .git/index file like `git ls-files` does.
|
4
4
|
|
5
|
-
-
|
6
|
-
it can be faster than doing the system call to git
|
7
|
-
- still takes less than half a second for very large repos e.g. the linux repo
|
5
|
+
- faster than doing the system call to git
|
8
6
|
- doesn't require git to be installed
|
7
|
+
- tested against ruby 2.4 - 3.4.1 and jruby
|
9
8
|
|
10
9
|
## Installation
|
11
10
|
|
@@ -23,23 +22,30 @@ Or install it yourself as:
|
|
23
22
|
|
24
23
|
$ gem install git_ls
|
25
24
|
|
25
|
+
And require
|
26
|
+
```ruby
|
27
|
+
require 'git_ls'
|
28
|
+
```
|
29
|
+
|
26
30
|
## Usage
|
27
31
|
|
28
|
-
`GitLS.files`
|
32
|
+
`GitLS.files` reads the `.git/index` file to return an array of file paths, equivalent to `` `git ls-files`.split("\n") ``, but faster, and without requiring git being installed.
|
33
|
+
|
29
34
|
`GitLS.files("path/to/repo")` if the repo is not $PWD.
|
30
35
|
|
36
|
+
Strictly speaking it's equivalent to `` `git ls-files -c core.quotepath=off -z`.split("\0") ``, handling file paths with spaces and non-ascii characters, and returning file paths as UTF-8 strings.
|
37
|
+
|
31
38
|
## Development
|
32
39
|
|
33
|
-
Have a look in the bin dir for some useful tools.
|
34
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
40
|
+
- Have a look in the bin dir for some useful tools.
|
41
|
+
- To install this gem onto your local machine, run `bundle exec rake install`.
|
42
|
+
- Run `rake` to run all tests & linters.
|
35
43
|
|
36
44
|
## Contributing
|
37
45
|
|
38
46
|
Bug reports and pull requests are welcome on GitHub at https://github.com/robotdana/git_ls.
|
39
47
|
If you're comfortable, please attach `.git/index` (and `.git/sharedindex.<sha>` if applicable) and the output of `git ls-files` where it doesn't match.
|
40
48
|
|
41
|
-
|
42
49
|
## License
|
43
50
|
|
44
51
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
45
|
-
# git_ls
|
data/Rakefile
CHANGED
@@ -1,18 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'bundler/setup'
|
3
4
|
require 'bundler/gem_tasks'
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
require 'rubocop/rake_task'
|
6
|
-
require 'spellr/rake_task'
|
7
|
-
require 'leftovers/rake_task'
|
8
5
|
|
9
|
-
|
6
|
+
require 'rspec/core/rake_task'
|
10
7
|
RSpec::Core::RakeTask.new(:spec)
|
11
|
-
|
12
|
-
|
8
|
+
linters = %i{spec}
|
9
|
+
|
10
|
+
if RUBY_PLATFORM != 'java'
|
11
|
+
require 'rubocop/rake_task'
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
linters << :rubocop
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
require 'spellr/rake_task'
|
16
|
+
Spellr::RakeTask.generate_task
|
17
|
+
linters << :spellr
|
18
|
+
|
19
|
+
require 'leftovers/rake_task'
|
20
|
+
Leftovers::RakeTask.generate_task
|
21
|
+
linters << :leftovers
|
18
22
|
end
|
23
|
+
|
24
|
+
linters << :build
|
25
|
+
|
26
|
+
desc 'Run all linters'
|
27
|
+
task default: linters
|
data/git_index.gemspec
CHANGED
@@ -26,14 +26,5 @@ Gem::Specification.new do |spec|
|
|
26
26
|
end
|
27
27
|
|
28
28
|
spec.require_paths = ['lib']
|
29
|
-
|
30
|
-
spec.add_development_dependency 'bundler', '>= 2'
|
31
|
-
spec.add_development_dependency 'leftovers'
|
32
|
-
spec.add_development_dependency 'pry', '> 0'
|
33
|
-
spec.add_development_dependency 'rake', '>= 12.3.3'
|
34
|
-
spec.add_development_dependency 'rubocop'
|
35
|
-
spec.add_development_dependency 'rubocop-performance'
|
36
|
-
spec.add_development_dependency 'rubocop-rspec'
|
37
|
-
spec.add_development_dependency 'simplecov', '~> 0.18.5'
|
38
|
-
spec.add_development_dependency 'spellr'
|
29
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
39
30
|
end
|
data/lib/git_ls/version.rb
CHANGED
data/lib/git_ls.rb
CHANGED
@@ -3,105 +3,105 @@
|
|
3
3
|
# Usage:
|
4
4
|
# GitLS.files -> Array of strings as files.
|
5
5
|
# This will be identical output to git ls-files
|
6
|
+
require 'stringio'
|
7
|
+
require_relative 'git_ls/version'
|
8
|
+
|
6
9
|
module GitLS # rubocop:disable Metrics/ModuleLength
|
7
10
|
class Error < StandardError; end
|
8
11
|
|
9
12
|
class << self
|
10
|
-
def files(path =
|
11
|
-
|
12
|
-
end
|
13
|
+
def files(path = nil)
|
14
|
+
path = path ? ::File.join(path, '.git/index') : '.git/index'
|
13
15
|
|
14
|
-
|
15
|
-
read(path, true)
|
16
|
+
read(path, false)
|
16
17
|
end
|
17
18
|
|
18
19
|
private
|
19
20
|
|
20
|
-
def read(path,
|
21
|
-
|
22
|
-
|
21
|
+
def read(path, _return_headers_only) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
22
|
+
begin
|
23
|
+
# reading the whole file into memory is faster than lots of ::File#read
|
24
|
+
# the biggest it's going to be is 10s of megabytes, well within ram.
|
25
|
+
file = ::StringIO.new(::File.read(path, mode: 'rb'))
|
26
|
+
rescue ::Errno::ENOENT => e
|
27
|
+
raise ::GitLS::Error, "Not a git directory: #{e.message}"
|
28
|
+
end
|
29
|
+
|
23
30
|
buf = ::String.new
|
24
31
|
# 4-byte signature:
|
25
32
|
# The signature is { 'D', 'I', 'R', 'C' } (stands for "dircache")
|
26
33
|
# 4-byte version number:
|
27
34
|
# The current supported versions are 2, 3 and 4.
|
28
35
|
# 32-bit number of index entries.
|
29
|
-
|
30
|
-
|
36
|
+
file.read(4, buf)
|
37
|
+
sig = buf
|
38
|
+
raise ::GitLS::Error, ".git/index file not found at '#{path}'" unless sig == 'DIRC'
|
39
|
+
|
40
|
+
file.read(4, buf)
|
41
|
+
git_index_version = buf.unpack1('N')
|
31
42
|
|
32
|
-
|
43
|
+
file.read(4, buf)
|
44
|
+
entries = buf.unpack1('N')
|
33
45
|
|
34
|
-
files = ::Array.new(
|
35
|
-
case git_index_version
|
46
|
+
files = ::Array.new(entries)
|
47
|
+
files = case git_index_version
|
36
48
|
when 2 then files_2(files, file)
|
37
49
|
when 3 then files_3(files, file)
|
38
50
|
when 4 then files_4(files, file)
|
39
|
-
else raise ::GitLS::Error,
|
51
|
+
else raise ::GitLS::Error, "Unrecognized git index version '#{git_index_version}'"
|
40
52
|
end
|
41
53
|
|
42
|
-
|
43
|
-
files
|
44
|
-
rescue ::Errno::ENOENT => e
|
45
|
-
raise ::GitLS::Error, "Not a git directory: #{e.message}"
|
46
|
-
ensure
|
47
|
-
# :nocov:
|
48
|
-
# coverage tracking for branches in ensure blocks is weird
|
49
|
-
file&.close
|
50
|
-
# :nocov:
|
51
|
-
files
|
54
|
+
read_extensions(files, file, path, buf)
|
52
55
|
end
|
53
56
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
def read_extensions(files, file, path, buf) # rubocop:disable Metrics/MethodLength
|
58
|
+
extension = file.read(4, buf)
|
59
|
+
if extension == 'link'
|
60
|
+
read_link_extension(files, file, path, buf)
|
61
|
+
elsif extension.match?(/\A[A-Z]{4}\z/)
|
62
|
+
size = file.read(4, buf).unpack1('N')
|
63
|
+
file.seek(size, 1)
|
64
|
+
read_extensions(files, file, path, buf)
|
58
65
|
else
|
59
|
-
return if
|
66
|
+
return files if file.seek(16, 1) && file.eof?
|
60
67
|
|
61
|
-
raise ::GitLS::Error, "Unrecognized .git/index extension #{
|
68
|
+
raise ::GitLS::Error, "Unrecognized .git/index extension #{extension.inspect}"
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
def
|
66
|
-
|
67
|
-
file.pos += size
|
68
|
-
extensions(files, file, buf)
|
69
|
-
end
|
70
|
-
|
71
|
-
def link_extension(files, file, buf) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
72
|
-
file.pos += 4 # size = file.read(4, buf).unpack1('N')
|
72
|
+
def read_link_extension(files, file, path, buf) # rubocop:disable Metrics/MethodLength
|
73
|
+
file.seek(4, 1) # skip size
|
73
74
|
|
74
75
|
sha = file.read(20, buf)
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
files.replace files("#{::File.dirname(file.path)}/sharedindex.#{sha.unpack1('H*')}")
|
77
|
+
split_files = read("#{::File.dirname(path)}/sharedindex.#{sha.unpack1('H*')}", false)
|
79
78
|
|
80
79
|
ewah_each_value(file, buf) do |pos|
|
81
|
-
|
80
|
+
split_files[pos] = nil
|
82
81
|
end
|
83
82
|
|
84
83
|
ewah_each_value(file, buf) do |pos|
|
85
|
-
replacement_file =
|
84
|
+
replacement_file = files.shift
|
86
85
|
# the documentation *implies* that this *may* get a new filename
|
87
86
|
# i can't get it to happen though
|
88
87
|
# :nocov:
|
89
|
-
|
88
|
+
split_files[pos] = replacement_file unless replacement_file.empty?
|
90
89
|
# :nocov:
|
91
90
|
end
|
92
91
|
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
split_files.compact!
|
93
|
+
split_files.concat(files)
|
94
|
+
split_files.sort!
|
96
95
|
|
97
|
-
|
96
|
+
read_extensions(split_files, file, path, buf)
|
98
97
|
end
|
99
98
|
|
100
99
|
# format is defined here:
|
101
100
|
# https://git-scm.com/docs/bitmap-format#_appendix_a_serialization_format_for_an_ewah_bitmap
|
102
101
|
def ewah_each_value(file, buf) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
103
102
|
uncompressed_pos = 0
|
104
|
-
|
103
|
+
|
104
|
+
file.seek(4, 1) # skip 4 byte uncompressed_bits_count.
|
105
105
|
compressed_bytes = file.read(4, buf).unpack1('N') * 8
|
106
106
|
|
107
107
|
final_file_pos = file.pos + compressed_bytes
|
@@ -110,10 +110,10 @@ module GitLS # rubocop:disable Metrics/ModuleLength
|
|
110
110
|
run_length_word = file.read(8, buf).unpack1('Q>')
|
111
111
|
# 1st bit
|
112
112
|
run_bit = run_length_word & 1
|
113
|
-
# the next 32 bits, masked, multiplied by 64
|
114
|
-
run_length = ((run_length_word
|
113
|
+
# the next 32 bits, masked, multiplied by 64
|
114
|
+
run_length = ((run_length_word / 0b1_0) & 0xFFFF_FFFF) * 64
|
115
115
|
# the next 31 bits
|
116
|
-
literal_length = (run_length_word
|
116
|
+
literal_length = (run_length_word / 0b100000000_00000000_00000000_00000000_0)
|
117
117
|
|
118
118
|
if run_bit == 1
|
119
119
|
run_length.times do
|
@@ -124,9 +124,12 @@ module GitLS # rubocop:disable Metrics/ModuleLength
|
|
124
124
|
uncompressed_pos += run_length
|
125
125
|
end
|
126
126
|
|
127
|
-
literal_length
|
128
|
-
|
129
|
-
|
127
|
+
next unless literal_length > 0
|
128
|
+
|
129
|
+
file.read(8 * literal_length, buf)
|
130
|
+
words = buf.unpack('B64' * literal_length)
|
131
|
+
words.each do |word|
|
132
|
+
word.each_char.reverse_each do |char|
|
130
133
|
yield(uncompressed_pos) if char == '1'
|
131
134
|
|
132
135
|
uncompressed_pos += 1
|
@@ -134,59 +137,64 @@ module GitLS # rubocop:disable Metrics/ModuleLength
|
|
134
137
|
end
|
135
138
|
end
|
136
139
|
|
137
|
-
file.
|
140
|
+
file.seek(4, 1) # bitmap metadata for adding to bitmaps
|
138
141
|
end
|
139
142
|
|
140
143
|
def files_2(files, file) # rubocop:disable Metrics/MethodLength
|
141
144
|
files.map! do
|
142
|
-
file.
|
143
|
-
|
145
|
+
file.seek(60, 1) # skip 60 bytes (40 bytes of stat, 20 bytes of sha)
|
146
|
+
|
147
|
+
length = ((file.getbyte & 0xF) * 256) + file.getbyte # find the 12 byte length
|
144
148
|
if length < 0xFFF
|
145
149
|
path = file.read(length)
|
146
150
|
# :nocov:
|
147
151
|
else
|
148
152
|
# i can't test this i just get ENAMETOOLONG a lot
|
149
|
-
path
|
150
|
-
|
153
|
+
# I'm not sure it's even possible to get to this path, PATH_MAX is 4096 bytes on linux, 1024 on mac
|
154
|
+
# and length is a 12 byte number: 4096 max.
|
155
|
+
path = file.readline("\0").chop!
|
156
|
+
file.seek(-1, 1)
|
151
157
|
# :nocov:
|
152
158
|
end
|
153
|
-
file.
|
159
|
+
file.seek(8 - ((length - 2) % 8), 1) # 1-8 bytes padding of nuls
|
160
|
+
path.force_encoding(Encoding::UTF_8)
|
154
161
|
path
|
155
162
|
end
|
156
163
|
end
|
157
164
|
|
158
165
|
def files_3(files, file) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
159
166
|
files.map! do
|
160
|
-
file.
|
167
|
+
file.seek(60, 1) # skip 60 bytes (40 bytes of stat, 20 bytes of sha)
|
168
|
+
flags = file.getbyte
|
169
|
+
extended_flag = (flags & 0b0100_0000) > 0
|
170
|
+
length = ((flags & 0xF) * 256) + file.getbyte # find the 12 byte length
|
171
|
+
file.seek(2, 1) if extended_flag
|
161
172
|
|
162
|
-
flags = file.getbyte * 256 + file.getbyte
|
163
|
-
extended_flag = (flags & 0b0100_0000_0000_0000).positive?
|
164
|
-
file.pos += 2 if extended_flag
|
165
|
-
|
166
|
-
length = flags & 0b0000_1111_1111_1111
|
167
173
|
if length < 0xFFF
|
168
174
|
path = file.read(length)
|
169
175
|
# :nocov:
|
170
176
|
else
|
171
177
|
# i can't test this i just get ENAMETOOLONG a lot
|
172
|
-
path
|
173
|
-
|
178
|
+
# I'm not sure it's even possible to get to this path, PATH_MAX is 4096 bytes on linux, 1024 on mac
|
179
|
+
# and length is a 12 byte number: 4096 max.
|
180
|
+
path = file.readline("\0").chop!
|
181
|
+
file.seek(-1, 1)
|
174
182
|
# :nocov:
|
175
183
|
end
|
176
|
-
|
177
|
-
|
184
|
+
file.seek(8 - ((path.bytesize - (extended_flag ? 0 : 2)) % 8), 1) # 1-8 bytes padding of nuls
|
185
|
+
path.force_encoding(Encoding::UTF_8)
|
178
186
|
path
|
179
187
|
end
|
180
188
|
end
|
181
189
|
|
182
190
|
def files_4(files, file) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
183
191
|
prev_entry_path = ''
|
184
|
-
files.map! do
|
185
|
-
file.
|
186
|
-
flags = file.getbyte
|
187
|
-
|
188
|
-
|
189
|
-
|
192
|
+
files.map! do # rubocop:disable Metrics/BlockLength
|
193
|
+
file.seek(60, 1) # skip 60 bytes (40 bytes of stat, 20 bytes of sha)
|
194
|
+
flags = file.getbyte
|
195
|
+
extended_flag = (flags & 0b0100_0000) > 0
|
196
|
+
length = ((flags & 0xF) * 256) + file.getbyte # find the 12 byte length
|
197
|
+
file.seek(2, 1) if extended_flag
|
190
198
|
|
191
199
|
# documentation for this number from
|
192
200
|
# https://git-scm.com/docs/pack-format#_original_version_1_pack_idx_files_have_the_following_format
|
@@ -199,9 +207,9 @@ module GitLS # rubocop:disable Metrics/ModuleLength
|
|
199
207
|
read_offset = 0
|
200
208
|
prev_read_offset = file.getbyte
|
201
209
|
n = 1
|
202
|
-
while (prev_read_offset & 0b1000_0000)
|
203
|
-
read_offset += (prev_read_offset
|
204
|
-
read_offset +=
|
210
|
+
while (prev_read_offset & 0b1000_0000) > 0
|
211
|
+
read_offset += (prev_read_offset & 0b0111_1111)
|
212
|
+
read_offset += 1 << (7 * n)
|
205
213
|
n += 1
|
206
214
|
prev_read_offset = file.getbyte
|
207
215
|
end
|
@@ -210,16 +218,21 @@ module GitLS # rubocop:disable Metrics/ModuleLength
|
|
210
218
|
initial_part_length = prev_entry_path.bytesize - read_offset
|
211
219
|
|
212
220
|
if length < 0xFFF
|
213
|
-
rest =
|
214
|
-
file.
|
221
|
+
rest = +''
|
222
|
+
file.read(length - initial_part_length, rest)
|
223
|
+
file.seek(1, 1) # the NUL
|
215
224
|
# :nocov:
|
216
225
|
else
|
217
226
|
# i can't test this i just get ENAMETOOLONG a lot
|
218
|
-
|
227
|
+
# I'm not sure it's even possible to get to this path, PATH_MAX is 4096 bytes on linux, 1024 on mac
|
228
|
+
# and length is a 12 byte number: 4096 max.
|
229
|
+
rest = file.readline("\0").chop!
|
230
|
+
file.seek(-1, 1)
|
219
231
|
# :nocov:
|
220
232
|
end
|
221
233
|
|
222
|
-
prev_entry_path = prev_entry_path.byteslice(0, initial_part_length)
|
234
|
+
prev_entry_path = +"#{prev_entry_path.byteslice(0, initial_part_length)}#{rest}"
|
235
|
+
prev_entry_path.force_encoding(::Encoding::UTF_8)
|
223
236
|
end
|
224
237
|
end
|
225
238
|
end
|
metadata
CHANGED
@@ -1,148 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_ls
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dana Sherson
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '2'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: leftovers
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: pry
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 12.3.3
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 12.3.3
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rubocop
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop-performance
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop-rspec
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 0.18.5
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 0.18.5
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: spellr
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
description:
|
10
|
+
date: 2025-01-28 00:00:00.000000000 Z
|
11
|
+
dependencies: []
|
140
12
|
email:
|
141
13
|
- robot@dana.sh
|
142
14
|
executables: []
|
143
15
|
extensions: []
|
144
16
|
extra_rdoc_files: []
|
145
17
|
files:
|
18
|
+
- ".github/workflows/ci.yml"
|
146
19
|
- ".gitignore"
|
147
20
|
- ".leftovers.yml"
|
148
21
|
- ".rspec"
|
@@ -152,7 +25,6 @@ files:
|
|
152
25
|
- ".spellr_wordlists/english.txt"
|
153
26
|
- ".spellr_wordlists/ruby.txt"
|
154
27
|
- ".spellr_wordlists/shell.txt"
|
155
|
-
- ".travis.yml"
|
156
28
|
- CHANGELOG.md
|
157
29
|
- Gemfile
|
158
30
|
- LICENSE.txt
|
@@ -168,7 +40,7 @@ metadata:
|
|
168
40
|
homepage_uri: https://github.com/robotdana/git_ls
|
169
41
|
source_code_uri: https://github.com/robotdana/git_ls
|
170
42
|
changelog_uri: https://github.com/robotdana/git_ls/blob/main/CHANGELOG.md
|
171
|
-
|
43
|
+
rubygems_mfa_required: 'true'
|
172
44
|
rdoc_options: []
|
173
45
|
require_paths:
|
174
46
|
- lib
|
@@ -183,8 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
55
|
- !ruby/object:Gem::Version
|
184
56
|
version: '0'
|
185
57
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
187
|
-
signing_key:
|
58
|
+
rubygems_version: 3.6.2
|
188
59
|
specification_version: 4
|
189
60
|
summary: Read a .git/index file and list the files
|
190
61
|
test_files: []
|