git-object-browser 0.0.6 → 0.0.7
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.
- 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|
|