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