jit 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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