rjgit 5.6.0.0 → 5.8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -6
- data/README.md +7 -0
- data/lib/actor.rb +10 -3
- data/lib/commit.rb +12 -3
- data/lib/git.rb +53 -54
- data/lib/java/jars/org.eclipse.jgit-5.8.1.202007141445-r.jar +0 -0
- data/lib/java/jars/org.eclipse.jgit.ssh.jsch-5.8.0.202006091008-r.jar +0 -0
- data/lib/rjgit.rb +217 -62
- data/lib/version.rb +1 -1
- metadata +4 -3
- data/lib/java/jars/org.eclipse.jgit-5.6.0.201912101111-r.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2022eac50d1c23127bf8971f5b8b60e931eb643ea0a181956de3743418c62a00
|
4
|
+
data.tar.gz: 4c7ad80622c9889ab848c15e7d1fbcce99f41f08f4900620bf65d805f2da1ea6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4da6ac22532cb16873e6d45246d7290695bc456abf73afd5eae8dced1141a14460fad41797927612585237f9e6fe7f5bcc0695dacfbe3fc9249e1134481a433
|
7
|
+
data.tar.gz: bd28dc840e9e7c2676ad4bb4aa6c7f9f16a5948d34fe8ecd5bb0930881cf5d0915d19ac62f969e1f06fd683fe3ad36e3b2d4365177a7f4dfe0ad88703af4b844
|
data/Gemfile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem
|
4
|
-
gem
|
3
|
+
gem 'mime-types', '~> 2.6.2'
|
4
|
+
gem 'rake', '>= 12.3.3'
|
5
5
|
|
6
|
-
gem 'coveralls', require: false
|
6
|
+
gem 'coveralls', '~> 0.8.23', require: false
|
7
7
|
|
8
8
|
group :test do
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem 'rspec', '~> 3.4.0'
|
10
|
+
gem 'rspec-collection_matchers', '~> 1.1.2'
|
11
|
+
gem 'simplecov'
|
12
12
|
end
|
data/README.md
CHANGED
@@ -75,6 +75,13 @@ repo.find('959329025f67539fb82e76b02782322fad032821')
|
|
75
75
|
repo.find('959329025f67539fb82e76b02782322fad032821', :commit) # Find a specific :commit, :blob, :tree, or :tag
|
76
76
|
```
|
77
77
|
|
78
|
+
### Logs
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
repo.git.log # Returns an Array of Commits constituting the log for the default branch
|
82
|
+
repo.git.log("follow-rename.txt", "HEAD", follow: true, list_renames: true) # Log for a specific path, tracking the pathname over renames. Returns an Array of TrackingCommits, which store the tracked filename: [#<RJGit::TrackingCommit:0x773014d3 @tracked_pathname="follow-rename.txt" ...>]
|
83
|
+
```
|
84
|
+
|
78
85
|
### Getting diffs
|
79
86
|
```ruby
|
80
87
|
sha1 = repo.head.id
|
data/lib/actor.rb
CHANGED
@@ -2,6 +2,7 @@ module RJGit
|
|
2
2
|
|
3
3
|
# PersonIdent in JGit
|
4
4
|
import 'org.eclipse.jgit.lib.PersonIdent'
|
5
|
+
import 'java.util.TimeZone'
|
5
6
|
|
6
7
|
class Actor
|
7
8
|
|
@@ -17,10 +18,11 @@ module RJGit
|
|
17
18
|
return self.new(name, email)
|
18
19
|
end
|
19
20
|
|
20
|
-
def initialize(name, email)
|
21
|
+
def initialize(name, email, time = nil)
|
21
22
|
@name = name
|
22
23
|
@email = email
|
23
|
-
@
|
24
|
+
@time = time
|
25
|
+
@person_ident = @time ? PersonIdent.new(name, email, time.to_java, TimeZone.getTimeZone(time.zone)) : PersonIdent.new(name, email)
|
24
26
|
end
|
25
27
|
|
26
28
|
# Create an Actor from a string.
|
@@ -43,7 +45,8 @@ module RJGit
|
|
43
45
|
# time - The Time the commit was authored or committed.
|
44
46
|
#
|
45
47
|
# Returns a String.
|
46
|
-
def output(time)
|
48
|
+
def output(time = nil)
|
49
|
+
time = time || self.time
|
47
50
|
offset = time.utc_offset / 60
|
48
51
|
"%s <%s> %d %+.2d%.2d" % [
|
49
52
|
@name,
|
@@ -52,6 +55,10 @@ module RJGit
|
|
52
55
|
offset / 60,
|
53
56
|
offset.abs % 60]
|
54
57
|
end
|
58
|
+
|
59
|
+
def time
|
60
|
+
Time.at(@person_ident.getWhen.getTime/1000)
|
61
|
+
end
|
55
62
|
|
56
63
|
end
|
57
64
|
|
data/lib/commit.rb
CHANGED
@@ -4,7 +4,7 @@ module RJGit
|
|
4
4
|
import 'org.eclipse.jgit.revwalk.RevCommit'
|
5
5
|
import 'org.eclipse.jgit.diff.DiffFormatter'
|
6
6
|
import 'org.eclipse.jgit.util.io.DisabledOutputStream'
|
7
|
-
|
7
|
+
|
8
8
|
class Commit
|
9
9
|
|
10
10
|
attr_reader :id, :parents, :actor, :committer, :authored_date, :committed_date
|
@@ -100,12 +100,12 @@ module RJGit
|
|
100
100
|
Commit.new(repository, RevWalk.new(repository).parseCommit(new_commit))
|
101
101
|
end
|
102
102
|
|
103
|
-
def self.find_head(repository)
|
103
|
+
def self.find_head(repository, ref = Constants::HEAD)
|
104
104
|
repository = RJGit.repository_type(repository)
|
105
105
|
return nil if repository.nil?
|
106
106
|
begin
|
107
107
|
walk = RevWalk.new(repository)
|
108
|
-
objhead = repository.resolve(
|
108
|
+
objhead = repository.resolve(ref)
|
109
109
|
return Commit.new(repository, walk.parseCommit(objhead))
|
110
110
|
rescue java.lang.NullPointerException => e
|
111
111
|
return nil
|
@@ -128,4 +128,13 @@ module RJGit
|
|
128
128
|
end
|
129
129
|
|
130
130
|
end
|
131
|
+
|
132
|
+
class TrackingCommit < Commit
|
133
|
+
attr_reader :tracked_pathname # This commit is part of a log for a single pathname. The tracked_pathname attribute tracks the pathname over renames.
|
134
|
+
|
135
|
+
def initialize(repository, commit, tracked_pathname = nil)
|
136
|
+
super(repository, commit)
|
137
|
+
@tracked_pathname = tracked_pathname
|
138
|
+
end
|
139
|
+
end
|
131
140
|
end
|
data/lib/git.rb
CHANGED
@@ -15,6 +15,10 @@ module RJGit
|
|
15
15
|
import 'org.eclipse.jgit.api.TransportConfigCallback'
|
16
16
|
import 'org.eclipse.jgit.transport.JschConfigSessionFactory'
|
17
17
|
import 'org.eclipse.jgit.transport.SshTransport'
|
18
|
+
import 'org.eclipse.jgit.revwalk.FollowFilter'
|
19
|
+
import 'org.eclipse.jgit.revwalk.TreeRevFilter'
|
20
|
+
|
21
|
+
class PatchApplyException < StandardError; end
|
18
22
|
|
19
23
|
class RubyGit
|
20
24
|
|
@@ -47,67 +51,58 @@ module RJGit
|
|
47
51
|
return [] unless ref
|
48
52
|
jcommits = Array.new
|
49
53
|
|
54
|
+
logs = @jgit.log
|
55
|
+
logs.add(ref)
|
56
|
+
|
50
57
|
if path && options[:follow]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
start = jcommit
|
59
|
-
end
|
60
|
-
current_path = follow_renames(start, current_path) if start
|
61
|
-
break if current_path.nil?
|
62
|
-
end
|
58
|
+
cfg = Configuration.new(nil)
|
59
|
+
cfg.add_setting('renames', true, 'diffs', nil)
|
60
|
+
follow = FollowFilter.create(path, cfg.jconfig.get(org.eclipse.jgit.diff.DiffConfig::KEY))
|
61
|
+
logs.set_rev_filter(TreeRevFilter.new(RevWalk.new(jrepo), follow))
|
62
|
+
elsif path
|
63
|
+
logs.addPath(path)
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
revwalk = RevWalk.new(jrepo)
|
73
|
-
since_commit = revwalk.parseCommit(jrepo.resolve(options[:since]))
|
74
|
-
until_commit = revwalk.parseCommit(jrepo.resolve(options[:until]))
|
75
|
-
logs.addRange(since_commit, until_commit)
|
76
|
-
end
|
77
|
-
if options[:not]
|
78
|
-
revwalk = RevWalk.new(jrepo)
|
79
|
-
options[:not].each do |ref|
|
80
|
-
logs.not(revwalk.parseCommit(jrepo.resolve(ref)))
|
81
|
-
end
|
82
|
-
end
|
83
|
-
jcommits = logs.call
|
66
|
+
logs.setMaxCount(options[:max_count]) if options[:max_count]
|
67
|
+
logs.setSkip(options[:skip]) if options[:skip]
|
68
|
+
|
69
|
+
if (options[:since] && options[:until])
|
70
|
+
revwalk = RevWalk.new(jrepo)
|
71
|
+
since_commit = revwalk.parseCommit(jrepo.resolve(options[:since]))
|
72
|
+
until_commit = revwalk.parseCommit(jrepo.resolve(options[:until]))
|
73
|
+
logs.addRange(since_commit, until_commit)
|
84
74
|
end
|
85
75
|
|
86
|
-
|
87
|
-
|
76
|
+
if options[:not]
|
77
|
+
revwalk = RevWalk.new(jrepo)
|
78
|
+
options[:not].each do |ref|
|
79
|
+
logs.not(revwalk.parseCommit(jrepo.resolve(ref)))
|
80
|
+
end
|
81
|
+
end
|
88
82
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
83
|
+
if options[:follow] && options[:list_renames]
|
84
|
+
df = DiffFormatter.new(DisabledOutputStream::INSTANCE)
|
85
|
+
df.set_repository(jrepo)
|
86
|
+
df.set_context(0)
|
87
|
+
df.set_path_filter(follow)
|
88
|
+
df.set_detect_renames(true)
|
89
|
+
prev_commit = nil
|
90
|
+
pathname = path
|
91
|
+
end
|
92
|
+
|
93
|
+
commits = logs.call.map do |jcommit|
|
94
|
+
if path && options[:follow] && options[:list_renames]
|
95
|
+
entries = df.scan(jcommit, prev_commit).to_a
|
96
|
+
pathname = entries.empty? ? pathname : entries.last.get_old_path
|
97
|
+
prev_commit = jcommit
|
98
|
+
TrackingCommit.new(jrepo, jcommit, pathname)
|
99
|
+
else
|
100
|
+
Commit.new(jrepo, jcommit)
|
106
101
|
end
|
107
102
|
end
|
108
|
-
return nil
|
109
|
-
end
|
110
103
|
|
104
|
+
commits
|
105
|
+
end
|
111
106
|
|
112
107
|
def branch_list
|
113
108
|
branch = @jgit.branch_list
|
@@ -289,7 +284,11 @@ module RJGit
|
|
289
284
|
end
|
290
285
|
|
291
286
|
def apply(input_stream)
|
292
|
-
|
287
|
+
begin
|
288
|
+
apply_result = @jgit.apply.set_patch(input_stream).call
|
289
|
+
rescue Java::OrgEclipseJgitApiErrors::PatchApplyException
|
290
|
+
raise RJGit::PatchApplyException
|
291
|
+
end
|
293
292
|
updated_files = apply_result.get_updated_files
|
294
293
|
updated_files_parsed = []
|
295
294
|
updated_files.each do |file|
|
Binary file
|
Binary file
|
data/lib/rjgit.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module RJGit
|
2
|
-
|
3
2
|
begin
|
4
3
|
require 'java'
|
5
4
|
Dir["#{File.dirname(__FILE__)}/java/jars/*.jar"].each { |jar| require jar }
|
@@ -10,7 +9,7 @@ module RJGit
|
|
10
9
|
def self.version
|
11
10
|
VERSION
|
12
11
|
end
|
13
|
-
|
12
|
+
|
14
13
|
require 'uri'
|
15
14
|
require 'stringio'
|
16
15
|
# gem requires
|
@@ -19,37 +18,42 @@ module RJGit
|
|
19
18
|
require "#{File.dirname(__FILE__)}/rjgit_helpers.rb"
|
20
19
|
# require everything else
|
21
20
|
begin
|
22
|
-
Dir["#{File.dirname(__FILE__)}/*.rb"].each do |file|
|
21
|
+
Dir["#{File.dirname(__FILE__)}/*.rb"].each do |file|
|
23
22
|
require file
|
24
23
|
end
|
25
24
|
end
|
26
|
-
|
25
|
+
|
27
26
|
import 'org.eclipse.jgit.lib.ObjectId'
|
28
|
-
|
27
|
+
|
29
28
|
module Porcelain
|
30
|
-
|
29
|
+
|
30
|
+
import 'java.io.IOException'
|
31
|
+
import 'org.eclipse.jgit.lib.Constants'
|
31
32
|
import 'org.eclipse.jgit.api.AddCommand'
|
32
33
|
import 'org.eclipse.jgit.api.CommitCommand'
|
33
34
|
import 'org.eclipse.jgit.api.BlameCommand'
|
35
|
+
import 'org.eclipse.jgit.api.errors.RefNotFoundException'
|
34
36
|
import 'org.eclipse.jgit.blame.BlameGenerator'
|
35
37
|
import 'org.eclipse.jgit.blame.BlameResult'
|
38
|
+
import 'org.eclipse.jgit.errors.IncorrectObjectTypeException'
|
39
|
+
import 'org.eclipse.jgit.errors.InvalidPatternException'
|
40
|
+
import 'org.eclipse.jgit.errors.MissingObjectException'
|
36
41
|
import 'org.eclipse.jgit.treewalk.CanonicalTreeParser'
|
37
42
|
import 'org.eclipse.jgit.diff.DiffFormatter'
|
38
43
|
|
39
|
-
|
40
44
|
# http://wiki.eclipse.org/JGit/User_Guide#Porcelain_API
|
41
45
|
def self.add(repository, file_pattern)
|
42
46
|
repository.add(file_pattern)
|
43
47
|
end
|
44
|
-
|
48
|
+
|
45
49
|
def self.commit(repository, message="")
|
46
50
|
repository.commit(message)
|
47
51
|
end
|
48
|
-
|
52
|
+
|
49
53
|
def self.object_for_tag(repository, tag)
|
50
54
|
repository.find(tag.object.name, RJGit.sym_for_type(tag.object_type))
|
51
55
|
end
|
52
|
-
|
56
|
+
|
53
57
|
# http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg00558.html
|
54
58
|
def self.cat_file(repository, blob)
|
55
59
|
jrepo = RJGit.repository_type(repository)
|
@@ -65,7 +69,7 @@ module RJGit
|
|
65
69
|
bytes = jrepo.open(jblob.id).get_bytes
|
66
70
|
return bytes.to_a.pack('c*').force_encoding('UTF-8')
|
67
71
|
end
|
68
|
-
|
72
|
+
|
69
73
|
def self.ls_tree(repository, path=nil, treeish=Constants::HEAD, options={})
|
70
74
|
options = {recursive: false, print: false, io: $stdout, path_filter: nil}.merge options
|
71
75
|
jrepo = RJGit.repository_type(repository)
|
@@ -95,7 +99,7 @@ module RJGit
|
|
95
99
|
treewalk.set_recursive(options[:recursive])
|
96
100
|
treewalk.set_filter(PathFilter.create(options[:path_filter])) if options[:path_filter]
|
97
101
|
entries = []
|
98
|
-
|
102
|
+
|
99
103
|
while treewalk.next
|
100
104
|
entry = {}
|
101
105
|
mode = treewalk.get_file_mode(0)
|
@@ -107,8 +111,8 @@ module RJGit
|
|
107
111
|
end
|
108
112
|
options[:io].puts RJGit.stringify(entries) if options[:print]
|
109
113
|
entries
|
110
|
-
end
|
111
|
-
|
114
|
+
end
|
115
|
+
|
112
116
|
def self.blame(repository, file_path, options={})
|
113
117
|
options = {:print => false, :io => $stdout}.merge(options)
|
114
118
|
jrepo = RJGit.repository_type(repository)
|
@@ -130,28 +134,22 @@ module RJGit
|
|
130
134
|
options[:io].puts RJGit.stringify(blame) if options[:print]
|
131
135
|
return blame
|
132
136
|
end
|
133
|
-
|
137
|
+
|
134
138
|
def self.diff(repository, options = {})
|
135
139
|
options = {:namestatus => false, :patch => false}.merge(options)
|
136
140
|
repo = RJGit.repository_type(repository)
|
137
141
|
git = RubyGit.new(repo).jgit
|
138
142
|
diff_command = git.diff
|
139
|
-
|
143
|
+
[:old, :new].each do |which_rev|
|
144
|
+
if rev = options["#{which_rev}_rev".to_sym]
|
140
145
|
reader = repo.new_object_reader
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
diff_command.set_old_tree(old_tree_iter)
|
145
|
-
end
|
146
|
-
if options[:new_rev]
|
147
|
-
reader = repo.new_object_reader unless reader
|
148
|
-
new_tree = repo.resolve("#{options[:new_rev]}^{tree}")
|
149
|
-
new_tree_iter = CanonicalTreeParser.new
|
150
|
-
new_tree_iter.reset(reader, new_tree)
|
151
|
-
diff_command.set_new_tree(new_tree_iter)
|
146
|
+
parser = CanonicalTreeParser.new
|
147
|
+
parser.reset(reader, repo.resolve("#{rev}^{tree}"))
|
148
|
+
diff_command.send("set_#{which_rev}_tree".to_sym, parser)
|
152
149
|
end
|
150
|
+
end
|
153
151
|
diff_command.set_path_filter(PathFilter.create(options[:file_path])) if options[:file_path]
|
154
|
-
diff_command.set_show_name_and_status_only(true) if options[:namestatus]
|
152
|
+
diff_command.set_show_name_and_status_only(true) if options[:namestatus]
|
155
153
|
diff_command.set_cached(true) if options[:cached]
|
156
154
|
diff_entries = diff_command.call
|
157
155
|
diff_entries = diff_entries.to_array.to_ary
|
@@ -169,34 +167,86 @@ module RJGit
|
|
169
167
|
diff_entries = options[:patch] ? result : diff_entries.map {|entry| [entry]}
|
170
168
|
RJGit.convert_diff_entries(diff_entries)
|
171
169
|
end
|
172
|
-
|
170
|
+
|
171
|
+
def self.describe(repository, ref, options = {})
|
172
|
+
options = {:always => false, :long => false, :tags => false, :match => []}.merge(options)
|
173
|
+
repo = RJGit.repository_type(repository)
|
174
|
+
git = RubyGit.new(repo).jgit
|
175
|
+
command = git.describe.
|
176
|
+
set_always(options[:always]).
|
177
|
+
set_long(options[:long]).
|
178
|
+
set_tags(options[:tags])
|
179
|
+
begin
|
180
|
+
command = command.set_target(ref)
|
181
|
+
rescue IncorrectObjectTypeException, IOException, MissingObjectException, RefNotFoundException
|
182
|
+
return nil
|
183
|
+
end
|
184
|
+
options[:match].each do |match|
|
185
|
+
begin
|
186
|
+
command = command.set_match(match)
|
187
|
+
rescue InvalidPatternException
|
188
|
+
return nil
|
189
|
+
end
|
190
|
+
end
|
191
|
+
command.call
|
192
|
+
end
|
193
|
+
|
194
|
+
# options:
|
195
|
+
# * ref
|
196
|
+
# * path_filter
|
197
|
+
# * case_insensitive
|
198
|
+
def self.grep(repository, query, options={})
|
199
|
+
case_insensitive = options[:case_insensitive]
|
200
|
+
repo = RJGit.repository_type(repository)
|
201
|
+
walk = RevWalk.new(repo)
|
202
|
+
ls_tree_options = {:recursive => true, :path_filter => options[:path_filter]}
|
203
|
+
|
204
|
+
query = case query
|
205
|
+
when Regexp then query
|
206
|
+
when String then Regexp.new(Regexp.escape(query))
|
207
|
+
else raise "A #{query.class} was passed to #{self}.grep(). Only Regexps and Strings are supported!"
|
208
|
+
end
|
209
|
+
|
210
|
+
query = Regexp.new(query.source, query.options | Regexp::IGNORECASE) if case_insensitive
|
211
|
+
|
212
|
+
ls_tree(repo, nil, options.fetch(:ref, 'HEAD'), ls_tree_options).each_with_object({}) do |item, result|
|
213
|
+
blob = Blob.new(repo, item[:mode], item[:path], walk.lookup_blob(ObjectId.from_string(item[:id])))
|
214
|
+
next if blob.binary?
|
215
|
+
|
216
|
+
rows = blob.data.split("\n")
|
217
|
+
data = rows.grep(query)
|
218
|
+
next if data.empty?
|
219
|
+
|
220
|
+
result[blob.path] = data
|
221
|
+
end
|
222
|
+
end
|
173
223
|
end
|
174
|
-
|
224
|
+
|
175
225
|
module Plumbing
|
176
226
|
import org.eclipse.jgit.lib.Constants
|
177
|
-
|
227
|
+
|
178
228
|
class TreeBuilder
|
179
229
|
import org.eclipse.jgit.lib.FileMode
|
180
230
|
import org.eclipse.jgit.lib.TreeFormatter
|
181
|
-
|
182
|
-
|
231
|
+
import org.eclipse.jgit.patch.Patch
|
232
|
+
|
183
233
|
attr_accessor :treemap
|
184
234
|
attr_reader :log
|
185
|
-
|
235
|
+
|
186
236
|
def initialize(repository)
|
187
237
|
@jrepo = RJGit.repository_type(repository)
|
188
238
|
@treemap = {}
|
189
239
|
init_log
|
190
240
|
end
|
191
|
-
|
241
|
+
|
192
242
|
def object_inserter
|
193
243
|
@object_inserter ||= @jrepo.newObjectInserter
|
194
244
|
end
|
195
|
-
|
245
|
+
|
196
246
|
def init_log
|
197
247
|
@log = {:deleted => [], :added => [] }
|
198
248
|
end
|
199
|
-
|
249
|
+
|
200
250
|
def only_contains_deletions(hashmap)
|
201
251
|
hashmap.each do |key, value|
|
202
252
|
if value.is_a?(Hash)
|
@@ -207,7 +257,7 @@ module RJGit
|
|
207
257
|
end
|
208
258
|
true
|
209
259
|
end
|
210
|
-
|
260
|
+
|
211
261
|
def build_tree(start_tree, treemap = nil, flush = false)
|
212
262
|
existing_trees = {}
|
213
263
|
untouched_objects = {}
|
@@ -232,7 +282,7 @@ module RJGit
|
|
232
282
|
end
|
233
283
|
end
|
234
284
|
end
|
235
|
-
|
285
|
+
|
236
286
|
sorted_treemap = treemap.inject({}) {|h, (k,v)| v.is_a?(Hash) ? h["#{k}/"] = v : h[k] = v; h }.merge(untouched_objects).sort
|
237
287
|
sorted_treemap.each do |object_name, data|
|
238
288
|
case data
|
@@ -252,27 +302,27 @@ module RJGit
|
|
252
302
|
end
|
253
303
|
object_inserter.insert(formatter)
|
254
304
|
end
|
255
|
-
|
305
|
+
|
256
306
|
def write_blob(contents, flush = false)
|
257
307
|
blobid = object_inserter.insert(Constants::OBJ_BLOB, contents.to_java_bytes)
|
258
308
|
object_inserter.flush if flush
|
259
309
|
blobid
|
260
310
|
end
|
261
|
-
|
311
|
+
|
262
312
|
end
|
263
|
-
|
313
|
+
|
264
314
|
class Index
|
265
315
|
import org.eclipse.jgit.lib.CommitBuilder
|
266
|
-
|
316
|
+
|
267
317
|
attr_accessor :treemap, :current_tree
|
268
318
|
attr_reader :jrepo
|
269
|
-
|
319
|
+
|
270
320
|
def initialize(repository)
|
271
321
|
@treemap = {}
|
272
322
|
@jrepo = RJGit.repository_type(repository)
|
273
323
|
@treebuilder = TreeBuilder.new(@jrepo)
|
274
324
|
end
|
275
|
-
|
325
|
+
|
276
326
|
def add(path, data)
|
277
327
|
path = path[1..-1] if path[0] == '/'
|
278
328
|
path = path.split('/')
|
@@ -289,24 +339,24 @@ module RJGit
|
|
289
339
|
current[filename] = data
|
290
340
|
@treemap
|
291
341
|
end
|
292
|
-
|
342
|
+
|
293
343
|
def delete(path)
|
294
344
|
path = path[1..-1] if path[0] == '/'
|
295
345
|
path = path.split('/')
|
296
346
|
last = path.pop
|
297
|
-
|
347
|
+
|
298
348
|
current = self.treemap
|
299
|
-
|
349
|
+
|
300
350
|
path.each do |dir|
|
301
351
|
current[dir] ||= {}
|
302
352
|
node = current[dir]
|
303
353
|
current = node
|
304
354
|
end
|
305
|
-
|
355
|
+
|
306
356
|
current[last] = false
|
307
357
|
@treemap
|
308
358
|
end
|
309
|
-
|
359
|
+
|
310
360
|
def do_commit(message, author, parents, new_tree)
|
311
361
|
commit_builder = CommitBuilder.new
|
312
362
|
person = author.person_ident
|
@@ -323,14 +373,11 @@ module RJGit
|
|
323
373
|
@treebuilder.object_inserter.flush
|
324
374
|
result
|
325
375
|
end
|
326
|
-
|
327
|
-
def commit(message, author, parents = nil, ref =
|
328
|
-
|
329
|
-
@current_tree = @current_tree ? RJGit.tree_type(@current_tree) : @jrepo.resolve("refs/heads/#{Constants::MASTER}^{tree}")
|
330
|
-
@treebuilder.treemap = @treemap
|
331
|
-
new_tree = @treebuilder.build_tree(@current_tree)
|
376
|
+
|
377
|
+
def commit(message, author, parents = nil, ref = "refs/heads/#{Constants::MASTER}", force = false)
|
378
|
+
new_tree = build_new_tree(@treemap, "#{ref}^{tree}")
|
332
379
|
return false if @current_tree && new_tree.name == @current_tree.name
|
333
|
-
|
380
|
+
|
334
381
|
parents = parents ? parents : @jrepo.resolve(ref+"^{commit}")
|
335
382
|
new_head = do_commit(message, author, parents, new_tree)
|
336
383
|
|
@@ -341,21 +388,129 @@ module RJGit
|
|
341
388
|
ru.setRefLogIdent(author.person_ident)
|
342
389
|
ru.setRefLogMessage("commit: #{message}", false)
|
343
390
|
res = ru.update.to_string
|
344
|
-
|
345
|
-
# @treebuilder.object_inserter.release
|
391
|
+
|
346
392
|
@current_tree = new_tree
|
347
393
|
log = @treebuilder.log
|
348
394
|
@treebuilder.init_log
|
349
395
|
sha = ObjectId.to_string(new_head)
|
350
396
|
return res, log, sha
|
351
397
|
end
|
352
|
-
|
398
|
+
|
353
399
|
def self.successful?(result)
|
354
400
|
["NEW", "FAST_FORWARD", "FORCED"].include?(result)
|
355
401
|
end
|
356
402
|
|
403
|
+
private
|
404
|
+
|
405
|
+
def build_new_tree(treemap, ref)
|
406
|
+
@treebuilder.treemap = treemap
|
407
|
+
new_tree = @treebuilder.build_tree(@current_tree ? RJGit.tree_type(@current_tree) : @jrepo.resolve(ref))
|
408
|
+
end
|
409
|
+
|
357
410
|
end
|
358
|
-
|
411
|
+
|
412
|
+
class ApplyPatchToIndex < RJGit::Plumbing::Index
|
413
|
+
|
414
|
+
import org.eclipse.jgit.patch.Patch
|
415
|
+
import org.eclipse.jgit.diff.DiffEntry
|
416
|
+
|
417
|
+
ADD = org.eclipse.jgit.diff.DiffEntry::ChangeType::ADD
|
418
|
+
COPY = org.eclipse.jgit.diff.DiffEntry::ChangeType::COPY
|
419
|
+
MODIFY = org.eclipse.jgit.diff.DiffEntry::ChangeType::MODIFY
|
420
|
+
DELETE = org.eclipse.jgit.diff.DiffEntry::ChangeType::DELETE
|
421
|
+
RENAME = org.eclipse.jgit.diff.DiffEntry::ChangeType::RENAME
|
422
|
+
|
423
|
+
# Take the result of RJGit::Porcelain.diff with options[:patch] = true and return a patch String
|
424
|
+
def self.diffs_to_patch(diffs)
|
425
|
+
diffs.inject(""){|result, diff| result << diff[:patch]}
|
426
|
+
end
|
427
|
+
|
428
|
+
def initialize(repository, patch, ref = Constants::HEAD)
|
429
|
+
super(repository)
|
430
|
+
@ref = ref
|
431
|
+
@patch = Patch.new
|
432
|
+
@patch.parse(ByteArrayInputStream.new(patch.to_java_bytes))
|
433
|
+
raise_patch_apply_error unless @patch.getErrors.isEmpty()
|
434
|
+
@current_tree = Commit.find_head(@jrepo, ref).tree
|
435
|
+
end
|
436
|
+
|
437
|
+
def commit(message, author, parents = nil, force = false)
|
438
|
+
super(message, author, parents, @ref, force)
|
439
|
+
end
|
440
|
+
|
441
|
+
def build_map
|
442
|
+
raise_patch_apply_error if @patch.getFiles.isEmpty()
|
443
|
+
@patch.getFiles.each do |file_header|
|
444
|
+
case file_header.getChangeType
|
445
|
+
when ADD
|
446
|
+
add(file_header.getNewPath, apply('', file_header))
|
447
|
+
when MODIFY
|
448
|
+
add(file_header.getOldPath, apply(getData(file_header.getOldPath), file_header))
|
449
|
+
when DELETE
|
450
|
+
delete(file_header.getOldPath)
|
451
|
+
when RENAME
|
452
|
+
delete(file_header.getOldPath)
|
453
|
+
add(file_header.getNewPath, getData(file_header.getOldPath))
|
454
|
+
when COPY
|
455
|
+
add(file_header.getNewPath, getData(file_header.getOldPath))
|
456
|
+
end
|
457
|
+
end
|
458
|
+
@treemap
|
459
|
+
end
|
460
|
+
|
461
|
+
# Build the new tree based on the patch, but don't commit it
|
462
|
+
# Return the String object id of the new tree, and an Array of affected paths
|
463
|
+
def new_tree
|
464
|
+
map = build_map
|
465
|
+
return ObjectId.to_string(build_new_tree(map, @ref)), map.keys
|
466
|
+
end
|
467
|
+
|
468
|
+
private
|
469
|
+
|
470
|
+
def raise_patch_apply_error
|
471
|
+
raise ::RJGit::PatchApplyException.new('Patch failed to apply')
|
472
|
+
end
|
473
|
+
|
474
|
+
def getData(path)
|
475
|
+
begin
|
476
|
+
(@current_tree / path).data
|
477
|
+
rescue NoMethodError
|
478
|
+
raise_patch_apply_error
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def hunk_sanity_check(hunk, hunk_line, pos, newLines)
|
483
|
+
raise_patch_apply_error unless newLines[hunk.getNewStartLine - 1 + pos] == hunk_line[1..-1]
|
484
|
+
end
|
485
|
+
|
486
|
+
def apply(original, file_header)
|
487
|
+
newLines = original.lines
|
488
|
+
file_header.getHunks.each do |hunk|
|
489
|
+
length = hunk.getEndOffset - hunk.getStartOffset
|
490
|
+
buffer_text = hunk.getBuffer.to_s.slice(hunk.getStartOffset, length)
|
491
|
+
pos = 0
|
492
|
+
buffer_text.each_line do |hunk_line|
|
493
|
+
case hunk_line[0]
|
494
|
+
when ' '
|
495
|
+
hunk_sanity_check(hunk, hunk_line, pos, newLines)
|
496
|
+
pos += 1
|
497
|
+
when '-'
|
498
|
+
if hunk.getNewStartLine == 0
|
499
|
+
newLines = []
|
500
|
+
else
|
501
|
+
hunk_sanity_check(hunk, hunk_line, pos, newLines)
|
502
|
+
newLines.slice!(hunk.getNewStartLine - 1 + pos)
|
503
|
+
end
|
504
|
+
when '+'
|
505
|
+
newLines.insert(hunk.getNewStartLine - 1 + pos, hunk_line[1..-1])
|
506
|
+
pos += 1
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
newLines.join
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
359
514
|
end
|
360
|
-
|
515
|
+
|
361
516
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rjgit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.8.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maarten Engelen
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2020-08-14 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,8 @@ files:
|
|
49
49
|
- lib/java/jars/bcpkix-jdk15on-161.jar
|
50
50
|
- lib/java/jars/bcprov-jdk15on-161.jar
|
51
51
|
- lib/java/jars/jsch-0.1.54.jar
|
52
|
-
- lib/java/jars/org.eclipse.jgit-5.
|
52
|
+
- lib/java/jars/org.eclipse.jgit-5.8.1.202007141445-r.jar
|
53
|
+
- lib/java/jars/org.eclipse.jgit.ssh.jsch-5.8.0.202006091008-r.jar
|
53
54
|
- lib/java/jars/slf4j-api-1.7.2.jar
|
54
55
|
- lib/java/jars/slf4j-simple-1.7.12.jar
|
55
56
|
- lib/repo.rb
|
Binary file
|