Module: RJGit::Porcelain

Defined in:
lib/rjgit.rb

Class Method Summary collapse

Class Method Details

.add(repository, file_pattern) ⇒ Object



45
46
47
# File 'lib/rjgit.rb', line 45

def self.add(repository, file_pattern)
  repository.add(file_pattern)
end

.blame(repository, file_path, options = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rjgit.rb', line 117

def self.blame(repository, file_path, options={})
  options = {:print => false, :io => $stdout}.merge(options)
  jrepo = RJGit.repository_type(repository)
  return nil unless jrepo

  blame_command = BlameCommand.new(jrepo)
  blame_command.set_file_path(file_path)
  result = blame_command.call
  content = result.get_result_contents
  blame = []
  for index in (0..content.size - 1) do
    blameline = {}
    blameline[:actor] = Actor.new_from_person_ident(result.get_source_author(index))
    blameline[:line] = result.get_source_line(index)
    blameline[:commit] = Commit.new(repository, result.get_source_commit(index))
    blameline[:line] = content.get_string(index)
    blame << blameline
  end
  options[:io].puts RJGit.stringify(blame) if options[:print]
  return blame
end

.cat_file(repository, blob) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rjgit.rb', line 58

def self.cat_file(repository, blob)
  mode = blob.mode if blob.respond_to?(:mode)
  jrepo = RJGit.repository_type(repository)
  jblob = RJGit.blob_type(blob)
  # Try to resolve symlinks; return nil otherwise
  mode ||= RJGit.get_file_mode(jrepo, jblob)
  if mode == SYMLINK_TYPE
    symlink_source = jrepo.open(jblob.id).get_bytes.to_a.pack('c*').force_encoding('UTF-8')
    blob = Blob.find_blob(jrepo, symlink_source)
    return nil if blob.nil?
    jblob = blob.jblob
  end
  bytes = jrepo.open(jblob.id).get_bytes
  return bytes.to_a.pack('c*').force_encoding('UTF-8')
end

.commit(repository, message = "") ⇒ Object



49
50
51
# File 'lib/rjgit.rb', line 49

def self.commit(repository, message="")
  repository.commit(message)
end

.describe(repository, ref, options = {}) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/rjgit.rb', line 172

def self.describe(repository, ref, options = {})
  options = {:always => false, :long => false, :tags => false, :match => []}.merge(options)
  repo = RJGit.repository_type(repository)
  git = RubyGit.new(repo).jgit
  command = git.describe.
    set_always(options[:always]).
    set_long(options[:long]).
    set_tags(options[:tags])
  begin
    command = command.set_target(ref)
  rescue IncorrectObjectTypeException, IOException, MissingObjectException, RefNotFoundException
    return nil
  end
  options[:match].each do |match|
    begin
      command = command.set_match(match)
    rescue InvalidPatternException
      return nil
    end
  end
  command.call
end

.diff(repository, options = {}) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/rjgit.rb', line 139

def self.diff(repository, options = {})
  options = {:namestatus => false, :patch => false}.merge(options)
  repo = RJGit.repository_type(repository)
  git = RubyGit.new(repo).jgit
  diff_command = git.diff
  [:old, :new].each do |which_rev|
    if rev = options["#{which_rev}_rev".to_sym]
      reader = repo.new_object_reader
      parser = CanonicalTreeParser.new
      parser.reset(reader, repo.resolve("#{rev}^{tree}"))
      diff_command.send("set_#{which_rev}_tree".to_sym, parser)
    end
  end
  diff_command.set_path_filter(PathFilter.create(options[:file_path])) if options[:file_path]
  diff_command.set_show_name_and_status_only(true) if options[:namestatus]
  diff_command.set_cached(true) if options[:cached]
  diff_entries = diff_command.call
  diff_entries = diff_entries.to_array.to_ary
    if options[:patch]
      result = []
      out_stream = ByteArrayOutputStream.new
      formatter = DiffFormatter.new(out_stream)
      formatter.set_repository(repo)
      diff_entries.each do |diff_entry|
        formatter.format(diff_entry)
        result.push [diff_entry, out_stream.to_string]
        out_stream.reset
      end
    end
  diff_entries = options[:patch] ? result : diff_entries.map {|entry| [entry]}
  RJGit.convert_diff_entries(diff_entries)
end

.grep(repository, query, options = {}) ⇒ Object

options:

* ref
* path_filter
* case_insensitive


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/rjgit.rb', line 199

def self.grep(repository, query, options={})
  case_insensitive = options[:case_insensitive]
  repo = RJGit.repository_type(repository)
  walk = RevWalk.new(repo)
  ls_tree_options = {:recursive => true, :path_filter => options[:path_filter]}

  query = case query
  when Regexp then query
  when String then Regexp.new(Regexp.escape(query))
  else raise "A #{query.class} was passed to #{self}.grep().  Only Regexps and Strings are supported!"
  end

  query = Regexp.new(query.source, query.options | Regexp::IGNORECASE) if case_insensitive

  # We optimize below by first grepping the entire file, and then, if a match is found, then identifying the individual line.
  # To avoid missing full-line matches during the optimization, we first convert multiline anchors to single-line anchors.
  query = Regexp.new(query.source.gsub(/\A\\A/, '^').gsub(/\\z\z/, '$'), query.options)

  ref = options.fetch(:ref, 'HEAD')
  files_to_scan = ls_tree(repo, nil, ref, ls_tree_options)

  files_to_scan.each_with_object({}) do |file, result|
    id = if file[:mode] == SYMLINK_TYPE
      symlink_source = repo.open(ObjectId.from_string(file[:id])).get_bytes.to_a.pack('c*').force_encoding('UTF-8')
      unless symlink_source[File::SEPARATOR]
        dir = file[:path].split(File::SEPARATOR)
        dir[-1] = symlink_source
        symlink_source = File.join(dir)
      end
      Blob.find_blob(repo, symlink_source, ref).jblob.id
    else
      ObjectId.from_string(file[:id])
    end
    bytes = repo.open(id).get_bytes

    next if RawText.is_binary(bytes)

    file_contents = bytes.to_s
    next unless query.match(file_contents)

    rows = file_contents.split("\n")
    data = rows.grep(query)
    next if data.empty?

    result[file[:path]] = data
  end
end

.ls_tree(repository, path = nil, treeish = Constants::HEAD, options = {}) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/rjgit.rb', line 74

def self.ls_tree(repository, path=nil, treeish=Constants::HEAD, options={})
  options = {recursive: false, print: false, io: $stdout, path_filter: nil}.merge options
  jrepo = RJGit.repository_type(repository)
  ref = treeish.respond_to?(:get_name) ? treeish.get_name : treeish

  begin
    obj = jrepo.resolve(ref)
    walk = RevWalk.new(jrepo)
    revobj = walk.parse_any(obj)
    jtree = case revobj.get_type
    when Constants::OBJ_TREE
      walk.parse_tree(obj)
    when Constants::OBJ_COMMIT
      walk.parse_commit(obj).get_tree
    end
  rescue Java::OrgEclipseJgitErrors::MissingObjectException, Java::JavaLang::IllegalArgumentException, Java::JavaLang::NullPointerException
    return nil
  end
  if path
    treewalk = TreeWalk.forPath(jrepo, path, jtree)
    return nil unless treewalk
    treewalk.enter_subtree
  else
    treewalk = TreeWalk.new(jrepo)
    treewalk.add_tree(jtree)
  end
  treewalk.set_recursive(options[:recursive])
  treewalk.set_filter(PathFilter.create(options[:path_filter])) if options[:path_filter]
  entries = []

  while treewalk.next
    entry = {}
    mode = treewalk.get_file_mode(0)
    entry[:mode] = mode.get_bits
    entry[:type] = Constants.type_string(mode.get_object_type)
    entry[:id]   = treewalk.get_object_id(0).name
    entry[:path] = treewalk.get_path_string
    entries << entry
  end
  options[:io].puts RJGit.stringify(entries) if options[:print]
  entries
end

.object_for_tag(repository, tag) ⇒ Object



53
54
55
# File 'lib/rjgit.rb', line 53

def self.object_for_tag(repository, tag)
  repository.find(tag.object.name, RJGit.sym_for_type(tag.object_type))
end