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,155 @@
1
+ class Revision
2
+ InvalidObject = Class.new(StandardError)
3
+ HintedError = Struct.new(:message, :hint)
4
+
5
+ Ref = Struct.new(:name) do
6
+ def resolve(context)
7
+ context.read_ref(name)
8
+ end
9
+ end
10
+
11
+ Parent = Struct.new(:rev, :n) do
12
+ def resolve(context)
13
+ context.commit_parent(rev.resolve(context), n)
14
+ end
15
+ end
16
+
17
+ Ancestor = Struct.new(:rev, :n) do
18
+ def resolve(context)
19
+ oid = rev.resolve(context)
20
+ n.times { oid = context.commit_parent(oid) }
21
+ oid
22
+ end
23
+ end
24
+
25
+ Upstream = Struct.new(:rev) do
26
+ def resolve(context)
27
+ name = context.upstream(rev.name)
28
+ context.read_ref(name)
29
+ end
30
+ end
31
+
32
+ INVALID_NAME = /
33
+ ^\.
34
+ | \/\.
35
+ | \.\.
36
+ | \/$
37
+ | \.lock$
38
+ | @\{
39
+ | [\x00-\x20*:?\[\\^~\x7f]
40
+ /x
41
+
42
+ PARENT = /^(.+)\^(\d*)$/
43
+ ANCESTOR = /^(.+)~(\d+)$/
44
+ UPSTREAM = /^(.*)@\{u(pstream)?\}$/i
45
+
46
+ HEAD = "HEAD"
47
+
48
+ REF_ALIASES = {
49
+ "@" => HEAD,
50
+ "" => HEAD
51
+ }
52
+
53
+ COMMIT = "commit"
54
+
55
+ def self.parse(revision)
56
+ if match = PARENT.match(revision)
57
+ rev = parse(match[1])
58
+ n = (match[2] == "") ? 1 : match[2].to_i
59
+ rev ? Parent.new(rev, n) : nil
60
+ elsif match = ANCESTOR.match(revision)
61
+ rev = parse(match[1])
62
+ rev ? Ancestor.new(rev, match[2].to_i) : nil
63
+ elsif match = UPSTREAM.match(revision)
64
+ rev = parse(match[1])
65
+ rev ? Upstream.new(rev) : nil
66
+ elsif valid_ref?(revision)
67
+ name = REF_ALIASES[revision] || revision
68
+ Ref.new(name)
69
+ end
70
+ end
71
+
72
+ def self.valid_ref?(revision)
73
+ INVALID_NAME =~ revision ? false : true
74
+ end
75
+
76
+ attr_reader :errors
77
+
78
+ def initialize(repo, expression)
79
+ @repo = repo
80
+ @expr = expression
81
+ @query = Revision.parse(@expr)
82
+ @errors = []
83
+ end
84
+
85
+ def resolve(type = nil)
86
+ oid = @query&.resolve(self)
87
+ oid = nil if type and not load_typed_object(oid, type)
88
+
89
+ return oid if oid
90
+
91
+ raise InvalidObject, "Not a valid object name: '#{ @expr }'."
92
+ end
93
+
94
+ def read_ref(name)
95
+ oid = @repo.refs.read_ref(name)
96
+ return oid if oid
97
+
98
+ candidates = @repo.database.prefix_match(name)
99
+ return candidates.first if candidates.size == 1
100
+
101
+ if candidates.size > 1
102
+ log_ambiguous_sha1(name, candidates)
103
+ end
104
+
105
+ nil
106
+ end
107
+
108
+ def commit_parent(oid, n = 1)
109
+ return nil unless oid
110
+
111
+ commit = load_typed_object(oid, COMMIT)
112
+ return nil unless commit
113
+
114
+ commit.parents[n - 1]
115
+ end
116
+
117
+ def upstream(branch)
118
+ branch = @repo.refs.current_ref.short_name if branch == HEAD
119
+ @repo.remotes.get_upstream(branch)
120
+ end
121
+
122
+ private
123
+
124
+ def load_typed_object(oid, type)
125
+ return nil unless oid
126
+
127
+ object = @repo.database.load(oid)
128
+
129
+ if object.type == type
130
+ object
131
+ else
132
+ message = "object #{ oid } is a #{ object.type }, not a #{ type }"
133
+ @errors.push(HintedError.new(message, []))
134
+ nil
135
+ end
136
+ end
137
+
138
+ def log_ambiguous_sha1(name, candidates)
139
+ objects = candidates.sort.map do |oid|
140
+ object = @repo.database.load(oid)
141
+ short = @repo.database.short_oid(object.oid)
142
+ info = " #{ short } #{ object.type }"
143
+
144
+ if object.type == COMMIT
145
+ "#{ info } #{ object.author.short_date } - #{ object.title_line }"
146
+ else
147
+ info
148
+ end
149
+ end
150
+
151
+ message = "short SHA1 #{ name } is ambiguous"
152
+ hint = ["The candidates are:"] + objects
153
+ @errors.push(HintedError.new(message, hint))
154
+ end
155
+ end
@@ -0,0 +1,17 @@
1
+ require "set"
2
+
3
+ class SortedHash < Hash
4
+ def initialize
5
+ super
6
+ @keys = SortedSet.new
7
+ end
8
+
9
+ def []=(key, value)
10
+ @keys.add(key)
11
+ super
12
+ end
13
+
14
+ def each
15
+ @keys.each { |key| yield [key, self[key]] }
16
+ end
17
+ end
@@ -0,0 +1,34 @@
1
+ class TempFile
2
+ TEMP_CHARS = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
3
+
4
+ def initialize(dirname, prefix)
5
+ @dirname = dirname
6
+ @path = @dirname.join(generate_temp_name(prefix))
7
+ @file = nil
8
+ end
9
+
10
+ def write(data)
11
+ open_file unless @file
12
+ @file.write(data)
13
+ end
14
+
15
+ def move(name)
16
+ @file.close
17
+ File.rename(@path, @dirname.join(name))
18
+ end
19
+
20
+ private
21
+
22
+ def generate_temp_name(prefix)
23
+ id = (1..6).map { TEMP_CHARS.sample }.join("")
24
+ "#{ prefix }_#{ id }"
25
+ end
26
+
27
+ def open_file
28
+ flags = File::RDWR | File::CREAT | File::EXCL
29
+ @file = File.open(@path, flags)
30
+ rescue Errno::ENOENT
31
+ Dir.mkdir(@dirname)
32
+ retry
33
+ end
34
+ end
@@ -0,0 +1,107 @@
1
+ require "fileutils"
2
+
3
+ class Workspace
4
+ MissingFile = Class.new(StandardError)
5
+ NoPermission = Class.new(StandardError)
6
+
7
+ IGNORE = [".", "..", ".git"]
8
+
9
+ def initialize(pathname)
10
+ @pathname = pathname
11
+ end
12
+
13
+ def list_files(path = @pathname)
14
+ relative = path.relative_path_from(@pathname)
15
+
16
+ if File.directory?(path)
17
+ filenames = Dir.entries(path) - IGNORE
18
+ filenames.flat_map { |name| list_files(path.join(name)) }
19
+ elsif File.exist?(path)
20
+ [relative]
21
+ else
22
+ raise MissingFile, "pathspec '#{ relative }' did not match any files"
23
+ end
24
+ end
25
+
26
+ def list_dir(dirname)
27
+ path = @pathname.join(dirname || "")
28
+ entries = Dir.entries(path) - IGNORE
29
+ stats = {}
30
+
31
+ entries.each do |name|
32
+ relative = path.join(name).relative_path_from(@pathname)
33
+ stats[relative.to_s] = File.stat(path.join(name))
34
+ end
35
+
36
+ stats
37
+ end
38
+
39
+ def read_file(path)
40
+ File.read(@pathname.join(path))
41
+ rescue Errno::EACCES
42
+ raise NoPermission, "open('#{ path }'): Permission denied"
43
+ end
44
+
45
+ def stat_file(path)
46
+ File.stat(@pathname.join(path))
47
+ rescue Errno::ENOENT, Errno::ENOTDIR
48
+ nil
49
+ rescue Errno::EACCES
50
+ raise NoPermission, "stat('#{ path }'): Permission denied"
51
+ end
52
+
53
+ def write_file(path, data, mode = nil, mkdir = false)
54
+ full_path = @pathname.join(path)
55
+ FileUtils.mkdir_p(full_path.dirname) if mkdir
56
+
57
+ flags = File::WRONLY | File::CREAT | File::TRUNC
58
+ File.open(full_path, flags) { |f| f.write(data) }
59
+
60
+ File.chmod(mode, full_path) if mode
61
+ end
62
+
63
+ def remove(path)
64
+ FileUtils.rm_rf(@pathname.join(path))
65
+ path.dirname.ascend { |dirname| remove_directory(dirname) }
66
+ rescue Errno::ENOENT
67
+ end
68
+
69
+ def apply_migration(migration)
70
+ apply_change_list(migration, :delete)
71
+ migration.rmdirs.sort.reverse_each { |dir| remove_directory(dir) }
72
+
73
+ migration.mkdirs.sort.each { |dir| make_directory(dir) }
74
+ apply_change_list(migration, :update)
75
+ apply_change_list(migration, :create)
76
+ end
77
+
78
+ private
79
+
80
+ def remove_directory(dirname)
81
+ Dir.rmdir(@pathname.join(dirname))
82
+ rescue Errno::ENOENT, Errno::ENOTDIR, Errno::ENOTEMPTY
83
+ end
84
+
85
+ def make_directory(dirname)
86
+ path = @pathname.join(dirname)
87
+ stat = stat_file(dirname)
88
+
89
+ File.unlink(path) if stat&.file?
90
+ Dir.mkdir(path) unless stat&.directory?
91
+ end
92
+
93
+ def apply_change_list(migration, action)
94
+ migration.changes[action].each do |filename, entry|
95
+ path = @pathname.join(filename)
96
+
97
+ FileUtils.rm_rf(path)
98
+ next if action == :delete
99
+
100
+ flags = File::WRONLY | File::CREAT | File::EXCL
101
+ data = migration.blob_data(entry.oid)
102
+
103
+ File.open(path, flags) { |file| file.write(data) }
104
+ File.chmod(entry.mode, path)
105
+ end
106
+ end
107
+ end
metadata CHANGED
@@ -1,23 +1,118 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Coglan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-08 00:00:00.000000000 Z
11
+ date: 2019-02-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: jcoglan@gmail.com
15
- executables: []
15
+ executables:
16
+ - jit
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
- files: []
19
- homepage: https://building-git.launchrock.com/
20
- licenses: []
19
+ files:
20
+ - LICENSE.txt
21
+ - bin/jit
22
+ - lib/color.rb
23
+ - lib/command.rb
24
+ - lib/command/add.rb
25
+ - lib/command/base.rb
26
+ - lib/command/branch.rb
27
+ - lib/command/checkout.rb
28
+ - lib/command/cherry_pick.rb
29
+ - lib/command/commit.rb
30
+ - lib/command/config.rb
31
+ - lib/command/diff.rb
32
+ - lib/command/fetch.rb
33
+ - lib/command/init.rb
34
+ - lib/command/log.rb
35
+ - lib/command/merge.rb
36
+ - lib/command/push.rb
37
+ - lib/command/receive_pack.rb
38
+ - lib/command/remote.rb
39
+ - lib/command/reset.rb
40
+ - lib/command/rev_list.rb
41
+ - lib/command/revert.rb
42
+ - lib/command/rm.rb
43
+ - lib/command/shared/fast_forward.rb
44
+ - lib/command/shared/print_diff.rb
45
+ - lib/command/shared/receive_objects.rb
46
+ - lib/command/shared/remote_agent.rb
47
+ - lib/command/shared/remote_client.rb
48
+ - lib/command/shared/send_objects.rb
49
+ - lib/command/shared/sequencing.rb
50
+ - lib/command/shared/write_commit.rb
51
+ - lib/command/status.rb
52
+ - lib/command/upload_pack.rb
53
+ - lib/config.rb
54
+ - lib/config/stack.rb
55
+ - lib/database.rb
56
+ - lib/database/author.rb
57
+ - lib/database/backends.rb
58
+ - lib/database/blob.rb
59
+ - lib/database/commit.rb
60
+ - lib/database/entry.rb
61
+ - lib/database/loose.rb
62
+ - lib/database/packed.rb
63
+ - lib/database/tree.rb
64
+ - lib/database/tree_diff.rb
65
+ - lib/diff.rb
66
+ - lib/diff/combined.rb
67
+ - lib/diff/hunk.rb
68
+ - lib/diff/myers.rb
69
+ - lib/editor.rb
70
+ - lib/index.rb
71
+ - lib/index/checksum.rb
72
+ - lib/index/entry.rb
73
+ - lib/lockfile.rb
74
+ - lib/merge/bases.rb
75
+ - lib/merge/common_ancestors.rb
76
+ - lib/merge/diff3.rb
77
+ - lib/merge/inputs.rb
78
+ - lib/merge/resolve.rb
79
+ - lib/pack.rb
80
+ - lib/pack/compressor.rb
81
+ - lib/pack/delta.rb
82
+ - lib/pack/entry.rb
83
+ - lib/pack/expander.rb
84
+ - lib/pack/index.rb
85
+ - lib/pack/indexer.rb
86
+ - lib/pack/numbers.rb
87
+ - lib/pack/reader.rb
88
+ - lib/pack/stream.rb
89
+ - lib/pack/unpacker.rb
90
+ - lib/pack/window.rb
91
+ - lib/pack/writer.rb
92
+ - lib/pack/xdelta.rb
93
+ - lib/pager.rb
94
+ - lib/progress.rb
95
+ - lib/refs.rb
96
+ - lib/remotes.rb
97
+ - lib/remotes/protocol.rb
98
+ - lib/remotes/refspec.rb
99
+ - lib/remotes/remote.rb
100
+ - lib/repository.rb
101
+ - lib/repository/divergence.rb
102
+ - lib/repository/hard_reset.rb
103
+ - lib/repository/inspector.rb
104
+ - lib/repository/migration.rb
105
+ - lib/repository/pending_commit.rb
106
+ - lib/repository/sequencer.rb
107
+ - lib/repository/status.rb
108
+ - lib/rev_list.rb
109
+ - lib/revision.rb
110
+ - lib/sorted_hash.rb
111
+ - lib/temp_file.rb
112
+ - lib/workspace.rb
113
+ homepage: https://shop.jcoglan.com/building-git/
114
+ licenses:
115
+ - GPL-3.0
21
116
  metadata: {}
22
117
  post_install_message:
23
118
  rdoc_options: []
@@ -34,9 +129,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
34
129
  - !ruby/object:Gem::Version
35
130
  version: '0'
36
131
  requirements: []
37
- rubyforge_project:
38
- rubygems_version: 2.6.13
132
+ rubygems_version: 3.0.1
39
133
  signing_key:
40
134
  specification_version: 4
41
- summary: Learning-oriented Git-compatible version control program
135
+ summary: The information manager from London
42
136
  test_files: []