jit 0.0.0 → 1.0.0
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 +5 -5
- data/LICENSE.txt +674 -0
- data/bin/jit +21 -0
- data/lib/color.rb +32 -0
- data/lib/command.rb +62 -0
- data/lib/command/add.rb +65 -0
- data/lib/command/base.rb +92 -0
- data/lib/command/branch.rb +199 -0
- data/lib/command/checkout.rb +104 -0
- data/lib/command/cherry_pick.rb +51 -0
- data/lib/command/commit.rb +86 -0
- data/lib/command/config.rb +126 -0
- data/lib/command/diff.rb +114 -0
- data/lib/command/fetch.rb +116 -0
- data/lib/command/init.rb +41 -0
- data/lib/command/log.rb +188 -0
- data/lib/command/merge.rb +148 -0
- data/lib/command/push.rb +172 -0
- data/lib/command/receive_pack.rb +92 -0
- data/lib/command/remote.rb +55 -0
- data/lib/command/reset.rb +64 -0
- data/lib/command/rev_list.rb +33 -0
- data/lib/command/revert.rb +69 -0
- data/lib/command/rm.rb +105 -0
- data/lib/command/shared/fast_forward.rb +19 -0
- data/lib/command/shared/print_diff.rb +116 -0
- data/lib/command/shared/receive_objects.rb +37 -0
- data/lib/command/shared/remote_agent.rb +44 -0
- data/lib/command/shared/remote_client.rb +82 -0
- data/lib/command/shared/send_objects.rb +24 -0
- data/lib/command/shared/sequencing.rb +146 -0
- data/lib/command/shared/write_commit.rb +167 -0
- data/lib/command/status.rb +210 -0
- data/lib/command/upload_pack.rb +54 -0
- data/lib/config.rb +240 -0
- data/lib/config/stack.rb +42 -0
- data/lib/database.rb +112 -0
- data/lib/database/author.rb +27 -0
- data/lib/database/backends.rb +57 -0
- data/lib/database/blob.rb +24 -0
- data/lib/database/commit.rb +70 -0
- data/lib/database/entry.rb +7 -0
- data/lib/database/loose.rb +70 -0
- data/lib/database/packed.rb +75 -0
- data/lib/database/tree.rb +77 -0
- data/lib/database/tree_diff.rb +88 -0
- data/lib/diff.rb +46 -0
- data/lib/diff/combined.rb +72 -0
- data/lib/diff/hunk.rb +64 -0
- data/lib/diff/myers.rb +90 -0
- data/lib/editor.rb +59 -0
- data/lib/index.rb +212 -0
- data/lib/index/checksum.rb +44 -0
- data/lib/index/entry.rb +91 -0
- data/lib/lockfile.rb +55 -0
- data/lib/merge/bases.rb +38 -0
- data/lib/merge/common_ancestors.rb +77 -0
- data/lib/merge/diff3.rb +156 -0
- data/lib/merge/inputs.rb +42 -0
- data/lib/merge/resolve.rb +178 -0
- data/lib/pack.rb +45 -0
- data/lib/pack/compressor.rb +83 -0
- data/lib/pack/delta.rb +58 -0
- data/lib/pack/entry.rb +54 -0
- data/lib/pack/expander.rb +54 -0
- data/lib/pack/index.rb +100 -0
- data/lib/pack/indexer.rb +200 -0
- data/lib/pack/numbers.rb +79 -0
- data/lib/pack/reader.rb +98 -0
- data/lib/pack/stream.rb +80 -0
- data/lib/pack/unpacker.rb +62 -0
- data/lib/pack/window.rb +47 -0
- data/lib/pack/writer.rb +92 -0
- data/lib/pack/xdelta.rb +118 -0
- data/lib/pager.rb +24 -0
- data/lib/progress.rb +78 -0
- data/lib/refs.rb +260 -0
- data/lib/remotes.rb +82 -0
- data/lib/remotes/protocol.rb +82 -0
- data/lib/remotes/refspec.rb +70 -0
- data/lib/remotes/remote.rb +57 -0
- data/lib/repository.rb +64 -0
- data/lib/repository/divergence.rb +21 -0
- data/lib/repository/hard_reset.rb +35 -0
- data/lib/repository/inspector.rb +49 -0
- data/lib/repository/migration.rb +168 -0
- data/lib/repository/pending_commit.rb +60 -0
- data/lib/repository/sequencer.rb +118 -0
- data/lib/repository/status.rb +98 -0
- data/lib/rev_list.rb +244 -0
- data/lib/revision.rb +155 -0
- data/lib/sorted_hash.rb +17 -0
- data/lib/temp_file.rb +34 -0
- data/lib/workspace.rb +107 -0
- metadata +103 -9
data/lib/pack/numbers.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Pack
|
2
|
+
module Numbers
|
3
|
+
|
4
|
+
module VarIntLE
|
5
|
+
def self.write(value, shift)
|
6
|
+
bytes = []
|
7
|
+
mask = 2 ** shift - 1
|
8
|
+
|
9
|
+
until value <= mask
|
10
|
+
bytes.push(0x80 | value & mask)
|
11
|
+
value >>= shift
|
12
|
+
|
13
|
+
mask, shift = 0x7f, 7
|
14
|
+
end
|
15
|
+
|
16
|
+
bytes + [value]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.read(input, shift)
|
20
|
+
first = input.readbyte
|
21
|
+
value = first & (2 ** shift - 1)
|
22
|
+
|
23
|
+
byte = first
|
24
|
+
|
25
|
+
until byte < 0x80
|
26
|
+
byte = input.readbyte
|
27
|
+
value |= (byte & 0x7f) << shift
|
28
|
+
shift += 7
|
29
|
+
end
|
30
|
+
|
31
|
+
[first, value]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module VarIntBE
|
36
|
+
def self.write(value)
|
37
|
+
bytes = [value & 0x7f]
|
38
|
+
|
39
|
+
until (value >>= 7) == 0
|
40
|
+
value -= 1
|
41
|
+
bytes.push(0x80 | value & 0x7f)
|
42
|
+
end
|
43
|
+
|
44
|
+
bytes.reverse.pack("C*")
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.read(input)
|
48
|
+
byte = input.readbyte
|
49
|
+
value = byte & 0x7f
|
50
|
+
|
51
|
+
until byte < 0x80
|
52
|
+
byte = input.readbyte
|
53
|
+
value = ((value + 1) << 7) | (byte & 0x7f)
|
54
|
+
end
|
55
|
+
|
56
|
+
value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module PackedInt56LE
|
61
|
+
def self.write(value)
|
62
|
+
bytes = (0..6).map { |i| (value >> (8 * i)) & 0xff }
|
63
|
+
|
64
|
+
flags = bytes.map.with_index { |b, i| b == 0 ? 0 : 1 << i }
|
65
|
+
header = flags.reduce(0) { |a, b| a | b }
|
66
|
+
|
67
|
+
[header] + bytes.reject { |b| b == 0 }
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.read(input, header)
|
71
|
+
flags = (0..6).reject { |i| header & (1 << i) == 0 }
|
72
|
+
bytes = flags.map { |i| input.readbyte << (8 * i) }
|
73
|
+
|
74
|
+
bytes.reduce(0) { |a, b| a | b }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
data/lib/pack/reader.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require "zlib"
|
2
|
+
|
3
|
+
require_relative "./expander"
|
4
|
+
require_relative "./numbers"
|
5
|
+
|
6
|
+
module Pack
|
7
|
+
class Reader
|
8
|
+
|
9
|
+
attr_reader :count
|
10
|
+
|
11
|
+
def initialize(input)
|
12
|
+
@input = input
|
13
|
+
end
|
14
|
+
|
15
|
+
def read_header
|
16
|
+
data = @input.read(HEADER_SIZE)
|
17
|
+
signature, version, @count = data.unpack(HEADER_FORMAT)
|
18
|
+
|
19
|
+
unless signature == SIGNATURE
|
20
|
+
raise InvalidPack, "bad pack signature: #{ signature }"
|
21
|
+
end
|
22
|
+
|
23
|
+
unless version == VERSION
|
24
|
+
raise InvalidPack, "unsupported pack version: #{ version }"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_record
|
29
|
+
type, _ = read_record_header
|
30
|
+
|
31
|
+
case type
|
32
|
+
when COMMIT, TREE, BLOB
|
33
|
+
Record.new(TYPE_CODES.key(type), read_zlib_stream)
|
34
|
+
when OFS_DELTA
|
35
|
+
read_ofs_delta
|
36
|
+
when REF_DELTA
|
37
|
+
read_ref_delta
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def read_info
|
42
|
+
type, size = read_record_header
|
43
|
+
|
44
|
+
case type
|
45
|
+
when COMMIT, TREE, BLOB
|
46
|
+
Record.new(TYPE_CODES.key(type), size)
|
47
|
+
|
48
|
+
when OFS_DELTA
|
49
|
+
delta = read_ofs_delta
|
50
|
+
size = Expander.new(delta.delta_data).target_size
|
51
|
+
|
52
|
+
OfsDelta.new(delta.base_ofs, size)
|
53
|
+
|
54
|
+
when REF_DELTA
|
55
|
+
delta = read_ref_delta
|
56
|
+
size = Expander.new(delta.delta_data).target_size
|
57
|
+
|
58
|
+
RefDelta.new(delta.base_oid, size)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def read_record_header
|
65
|
+
byte, size = Numbers::VarIntLE.read(@input, 4)
|
66
|
+
type = (byte >> 4) & 0x7
|
67
|
+
|
68
|
+
[type, size]
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_ofs_delta
|
72
|
+
offset = Numbers::VarIntBE.read(@input)
|
73
|
+
OfsDelta.new(offset, read_zlib_stream)
|
74
|
+
end
|
75
|
+
|
76
|
+
def read_ref_delta
|
77
|
+
base_oid = @input.read(20).unpack("H40").first
|
78
|
+
RefDelta.new(base_oid, read_zlib_stream)
|
79
|
+
end
|
80
|
+
|
81
|
+
def read_zlib_stream
|
82
|
+
stream = Zlib::Inflate.new
|
83
|
+
string = ""
|
84
|
+
total = 0
|
85
|
+
|
86
|
+
until stream.finished?
|
87
|
+
data = @input.read_nonblock(256)
|
88
|
+
total += data.bytesize
|
89
|
+
|
90
|
+
string.concat(stream.inflate(data))
|
91
|
+
end
|
92
|
+
@input.seek(stream.total_in - total, IO::SEEK_CUR)
|
93
|
+
|
94
|
+
string
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
data/lib/pack/stream.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
|
3
|
+
module Pack
|
4
|
+
class Stream
|
5
|
+
|
6
|
+
attr_reader :digest, :offset
|
7
|
+
|
8
|
+
def initialize(input, buffer = "")
|
9
|
+
@input = input
|
10
|
+
@digest = Digest::SHA1.new
|
11
|
+
@offset = 0
|
12
|
+
@buffer = new_byte_string.concat(buffer)
|
13
|
+
@capture = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def capture
|
17
|
+
@capture = new_byte_string
|
18
|
+
result = [yield, @capture]
|
19
|
+
|
20
|
+
@digest.update(@capture)
|
21
|
+
@capture = nil
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
26
|
+
def verify_checksum
|
27
|
+
unless read_buffered(20) == @digest.digest
|
28
|
+
raise InvalidPack, "Checksum does not match value read from pack"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def read(size)
|
33
|
+
data = read_buffered(size)
|
34
|
+
update_state(data)
|
35
|
+
data
|
36
|
+
end
|
37
|
+
|
38
|
+
def read_nonblock(size)
|
39
|
+
data = read_buffered(size, false)
|
40
|
+
update_state(data)
|
41
|
+
data
|
42
|
+
end
|
43
|
+
|
44
|
+
def readbyte
|
45
|
+
read(1).bytes.first
|
46
|
+
end
|
47
|
+
|
48
|
+
def seek(amount, whence = IO::SEEK_SET)
|
49
|
+
return unless amount < 0
|
50
|
+
|
51
|
+
data = @capture.slice!(amount .. -1)
|
52
|
+
@buffer.prepend(data)
|
53
|
+
@offset += amount
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def new_byte_string
|
59
|
+
String.new("", :encoding => Encoding::ASCII_8BIT)
|
60
|
+
end
|
61
|
+
|
62
|
+
def read_buffered(size, block = true)
|
63
|
+
from_buf = @buffer.slice!(0, size)
|
64
|
+
needed = size - from_buf.bytesize
|
65
|
+
from_io = block ? @input.read(needed) : @input.read_nonblock(needed)
|
66
|
+
|
67
|
+
from_buf.concat(from_io.to_s)
|
68
|
+
|
69
|
+
rescue EOFError, Errno::EWOULDBLOCK
|
70
|
+
from_buf
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_state(data)
|
74
|
+
@digest.update(data) unless @capture
|
75
|
+
@offset += data.bytesize
|
76
|
+
@capture&.concat(data)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require_relative "./expander"
|
2
|
+
|
3
|
+
module Pack
|
4
|
+
class Unpacker
|
5
|
+
|
6
|
+
def initialize(database, reader, stream, progress)
|
7
|
+
@database = database
|
8
|
+
@reader = reader
|
9
|
+
@stream = stream
|
10
|
+
@progress = progress
|
11
|
+
@offsets = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_pack
|
15
|
+
@progress&.start("Unpacking objects", @reader.count)
|
16
|
+
|
17
|
+
@reader.count.times do
|
18
|
+
process_record
|
19
|
+
@progress&.tick(@stream.offset)
|
20
|
+
end
|
21
|
+
@progress&.stop
|
22
|
+
|
23
|
+
@stream.verify_checksum
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def process_record
|
29
|
+
offset = @stream.offset
|
30
|
+
record, _ = @stream.capture { @reader.read_record }
|
31
|
+
|
32
|
+
record = resolve(record, offset)
|
33
|
+
@database.store(record)
|
34
|
+
@offsets[offset] = record.oid
|
35
|
+
end
|
36
|
+
|
37
|
+
def resolve(record, offset)
|
38
|
+
case record
|
39
|
+
when Record then record
|
40
|
+
when OfsDelta then resolve_ofs_delta(record, offset)
|
41
|
+
when RefDelta then resolve_ref_delta(record)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def resolve_ofs_delta(delta, offset)
|
46
|
+
oid = @offsets[offset - delta.base_ofs]
|
47
|
+
resolve_delta(oid, delta.delta_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def resolve_ref_delta(delta)
|
51
|
+
resolve_delta(delta.base_oid, delta.delta_data)
|
52
|
+
end
|
53
|
+
|
54
|
+
def resolve_delta(oid, delta_data)
|
55
|
+
base = @database.load_raw(oid)
|
56
|
+
data = Expander.expand(base.data, delta_data)
|
57
|
+
|
58
|
+
Record.new(base.type, data)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/pack/window.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Pack
|
4
|
+
class Window
|
5
|
+
|
6
|
+
Unpacked = Struct.new(:entry, :data) do
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :entry, :type, :size, :delta, :depth
|
9
|
+
|
10
|
+
attr_accessor :delta_index
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(size)
|
14
|
+
@objects = Array.new(size)
|
15
|
+
@offset = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(entry, data)
|
19
|
+
unpacked = Unpacked.new(entry, data)
|
20
|
+
@objects[@offset] = unpacked
|
21
|
+
@offset = wrap(@offset + 1)
|
22
|
+
|
23
|
+
unpacked
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
cursor = wrap(@offset - 2)
|
28
|
+
limit = wrap(@offset - 1)
|
29
|
+
|
30
|
+
loop do
|
31
|
+
break if cursor == limit
|
32
|
+
|
33
|
+
unpacked = @objects[cursor]
|
34
|
+
yield unpacked if unpacked
|
35
|
+
|
36
|
+
cursor = wrap(cursor - 1)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def wrap(offset)
|
43
|
+
offset % @objects.size
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/lib/pack/writer.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require "digest/sha1"
|
2
|
+
require "zlib"
|
3
|
+
|
4
|
+
require_relative "./compressor"
|
5
|
+
require_relative "./entry"
|
6
|
+
require_relative "./numbers"
|
7
|
+
|
8
|
+
module Pack
|
9
|
+
class Writer
|
10
|
+
|
11
|
+
def initialize(output, database, options = {})
|
12
|
+
@output = output
|
13
|
+
@database = database
|
14
|
+
@digest = Digest::SHA1.new
|
15
|
+
@offset = 0
|
16
|
+
|
17
|
+
@compression = options.fetch(:compression, Zlib::DEFAULT_COMPRESSION)
|
18
|
+
@allow_ofs = options[:allow_ofs]
|
19
|
+
@progress = options[:progress]
|
20
|
+
end
|
21
|
+
|
22
|
+
def write_objects(rev_list)
|
23
|
+
prepare_pack_list(rev_list)
|
24
|
+
compress_objects
|
25
|
+
write_header
|
26
|
+
write_entries
|
27
|
+
@output.write(@digest.digest)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def write(data)
|
33
|
+
@output.write(data)
|
34
|
+
@digest.update(data)
|
35
|
+
@offset += data.bytesize
|
36
|
+
end
|
37
|
+
|
38
|
+
def prepare_pack_list(rev_list)
|
39
|
+
@pack_list = []
|
40
|
+
@progress&.start("Counting objects")
|
41
|
+
|
42
|
+
rev_list.each do |object, path|
|
43
|
+
add_to_pack_list(object, path)
|
44
|
+
@progress&.tick
|
45
|
+
end
|
46
|
+
@progress&.stop
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_to_pack_list(object, path)
|
50
|
+
info = @database.load_info(object.oid)
|
51
|
+
@pack_list.push(Entry.new(object.oid, info, path, @allow_ofs))
|
52
|
+
end
|
53
|
+
|
54
|
+
def compress_objects
|
55
|
+
compressor = Compressor.new(@database, @progress)
|
56
|
+
@pack_list.each { |entry| compressor.add(entry) }
|
57
|
+
compressor.build_deltas
|
58
|
+
end
|
59
|
+
|
60
|
+
def write_header
|
61
|
+
header = [SIGNATURE, VERSION, @pack_list.size].pack(HEADER_FORMAT)
|
62
|
+
write(header)
|
63
|
+
end
|
64
|
+
|
65
|
+
def write_entries
|
66
|
+
count = @pack_list.size
|
67
|
+
@progress&.start("Writing objects", count) unless @output == STDOUT
|
68
|
+
|
69
|
+
@pack_list.each { |entry| write_entry(entry) }
|
70
|
+
@progress&.stop
|
71
|
+
end
|
72
|
+
|
73
|
+
def write_entry(entry)
|
74
|
+
write_entry(entry.delta.base) if entry.delta
|
75
|
+
|
76
|
+
return if entry.offset
|
77
|
+
entry.offset = @offset
|
78
|
+
|
79
|
+
object = entry.delta || @database.load_raw(entry.oid)
|
80
|
+
|
81
|
+
header = Numbers::VarIntLE.write(entry.packed_size, 4)
|
82
|
+
header[0] |= entry.packed_type << 4
|
83
|
+
|
84
|
+
write(header.pack("C*"))
|
85
|
+
write(entry.delta_prefix)
|
86
|
+
write(Zlib::Deflate.deflate(object.data, @compression))
|
87
|
+
|
88
|
+
@progress&.tick(@offset)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|