git-object-browser 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +17 -0
- data/htdocs/{css → common/css}/angular-ui.min.css +0 -0
- data/htdocs/{css → common/css}/bootstrap-responsive.css +0 -0
- data/htdocs/{css → common/css}/bootstrap-responsive.min.css +0 -0
- data/htdocs/{css → common/css}/bootstrap.css +0 -0
- data/htdocs/{css → common/css}/bootstrap.min.css +0 -0
- data/htdocs/{css → common/css}/font-awesome-ie7.css +0 -0
- data/htdocs/{css → common/css}/font-awesome.css +0 -0
- data/htdocs/{css → common/css}/main.css +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.eot +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.svg +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.ttf +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.woff +0 -0
- data/htdocs/{img → common/img}/glyphicons-halflings-white.png +0 -0
- data/htdocs/{img → common/img}/glyphicons-halflings.png +0 -0
- data/htdocs/common/js/main.js +495 -0
- data/htdocs/{js → common/js}/vendor/angular-bootstrap-prettify.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-bootstrap.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-cookies.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-loader.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-resource.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-sanitize.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-ui-ieshiv.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-ui.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/bootstrap.js +0 -0
- data/htdocs/{js → common/js}/vendor/bootstrap.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/html5shiv.js +0 -0
- data/htdocs/{js → common/js}/vendor/jquery-1.8.2.min.js +0 -0
- data/htdocs/{templates → common/templates}/directory.html +2 -2
- data/htdocs/common/templates/error.html +6 -0
- data/htdocs/{templates → common/templates}/file.html +0 -0
- data/htdocs/{templates → common/templates}/git.html +0 -0
- data/htdocs/{templates → common/templates}/index.html +1 -1
- data/htdocs/{templates → common/templates}/index_entry.html +0 -0
- data/htdocs/{templates → common/templates}/info_refs.html +2 -2
- data/htdocs/{templates → common/templates}/loading.html +0 -0
- data/htdocs/{templates → common/templates}/notfound.html +1 -2
- data/htdocs/{templates → common/templates}/object.html +1 -1
- data/htdocs/{templates → common/templates}/objects.html +3 -3
- data/htdocs/{templates → common/templates}/pack_file.html +1 -1
- data/htdocs/common/templates/pack_index.html +39 -0
- data/htdocs/{templates → common/templates}/packed_object.html +4 -4
- data/htdocs/{templates → common/templates}/packed_refs.html +2 -2
- data/htdocs/{templates → common/templates}/ref.html +0 -0
- data/htdocs/common/templates/reflog.html +29 -0
- data/htdocs/config.js +6 -0
- data/htdocs/default.js +7 -0
- data/htdocs/index.html +52 -20
- data/lib/git-object-browser.rb +12 -4
- data/lib/git-object-browser/dumper/directories_dumper.rb +42 -0
- data/lib/git-object-browser/dumper/index_dumper.rb +20 -7
- data/lib/git-object-browser/dumper/info_refs_dumper.rb +37 -0
- data/lib/git-object-browser/dumper/main.rb +188 -81
- data/lib/git-object-browser/dumper/objects_dumper.rb +46 -0
- data/lib/git-object-browser/dumper/pack_indexes_dumper.rb +85 -0
- data/lib/git-object-browser/dumper/packed_objects_dumper.rb +36 -0
- data/lib/git-object-browser/dumper/packed_refs_dumper.rb +37 -0
- data/lib/git-object-browser/dumper/plain_files_dumper.rb +74 -0
- data/lib/git-object-browser/dumper/refs_dumper.rb +46 -0
- data/lib/git-object-browser/main.rb +22 -6
- data/lib/git-object-browser/models/directory.rb +5 -3
- data/lib/git-object-browser/models/git_date.rb +26 -0
- data/lib/git-object-browser/models/git_object.rb +1 -1
- data/lib/git-object-browser/models/pack_file.rb +1 -1
- data/lib/git-object-browser/models/pack_index.rb +139 -25
- data/lib/git-object-browser/models/packed_object.rb +1 -1
- data/lib/git-object-browser/models/reflog.rb +54 -0
- data/lib/git-object-browser/models/wrapped_object.rb +40 -0
- data/lib/git-object-browser/server/git_servlet.rb +130 -100
- data/lib/git-object-browser/server/main.rb +1 -1
- data/lib/git-object-browser/version.rb +1 -1
- metadata +62 -50
- data/htdocs/js/main.js +0 -285
- data/htdocs/templates/pack_index.html +0 -37
- data/lib/git-object-browser/dumper/object_dumper.rb +0 -20
- data/lib/git-object-browser/dumper/pack_index_dumper.rb +0 -21
- data/lib/git-object-browser/dumper/packed_object_dumper.rb +0 -19
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module GitObjectBrowser
|
4
|
+
|
5
|
+
module Dumper
|
6
|
+
|
7
|
+
class PackedObjectsDumper
|
8
|
+
|
9
|
+
def initialize(root, outdir)
|
10
|
+
@root = root
|
11
|
+
@outdir = outdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump(path, index)
|
15
|
+
File.open(File.join(@root, path)) do |input|
|
16
|
+
index.entries.each do |entry|
|
17
|
+
dump_packed_object(index, input, entry[:offset], path)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def dump_packed_object(index, input, offset, path)
|
23
|
+
obj = GitObjectBrowser::Models::PackedObject.new(index, input).parse(offset)
|
24
|
+
wrapped = GitObjectBrowser::Models::WrappedObject.new(nil, path, obj)
|
25
|
+
|
26
|
+
ostr = "0000#{ offset }"
|
27
|
+
outfile = File.join(@outdir, path, ostr[-2,2], ostr[-4,2], "#{ offset }.json")
|
28
|
+
FileUtils.mkdir_p(File.dirname(outfile))
|
29
|
+
|
30
|
+
File.open(outfile, 'w') do |output|
|
31
|
+
output << JSON.pretty_generate(wrapped.to_hash)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module GitObjectBrowser
|
4
|
+
|
5
|
+
module Dumper
|
6
|
+
|
7
|
+
class PackedRefsDumper
|
8
|
+
|
9
|
+
def initialize(root, outdir)
|
10
|
+
@root = root
|
11
|
+
@outdir = outdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump
|
15
|
+
src_file = File.join(@root, "packed-refs")
|
16
|
+
dst_file = File.join(@outdir, "packed-refs.json")
|
17
|
+
|
18
|
+
return unless File.exist?(src_file)
|
19
|
+
|
20
|
+
puts "Write: packed-refs\n"
|
21
|
+
File.open(src_file) do |input|
|
22
|
+
File.open(dst_file, "w") do |output|
|
23
|
+
dump_object(input, output)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def dump_object(input, output)
|
29
|
+
obj = GitObjectBrowser::Models::PackedRefs.new(input)
|
30
|
+
wrapped = GitObjectBrowser::Models::WrappedObject.new(nil, 'packed-refs', obj)
|
31
|
+
output << JSON.pretty_generate(wrapped.to_hash)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module GitObjectBrowser
|
4
|
+
|
5
|
+
module Dumper
|
6
|
+
|
7
|
+
class PlainFilesDumper
|
8
|
+
|
9
|
+
def initialize(root, outdir)
|
10
|
+
@root = root
|
11
|
+
@outdir = outdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump
|
15
|
+
obj_files = []
|
16
|
+
|
17
|
+
# ! info/refs
|
18
|
+
# info
|
19
|
+
# logs
|
20
|
+
# objects/info
|
21
|
+
|
22
|
+
plain_files = []
|
23
|
+
subdirs = []
|
24
|
+
|
25
|
+
Dir.chdir(@root) do
|
26
|
+
Dir.glob('*') do |path|
|
27
|
+
next if %w{HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD CHERRY_PICK_HEAD}.include?(path)
|
28
|
+
next if %w{dump index objects refs packed-refs}.include?(path)
|
29
|
+
|
30
|
+
if File.directory?(path)
|
31
|
+
subdirs << path
|
32
|
+
else
|
33
|
+
plain_files << path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
subdirs << 'objects/info'
|
38
|
+
|
39
|
+
subdirs.each do |dir|
|
40
|
+
next unless File.directory?(File.join(@root, dir))
|
41
|
+
Dir.chdir(File.join(@root, dir)) do
|
42
|
+
Dir.glob('**/*') do |path|
|
43
|
+
# skip info/refs (InfoRefs)
|
44
|
+
next if dir == 'info' && path == 'refs'
|
45
|
+
if File.file?(path)
|
46
|
+
plain_files << File.join(dir, path)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
plain_files.each do |path|
|
53
|
+
outfile = File.join(@outdir, "#{ path }.json")
|
54
|
+
FileUtils.mkdir_p(File.dirname(outfile))
|
55
|
+
|
56
|
+
puts "Write: #{path}\n"
|
57
|
+
file = File.join(@root, path)
|
58
|
+
File.open(file) do |input|
|
59
|
+
File.open(outfile, "w") do |output|
|
60
|
+
dump_object(input, output, path)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def dump_object(input, output, path)
|
67
|
+
obj = GitObjectBrowser::Models::PlainFile.new(input).parse
|
68
|
+
wrapped = GitObjectBrowser::Models::WrappedObject.new(nil, path, obj)
|
69
|
+
output << JSON.pretty_generate(wrapped.to_hash)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module GitObjectBrowser
|
4
|
+
|
5
|
+
module Dumper
|
6
|
+
|
7
|
+
class RefsDumper
|
8
|
+
|
9
|
+
def initialize(root, outdir)
|
10
|
+
@root = root
|
11
|
+
@outdir = outdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump
|
15
|
+
ref_files = %w{HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD CHERRY_PICK_HEAD}
|
16
|
+
Dir.chdir(@root) do
|
17
|
+
Dir.glob("refs/**/*") do |path|
|
18
|
+
ref_files << path if File.file?(path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return if ref_files.empty?
|
22
|
+
|
23
|
+
ref_files.each do |path|
|
24
|
+
next unless File.exist?(File.join(@root, path))
|
25
|
+
outfile = File.join(@outdir, "#{ path }.json")
|
26
|
+
FileUtils.mkdir_p(File.dirname(outfile))
|
27
|
+
|
28
|
+
puts "Write: #{path}\n"
|
29
|
+
ref_file = File.join(@root, path)
|
30
|
+
File.open(ref_file) do |input|
|
31
|
+
File.open(outfile, "w") do |output|
|
32
|
+
dump_object(input, output, path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def dump_object(input, output, path)
|
39
|
+
obj = GitObjectBrowser::Models::Ref.new(input)
|
40
|
+
wrapped = GitObjectBrowser::Models::WrappedObject.new(nil, path, obj)
|
41
|
+
output << JSON.pretty_generate(wrapped.to_hash)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -4,7 +4,10 @@ module GitObjectBrowser
|
|
4
4
|
def execute
|
5
5
|
host = '127.0.0.1'
|
6
6
|
port = 8080
|
7
|
-
dump =
|
7
|
+
dump = nil
|
8
|
+
step = nil
|
9
|
+
diff_dir = nil
|
10
|
+
nextstep = false
|
8
11
|
opts = OptionParser.new do |opts|
|
9
12
|
opts.on('-p', '--port PORT', 'port number') do |value|
|
10
13
|
port = value.to_i if 0 < value.to_i
|
@@ -12,8 +15,17 @@ module GitObjectBrowser
|
|
12
15
|
opts.on('-b', '--bind HOST', 'address to bind') do |value|
|
13
16
|
host = value
|
14
17
|
end
|
15
|
-
opts.on('-d', '--dump', 'dump
|
16
|
-
dump =
|
18
|
+
opts.on('-d', '--dump PATH', 'dump .git as JSON and HTMLs') do |value|
|
19
|
+
dump = value
|
20
|
+
end
|
21
|
+
opts.on('--step STEP', 'dump JSONs into sub directory') do |value|
|
22
|
+
step = value
|
23
|
+
end
|
24
|
+
opts.on('--diff OLD_JSON_DIR', 'dump JSONs with diff data') do |value|
|
25
|
+
diff_dir = value
|
26
|
+
end
|
27
|
+
opts.on('--next', 'same with --step step${N} --diff step${N-1}') do |value|
|
28
|
+
nextstep = true
|
17
29
|
end
|
18
30
|
opts.on_tail("-h", "--help", "show this help.") do
|
19
31
|
puts opts
|
@@ -26,10 +38,14 @@ module GitObjectBrowser
|
|
26
38
|
opts.parse!(ARGV)
|
27
39
|
end
|
28
40
|
target = find_target(ARGV[0])
|
29
|
-
if dump
|
30
|
-
GitObjectBrowser::Dumper::Main.execute(target)
|
31
|
-
else
|
41
|
+
if dump.nil?
|
32
42
|
GitObjectBrowser::Server::Main.execute(target, host, port)
|
43
|
+
else
|
44
|
+
if nextstep
|
45
|
+
step = :next
|
46
|
+
diff_dir = nil
|
47
|
+
end
|
48
|
+
GitObjectBrowser::Dumper::Main.execute(target, dump, step, diff_dir)
|
33
49
|
end
|
34
50
|
end
|
35
51
|
|
@@ -18,11 +18,13 @@ module GitObjectBrowser
|
|
18
18
|
relpath = File.join(@path, file).gsub(%r{\A/}, '')
|
19
19
|
entry = {}
|
20
20
|
if File.directory?(file)
|
21
|
-
entry[:type] =
|
21
|
+
entry[:type] = 'directory'
|
22
22
|
elsif File.symlink?(file)
|
23
|
-
entry[:type] =
|
23
|
+
entry[:type] = 'symlink'
|
24
24
|
elsif Ref::path?(relpath)
|
25
25
|
entry[:type] = 'ref'
|
26
|
+
elsif Reflog::path?(relpath)
|
27
|
+
entry[:type] = 'reflog'
|
26
28
|
elsif InfoRefs::path?(relpath)
|
27
29
|
entry[:type] = 'info_refs'
|
28
30
|
elsif PackedRefs::path?(relpath)
|
@@ -40,7 +42,7 @@ module GitObjectBrowser
|
|
40
42
|
entries << entry
|
41
43
|
end
|
42
44
|
end
|
43
|
-
order = %w{directory ref info_refs packed_refs index object file symlink}
|
45
|
+
order = %w{directory ref reflog info_refs packed_refs index object file symlink}
|
44
46
|
entries.sort do |a,b|
|
45
47
|
(order.index(a[:type]) <=> order.index(b[:type])).nonzero? ||
|
46
48
|
a[:basename] <=> b[:basename]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module GitObjectBrowser
|
3
|
+
|
4
|
+
module Models
|
5
|
+
|
6
|
+
class GitDate
|
7
|
+
attr_reader :unixtime, :timezone, :date
|
8
|
+
|
9
|
+
def initialize(unixtime, timezone)
|
10
|
+
@unixtime = unixtime
|
11
|
+
@timezone = timezone
|
12
|
+
@date = DateTime.strptime(unixtime.to_s, '%s').new_offset(parse_timezone(timezone))
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_timezone(timezone)
|
16
|
+
timezone = '+00:00' if timezone == 'Z'
|
17
|
+
return Rational(0, 24) unless timezone =~ /(\+|-)?(\d\d):?(\d\d)/
|
18
|
+
Rational($2.to_i, 24) + Rational($3, 60) * (($1 == '-') ? -1 : 1)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
@date.iso8601
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,46 +4,142 @@ module GitObjectBrowser
|
|
4
4
|
module Models
|
5
5
|
|
6
6
|
# v2
|
7
|
-
# signature
|
8
|
-
# version
|
9
|
-
# fanout
|
10
|
-
# sha1
|
11
|
-
#
|
12
|
-
# offset
|
7
|
+
# signature 4bytes
|
8
|
+
# version 4bytes
|
9
|
+
# fanout 4bytes * 256
|
10
|
+
# sha1 20bytes * fanout[255]
|
11
|
+
# crc32 4bytes * fanout[255]
|
12
|
+
# offset 4bytes * fanout[255]
|
13
|
+
# pack sha1 20bytes
|
14
|
+
# index sha1 20bytes
|
13
15
|
class PackIndex < Bindata
|
16
|
+
attr_reader :entries
|
17
|
+
|
18
|
+
PER_PAGE = 200
|
14
19
|
|
15
20
|
def initialize(input)
|
16
21
|
super(input)
|
17
22
|
end
|
18
23
|
|
19
|
-
def parse
|
24
|
+
def parse(order, page)
|
20
25
|
parse_fanout
|
26
|
+
@page = page
|
27
|
+
@order = order
|
28
|
+
|
29
|
+
if order == 'digest'
|
30
|
+
parse_digest
|
31
|
+
elsif order == 'sha1'
|
32
|
+
parse_sha1_page
|
33
|
+
set_fanouts
|
34
|
+
else
|
35
|
+
@order = 'offset'
|
36
|
+
parse_offset_page
|
37
|
+
set_fanouts
|
38
|
+
end
|
39
|
+
|
40
|
+
# XXX Doesn't support packfile >= 2 GiB
|
41
|
+
# x.times do |i|
|
42
|
+
# puts "offset[#{ i }] = #{ hex(8) }"
|
43
|
+
# end
|
44
|
+
|
45
|
+
seek(4 + 4 + 4 * 256 + (20 + 4 + 4) * @fanout[255])
|
46
|
+
@packfile_sha1 = hex(20)
|
47
|
+
@index_sha1 = hex(20)
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
21
51
|
|
52
|
+
def empty?
|
53
|
+
@entries.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_fanouts
|
57
|
+
@fanout.each_with_index do |fo, i|
|
58
|
+
entry = @entries.select { |entry| entry[:index] == fo }
|
59
|
+
next if entry.empty?
|
60
|
+
entry = entry.first
|
61
|
+
entry[:fanout_min] = entry[:fanout_min] ? [entry[:fanout_min], i].min : i
|
62
|
+
entry[:fanout_max] = entry[:fanout_max] ? [entry[:fanout_max], i].max : i
|
63
|
+
end
|
64
|
+
|
65
|
+
@entries.each do |entry|
|
66
|
+
next unless entry[:fanout_min]
|
67
|
+
entry[:fanout_min] = '%02x' % entry[:fanout_min]
|
68
|
+
entry[:fanout_max] = '%02x' % entry[:fanout_max]
|
69
|
+
entry.delete(:fanout_max) if entry[:fanout_min] == entry[:fanout_max]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
private :set_fanouts
|
73
|
+
|
74
|
+
def parse_digest
|
75
|
+
index = 0
|
22
76
|
@entries = []
|
23
|
-
@fanout[255]
|
24
|
-
|
25
|
-
|
77
|
+
while index <= @fanout[255] - 1
|
78
|
+
@entries << hex(20)
|
79
|
+
index += PER_PAGE
|
80
|
+
skip(20 * (PER_PAGE - 1)) if index <= @fanout[255] - 1
|
81
|
+
end
|
82
|
+
end
|
83
|
+
private :parse_digest
|
84
|
+
|
85
|
+
def parse_sha1_page
|
86
|
+
@entries = []
|
87
|
+
|
88
|
+
index_start = PER_PAGE * (@page - 1)
|
89
|
+
index_end = PER_PAGE * @page - 1
|
90
|
+
index_last = @fanout[255] - 1
|
91
|
+
return if index_last < index_start
|
92
|
+
index_end = index_last if index_last <= index_end
|
93
|
+
entry_count = index_end - index_start + 1
|
94
|
+
|
95
|
+
skip(20 * index_start)
|
96
|
+
entry_count.times do |i|
|
97
|
+
entry = { :index => index_start + i, :sha1 => hex(20) }
|
26
98
|
@entries << entry
|
27
99
|
end
|
100
|
+
skip(20 * (index_last - index_end))
|
28
101
|
|
29
|
-
|
102
|
+
skip(4 * index_start)
|
103
|
+
entry_count.times do |i|
|
30
104
|
@entries[i][:crc32] = hex(4)
|
31
105
|
end
|
106
|
+
skip(4 * (index_last - index_end))
|
32
107
|
|
33
|
-
|
108
|
+
skip(4 * index_start)
|
109
|
+
entry_count.times do |i|
|
34
110
|
@entries[i][:offset] = int
|
35
111
|
end
|
112
|
+
end
|
113
|
+
private :parse_sha1_page
|
36
114
|
|
37
|
-
|
38
|
-
|
39
|
-
# puts "offset[#{ i }] = #{ hex(8) }"
|
40
|
-
# end
|
115
|
+
def parse_offset_page
|
116
|
+
@entries = []
|
41
117
|
|
42
|
-
|
43
|
-
@
|
118
|
+
index_start = PER_PAGE * (@page - 1)
|
119
|
+
index_end = PER_PAGE * @page - 1
|
120
|
+
index_last = @fanout[255] - 1
|
121
|
+
return if index_last < index_start
|
122
|
+
index_end = index_last if index_last <= index_end
|
123
|
+
entry_count = index_end - index_start + 1
|
44
124
|
|
45
|
-
|
125
|
+
# load all offsets
|
126
|
+
skip((20 + 4) * @fanout[255])
|
127
|
+
offsets = []
|
128
|
+
@fanout[255].times do |i|
|
129
|
+
offsets << [i, int]
|
130
|
+
end
|
131
|
+
|
132
|
+
offsets = offsets.sort { |a,b| a[1] <=> b[1] }[index_start, entry_count]
|
133
|
+
offsets.each do |offset|
|
134
|
+
@entries << { :index => offset[0], :offset => offset[1] }
|
135
|
+
end
|
136
|
+
|
137
|
+
@entries.each do |entry|
|
138
|
+
entry[:sha1] = get_sha1_hex(entry[:index])
|
139
|
+
entry[:crc32] = get_crc32_hex(entry[:index])
|
140
|
+
end
|
46
141
|
end
|
142
|
+
private :parse_offset_page
|
47
143
|
|
48
144
|
def parse_fanout
|
49
145
|
return if @fanout
|
@@ -72,11 +168,11 @@ module GitObjectBrowser
|
|
72
168
|
|
73
169
|
while lo < hi
|
74
170
|
mid = (lo + hi) / 2
|
75
|
-
mid_sha1 =
|
171
|
+
mid_sha1 = get_sha1_raw(mid)
|
76
172
|
if mid_sha1 == sha1
|
77
173
|
return {
|
78
174
|
:sha1 => sha1_hex,
|
79
|
-
:
|
175
|
+
:crc32 => get_crc32_hex(mid),
|
80
176
|
:offset => get_offset(mid)
|
81
177
|
}
|
82
178
|
elsif sha1 < mid_sha1
|
@@ -88,7 +184,7 @@ module GitObjectBrowser
|
|
88
184
|
nil
|
89
185
|
end
|
90
186
|
|
91
|
-
def
|
187
|
+
def get_sha1_raw(pos)
|
92
188
|
if @version == 2
|
93
189
|
seek(4 + 4 + 4 * 256 + 20 * pos)
|
94
190
|
else
|
@@ -97,7 +193,16 @@ module GitObjectBrowser
|
|
97
193
|
raw(20)
|
98
194
|
end
|
99
195
|
|
100
|
-
def
|
196
|
+
def get_sha1_hex(pos)
|
197
|
+
if @version == 2
|
198
|
+
seek(4 + 4 + 4 * 256 + 20 * pos)
|
199
|
+
else
|
200
|
+
raise "FIXME version 1"
|
201
|
+
end
|
202
|
+
hex(20)
|
203
|
+
end
|
204
|
+
|
205
|
+
def get_crc32_hex(pos)
|
101
206
|
if @version == 2
|
102
207
|
seek(4 + 4 + 4 * 256 + 20 * @fanout[255] + 4 * pos)
|
103
208
|
else
|
@@ -116,18 +221,27 @@ module GitObjectBrowser
|
|
116
221
|
end
|
117
222
|
|
118
223
|
def self.path?(relpath)
|
119
|
-
return relpath =~ %r{\Aobjects/pack/pack-[0-9a-f]{40}
|
224
|
+
return relpath =~ %r{\Aobjects/pack/pack-[0-9a-f]{40}\.idx\z}
|
120
225
|
end
|
121
226
|
|
122
227
|
def to_hash
|
123
228
|
return {
|
124
|
-
:fanout => @fanout,
|
125
229
|
:entries => @entries,
|
126
230
|
:packfile_sha1 => @packfile_sha1,
|
127
231
|
:index_sha1 => @index_sha1,
|
128
232
|
}
|
129
233
|
end
|
130
234
|
|
235
|
+
# Extended pagenation data for Git Object Browser.
|
236
|
+
def page_data
|
237
|
+
return {
|
238
|
+
:per_page => PER_PAGE,
|
239
|
+
:entry_count => @fanout[255],
|
240
|
+
:page => @page,
|
241
|
+
:order => @order
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
131
245
|
def load_object_types(input)
|
132
246
|
obj = PackedObject.new(self, input)
|
133
247
|
@entries.each do |entry|
|