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.
Files changed (95) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.txt +674 -0
  3. data/bin/jit +21 -0
  4. data/lib/color.rb +32 -0
  5. data/lib/command.rb +62 -0
  6. data/lib/command/add.rb +65 -0
  7. data/lib/command/base.rb +92 -0
  8. data/lib/command/branch.rb +199 -0
  9. data/lib/command/checkout.rb +104 -0
  10. data/lib/command/cherry_pick.rb +51 -0
  11. data/lib/command/commit.rb +86 -0
  12. data/lib/command/config.rb +126 -0
  13. data/lib/command/diff.rb +114 -0
  14. data/lib/command/fetch.rb +116 -0
  15. data/lib/command/init.rb +41 -0
  16. data/lib/command/log.rb +188 -0
  17. data/lib/command/merge.rb +148 -0
  18. data/lib/command/push.rb +172 -0
  19. data/lib/command/receive_pack.rb +92 -0
  20. data/lib/command/remote.rb +55 -0
  21. data/lib/command/reset.rb +64 -0
  22. data/lib/command/rev_list.rb +33 -0
  23. data/lib/command/revert.rb +69 -0
  24. data/lib/command/rm.rb +105 -0
  25. data/lib/command/shared/fast_forward.rb +19 -0
  26. data/lib/command/shared/print_diff.rb +116 -0
  27. data/lib/command/shared/receive_objects.rb +37 -0
  28. data/lib/command/shared/remote_agent.rb +44 -0
  29. data/lib/command/shared/remote_client.rb +82 -0
  30. data/lib/command/shared/send_objects.rb +24 -0
  31. data/lib/command/shared/sequencing.rb +146 -0
  32. data/lib/command/shared/write_commit.rb +167 -0
  33. data/lib/command/status.rb +210 -0
  34. data/lib/command/upload_pack.rb +54 -0
  35. data/lib/config.rb +240 -0
  36. data/lib/config/stack.rb +42 -0
  37. data/lib/database.rb +112 -0
  38. data/lib/database/author.rb +27 -0
  39. data/lib/database/backends.rb +57 -0
  40. data/lib/database/blob.rb +24 -0
  41. data/lib/database/commit.rb +70 -0
  42. data/lib/database/entry.rb +7 -0
  43. data/lib/database/loose.rb +70 -0
  44. data/lib/database/packed.rb +75 -0
  45. data/lib/database/tree.rb +77 -0
  46. data/lib/database/tree_diff.rb +88 -0
  47. data/lib/diff.rb +46 -0
  48. data/lib/diff/combined.rb +72 -0
  49. data/lib/diff/hunk.rb +64 -0
  50. data/lib/diff/myers.rb +90 -0
  51. data/lib/editor.rb +59 -0
  52. data/lib/index.rb +212 -0
  53. data/lib/index/checksum.rb +44 -0
  54. data/lib/index/entry.rb +91 -0
  55. data/lib/lockfile.rb +55 -0
  56. data/lib/merge/bases.rb +38 -0
  57. data/lib/merge/common_ancestors.rb +77 -0
  58. data/lib/merge/diff3.rb +156 -0
  59. data/lib/merge/inputs.rb +42 -0
  60. data/lib/merge/resolve.rb +178 -0
  61. data/lib/pack.rb +45 -0
  62. data/lib/pack/compressor.rb +83 -0
  63. data/lib/pack/delta.rb +58 -0
  64. data/lib/pack/entry.rb +54 -0
  65. data/lib/pack/expander.rb +54 -0
  66. data/lib/pack/index.rb +100 -0
  67. data/lib/pack/indexer.rb +200 -0
  68. data/lib/pack/numbers.rb +79 -0
  69. data/lib/pack/reader.rb +98 -0
  70. data/lib/pack/stream.rb +80 -0
  71. data/lib/pack/unpacker.rb +62 -0
  72. data/lib/pack/window.rb +47 -0
  73. data/lib/pack/writer.rb +92 -0
  74. data/lib/pack/xdelta.rb +118 -0
  75. data/lib/pager.rb +24 -0
  76. data/lib/progress.rb +78 -0
  77. data/lib/refs.rb +260 -0
  78. data/lib/remotes.rb +82 -0
  79. data/lib/remotes/protocol.rb +82 -0
  80. data/lib/remotes/refspec.rb +70 -0
  81. data/lib/remotes/remote.rb +57 -0
  82. data/lib/repository.rb +64 -0
  83. data/lib/repository/divergence.rb +21 -0
  84. data/lib/repository/hard_reset.rb +35 -0
  85. data/lib/repository/inspector.rb +49 -0
  86. data/lib/repository/migration.rb +168 -0
  87. data/lib/repository/pending_commit.rb +60 -0
  88. data/lib/repository/sequencer.rb +118 -0
  89. data/lib/repository/status.rb +98 -0
  90. data/lib/rev_list.rb +244 -0
  91. data/lib/revision.rb +155 -0
  92. data/lib/sorted_hash.rb +17 -0
  93. data/lib/temp_file.rb +34 -0
  94. data/lib/workspace.rb +107 -0
  95. metadata +103 -9
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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