lib/gitlab_git/repository.rb in gitlab_git-7.0.0.rc12 vs lib/gitlab_git/repository.rb in gitlab_git-7.0.0.rc13
- old
+ new
@@ -9,10 +9,11 @@
include Gitlab::Git::Popen
SEARCH_CONTEXT_LINES = 3
class NoRepository < StandardError; end
+ class InvalidBlobName < StandardError; end
# Default branch in the repository
attr_accessor :root_ref
# Full path to repo
@@ -263,23 +264,26 @@
def merge_base_commit(from, to)
rugged.merge_base(from, to)
end
# Return an array of Diff objects that represent the diff
- # between +from+ and +to+.
- def diff(from, to, *paths)
- rugged.diff(from, to, paths: paths).each_patch.map do |p|
+ # between +from+ and +to+. See Diff::filter_diff_options for the allowed
+ # diff options. The +options+ hash can also include :break_rewrites to
+ # split larger rewrites into delete/add pairs.
+ def diff(from, to, options = {}, *paths)
+ diff_patches(from, to, options, *paths).map do |p|
Gitlab::Git::Diff.new(p)
end
end
- # Return the diff between +from+ and +to+ in a single patch string.
- def diff_text(from, to, *paths)
+ # Return the diff between +from+ and +to+ in a single patch string. The
+ # +options+ hash has the same allowed keys as #diff.
+ def diff_text(from, to, options = {}, *paths)
# NOTE: It would be simpler to use the Rugged::Diff#patch method, but
# that formats the diff text differently than Rugged::Patch#to_s for
# changes to binary files.
- rugged.diff(from, to, paths: paths).each_patch.map do |p|
+ diff_patches(from, to, options, *paths).map do |p|
p.to_s
end.join("\n")
end
# Returns commits collection
@@ -414,11 +418,16 @@
# }
#
def submodules(ref)
commit = rugged.rev_parse(ref)
- content = blob_content(commit, ".gitmodules")
+ begin
+ content = blob_content(commit, ".gitmodules")
+ rescue InvalidBlobName
+ return {}
+ end
+
parse_gitmodules(commit, content)
end
# Return total commits count accessible from passed ref
def commit_count(ref)
@@ -656,17 +665,20 @@
def push(remote_name, *refspecs)
rugged.remotes[remote_name].push(refspecs)
end
# Return a String containing the mbox-formatted diff between +from+ and
- # +to+
- def format_patch(from, to)
- rugged.diff(from, to).patch
+ # +to+. See #diff for the allowed keys in the +options+ hash.
+ def format_patch(from, to, options = {})
+ options ||= {}
+ break_rewrites = options[:break_rewrites]
+ actual_options = Diff.filter_diff_options(options)
+
from_sha = rugged.rev_parse_oid(from)
to_sha = rugged.rev_parse_oid(to)
commits_between(from_sha, to_sha).map do |commit|
- commit.to_mbox
+ commit.to_mbox(actual_options)
end.join("\n")
end
# Merge the +source_name+ branch into the +target_name+ branch. This is
# equivalent to `git merge --no_ff +source_name+`, since a merge commit
@@ -722,10 +734,14 @@
# Get the content of a blob for a given commit. If the blob is a commit
# (for submodules) then return the blob's OID.
def blob_content(commit, blob_name)
blob_entry = tree_entry(commit, blob_name)
+ unless blob_entry
+ raise InvalidBlobName.new("Invalid blob name: #{blob_name}")
+ end
+
if blob_entry[:type] == :commit
blob_entry[:oid]
else
rugged.lookup(blob_entry[:oid]).content
end
@@ -740,15 +756,20 @@
content.split("\n").each do |txt|
if txt.match(/^\s*\[/)
current = txt.match(/(?<=").*(?=")/)[0]
results[current] = {}
else
+ next unless results[current]
match_data = txt.match(/(\w+)\s*=\s*(.*)/)
results[current][match_data[1]] = match_data[2]
if match_data[1] == "path"
- results[current]["id"] = blob_content(commit, match_data[2])
+ begin
+ results[current]["id"] = blob_content(commit, match_data[2])
+ rescue InvalidBlobName
+ results.delete(current)
+ end
end
end
end
results
@@ -982,9 +1003,20 @@
filename
)
end
greps
+ end
+
+ # Return the Rugged patches for the diff between +from+ and +to+.
+ def diff_patches(from, to, options = {}, *paths)
+ options ||= {}
+ break_rewrites = options[:break_rewrites]
+ actual_options = Diff.filter_diff_options(options.merge(paths: paths))
+
+ diff = rugged.diff(from, to, actual_options)
+ diff.find_similar!(break_rewrites: break_rewrites)
+ diff.each_patch
end
end
end
end