[DRE-commits] [ruby-gitlab-git] 01/03: New upstream version 10.4.7

Rahulkrishnan R A rahulkrishnanra-guest at moszumanska.debian.org
Tue Sep 13 10:55:59 UTC 2016


This is an automated email from the git hooks/post-receive script.

rahulkrishnanra-guest pushed a commit to branch master
in repository ruby-gitlab-git.

commit 50241aae8a6b1ad95ddc8dcf0484a8dedefb496c
Author: Rahulkrishnan R A <rahulkrishnanfs at gmail.com>
Date:   Tue Sep 13 10:32:42 2016 +0000

    New upstream version 10.4.7
---
 VERSION                           |   2 +-
 gitlab_git.gemspec                |  11 ++--
 lib/gitlab_git.rb                 |   1 +
 lib/gitlab_git/attributes.rb      | 127 ++++++++++++++++++++++++++++++++++++++
 lib/gitlab_git/blob.rb            |  10 ++-
 lib/gitlab_git/commit.rb          |  22 ++++---
 lib/gitlab_git/compare.rb         |  25 +++++---
 lib/gitlab_git/diff.rb            |  77 ++++++++++++++++++-----
 lib/gitlab_git/diff_collection.rb | 107 ++++++++++++++++++--------------
 lib/gitlab_git/ref.rb             |  21 +++----
 lib/gitlab_git/repository.rb      |  60 ++++++++++++++----
 lib/gitlab_git/tag.rb             |  15 ++++-
 12 files changed, 362 insertions(+), 116 deletions(-)

diff --git a/VERSION b/VERSION
index 15d0c6b..827886a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-10.3.2
+10.6.4
diff --git a/gitlab_git.gemspec b/gitlab_git.gemspec
index 6f02d7b..17c1ecf 100644
--- a/gitlab_git.gemspec
+++ b/gitlab_git.gemspec
@@ -2,22 +2,21 @@
 # This file has been automatically generated by gem2tgz #
 #########################################################
 # -*- encoding: utf-8 -*-
-# stub: gitlab_git 10.3.2 ruby lib
 
 Gem::Specification.new do |s|
   s.name = "gitlab_git"
-  s.version = "10.3.2"
+  s.version = "10.6.4"
 
   s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
-  s.require_paths = ["lib"]
   s.authors = ["Dmitriy Zaporozhets"]
-  s.date = "2016-07-18"
+  s.date = "2016-09-09"
   s.description = "GitLab wrapper around git objects"
   s.email = "dmitriy.zaporozhets at gmail.com"
-  s.files = ["VERSION", "lib/gitlab_git.rb", "lib/gitlab_git/blame.rb", "lib/gitlab_git/blob.rb", "lib/gitlab_git/blob_snippet.rb", "lib/gitlab_git/branch.rb", "lib/gitlab_git/commit.rb", "lib/gitlab_git/commit_stats.rb", "lib/gitlab_git/compare.rb", "lib/gitlab_git/diff.rb", "lib/gitlab_git/diff_collection.rb", "lib/gitlab_git/encoding_helper.rb", "lib/gitlab_git/path_helper.rb", "lib/gitlab_git/popen.rb", "lib/gitlab_git/ref.rb", "lib/gitlab_git/repository.rb", "lib/gitlab_git/tag.rb", [...]
+  s.files = ["VERSION", "lib/gitlab_git.rb", "lib/gitlab_git/attributes.rb", "lib/gitlab_git/blame.rb", "lib/gitlab_git/blob.rb", "lib/gitlab_git/blob_snippet.rb", "lib/gitlab_git/branch.rb", "lib/gitlab_git/commit.rb", "lib/gitlab_git/commit_stats.rb", "lib/gitlab_git/compare.rb", "lib/gitlab_git/diff.rb", "lib/gitlab_git/diff_collection.rb", "lib/gitlab_git/encoding_helper.rb", "lib/gitlab_git/path_helper.rb", "lib/gitlab_git/popen.rb", "lib/gitlab_git/ref.rb", "lib/gitlab_git/reposito [...]
   s.homepage = "https://gitlab.com/gitlab-org/gitlab_git"
   s.licenses = ["MIT"]
-  s.rubygems_version = "2.5.1"
+  s.require_paths = ["lib"]
+  s.rubygems_version = "1.8.23"
   s.summary = "Gitlab::Git library"
 
   if s.respond_to? :specification_version then
diff --git a/lib/gitlab_git.rb b/lib/gitlab_git.rb
index 39a9d4b..960eaa2 100644
--- a/lib/gitlab_git.rb
+++ b/lib/gitlab_git.rb
@@ -25,3 +25,4 @@ require_relative "gitlab_git/ref"
 require_relative "gitlab_git/branch"
 require_relative "gitlab_git/tag"
 require_relative "gitlab_git/util"
+require_relative "gitlab_git/attributes"
diff --git a/lib/gitlab_git/attributes.rb b/lib/gitlab_git/attributes.rb
new file mode 100644
index 0000000..1abf91d
--- /dev/null
+++ b/lib/gitlab_git/attributes.rb
@@ -0,0 +1,127 @@
+module Gitlab
+  module Git
+    # Class for parsing Git attribute files and extracting the attributes for
+    # file patterns.
+    #
+    # Unlike Rugged this parser only needs a single IO call (a call to `open`),
+    # vastly reducing the time spent in extracting attributes.
+    #
+    # This class _only_ supports parsing the attributes file located at
+    # `$GIT_DIR/info/attributes` as GitLab doesn't use any other files
+    # (`.gitattributes` is copied to this particular path).
+    #
+    # Basic usage:
+    #
+    #     attributes = Gitlab::Git::Attributes.new(some_repo.path)
+    #
+    #     attributes.attributes('README.md') # => { "eol" => "lf }
+    class Attributes
+      # path - The path to the Git repository.
+      def initialize(path)
+        @path = File.expand_path(path)
+        @patterns = nil
+      end
+
+      # Returns all the Git attributes for the given path.
+      #
+      # path - A path to a file for which to get the attributes.
+      #
+      # Returns a Hash.
+      def attributes(path)
+        full_path = File.join(@path, path)
+
+        patterns.each do |pattern, attrs|
+          return attrs if File.fnmatch?(pattern, full_path)
+        end
+
+        {}
+      end
+
+      # Returns a Hash containing the file patterns and their attributes.
+      def patterns
+        @patterns ||= parse_file
+      end
+
+      # Parses an attribute string.
+      #
+      # These strings can be in the following formats:
+      #
+      #     text      # => { "text" => true }
+      #     -text     # => { "text" => false }
+      #     key=value # => { "key" => "value" }
+      #
+      # string - The string to parse.
+      #
+      # Returns a Hash containing the attributes and their values.
+      def parse_attributes(string)
+        values = {}
+        dash = '-'
+        equal = '='
+        binary = 'binary'
+
+        string.split(/\s+/).each do |chunk|
+          # Data such as "foo = bar" should be treated as "foo" and "bar" being
+          # separate boolean attributes.
+          next if chunk == equal
+
+          key = chunk
+
+          # Input: "-foo"
+          if chunk.start_with?(dash)
+            key = chunk.byteslice(1, chunk.length - 1)
+            value = false
+
+          # Input: "foo=bar"
+          elsif chunk.include?(equal)
+            key, value = chunk.split(equal, 2)
+
+          # Input: "foo"
+          else
+            value = true
+          end
+
+          values[key] = value
+
+          # When the "binary" option is set the "diff" option should be set to
+          # the inverse. If "diff" is later set it should overwrite the
+          # automatically set value.
+          values['diff'] = false if key == binary && value
+        end
+
+        values
+      end
+
+      # Iterates over every line in the attributes file.
+      def each_line
+        full_path = File.join(@path, 'info/attributes')
+
+        return unless File.exist?(full_path)
+
+        File.open(full_path, 'r') do |handle|
+          handle.each_line do |line|
+            yield line.strip
+          end
+        end
+      end
+
+      private
+
+      # Parses the Git attributes file.
+      def parse_file
+        pairs = []
+        comment = '#'
+
+        each_line do |line|
+          next if line.start_with?(comment) || line.empty?
+
+          pattern, attrs = line.split(/\s+/, 2)
+
+          pairs << [File.join(@path, pattern), parse_attributes(attrs)]
+        end
+
+        # Newer entries take precedence over older entries.
+        pairs.reverse.to_h
+      end
+    end
+  end
+end
diff --git a/lib/gitlab_git/blob.rb b/lib/gitlab_git/blob.rb
index a8bfc9b..2aa7d93 100644
--- a/lib/gitlab_git/blob.rb
+++ b/lib/gitlab_git/blob.rb
@@ -13,7 +13,7 @@ module Gitlab
       # blob data should use load_all_data!.
       MAX_DATA_DISPLAY_SIZE = 10485760
 
-      attr_accessor :name, :path, :size, :data, :mode, :id, :commit_id, :loaded_size
+      attr_accessor :name, :path, :size, :data, :mode, :id, :commit_id, :loaded_size, :binary
 
       class << self
         def find(repository, sha, path)
@@ -38,6 +38,7 @@ module Gitlab
                 mode: blob_entry[:filemode].to_s(8),
                 path: path,
                 commit_id: sha,
+                binary: blob.binary?
               )
             end
           end
@@ -50,6 +51,7 @@ module Gitlab
             id: blob.oid,
             size: blob.size,
             data: blob.content(MAX_DATA_DISPLAY_SIZE),
+            binary: blob.binary?
           )
         end
 
@@ -247,7 +249,7 @@ module Gitlab
       end
 
       def initialize(options)
-        %w(id name path size data mode commit_id).each do |key|
+        %w(id name path size data mode commit_id binary).each do |key|
           self.send("#{key}=", options[key.to_sym])
         end
 
@@ -256,6 +258,10 @@ module Gitlab
         @loaded_size = @data.bytesize if @data
       end
 
+      def binary?
+        @binary.nil? ? super : @binary == true
+      end
+
       def empty?
         !data || data == ''
       end
diff --git a/lib/gitlab_git/commit.rb b/lib/gitlab_git/commit.rb
index 3c89e14..c455625 100644
--- a/lib/gitlab_git/commit.rb
+++ b/lib/gitlab_git/commit.rb
@@ -55,7 +55,12 @@ module Gitlab
         def find(repo, commit_id = "HEAD")
           return decorate(commit_id) if commit_id.is_a?(Rugged::Commit)
 
-          obj = repo.rev_parse_target(commit_id)
+          obj = if commit_id.is_a?(String)
+                  repo.rev_parse_target(commit_id)
+                else
+                  Ref.dereference_object(commit_id)
+                end
+
           return nil unless obj.is_a?(Rugged::Commit)
 
           decorate(obj)
@@ -282,15 +287,18 @@ module Gitlab
       end
 
       def init_from_rugged(commit)
+        author = commit.author
+        committer = commit.committer
+
         @raw_commit = commit
         @id = commit.oid
         @message = commit.message
-        @authored_date = commit.author[:time]
-        @committed_date = commit.committer[:time]
-        @author_name = commit.author[:name]
-        @author_email = commit.author[:email]
-        @committer_name = commit.committer[:name]
-        @committer_email = commit.committer[:email]
+        @authored_date = author[:time]
+        @committed_date = committer[:time]
+        @author_name = author[:name]
+        @author_email = author[:email]
+        @committer_name = committer[:name]
+        @committer_email = committer[:email]
         @parent_ids = commit.parents.map(&:oid)
       end
 
diff --git a/lib/gitlab_git/compare.rb b/lib/gitlab_git/compare.rb
index 0e55fa1..e2c8b3a 100644
--- a/lib/gitlab_git/compare.rb
+++ b/lib/gitlab_git/compare.rb
@@ -1,26 +1,31 @@
 module Gitlab
   module Git
     class Compare
-      attr_reader :commits, :same, :head, :base
+      attr_reader :head, :base
 
       def initialize(repository, base, head)
-        @commits = []
-        @same = false
         @repository = repository
 
-        return unless base && head
+        unless base && head
+          @commits = []
+          return
+        end
 
         @base = Gitlab::Git::Commit.find(repository, base.try(:strip))
         @head = Gitlab::Git::Commit.find(repository, head.try(:strip))
 
-        return unless @base && @head
+        @commits = [] unless @base && @head
+        @commits = [] if same
+      end
 
-        if @base.id == @head.id
-          @same = true
-          return
-        end
+      def same
+        @base && @head && @base.id == @head.id
+      end
+
+      def commits
+        return @commits if defined?(@commits)
 
-        @commits = Gitlab::Git::Commit.between(repository, @base.id, @head.id)
+        @commits = Gitlab::Git::Commit.between(@repository, @base.id, @head.id)
       end
 
       def diffs(options = {})
diff --git a/lib/gitlab_git/diff.rb b/lib/gitlab_git/diff.rb
index cf0fc31..d874dc7 100644
--- a/lib/gitlab_git/diff.rb
+++ b/lib/gitlab_git/diff.rb
@@ -13,6 +13,12 @@ module Gitlab
 
       attr_accessor :too_large
 
+      # The maximum size of a diff to display.
+      DIFF_SIZE_LIMIT = 102400 # 100 KB
+
+      # The maximum size before a diff is collapsed.
+      DIFF_COLLAPSE_LIMIT = 10240 # 10 KB
+
       class << self
         def between(repo, head, base, options = {}, *paths)
           # Only show what is new in the source branch compared to the target branch, not the other way around.
@@ -158,13 +164,14 @@ module Gitlab
         end
       end
 
-      def initialize(raw_diff)
-        raise "Nil as raw diff passed" unless raw_diff
-
-        if raw_diff.is_a?(Hash)
-          init_from_hash(raw_diff)
-        elsif raw_diff.is_a?(Rugged::Patch)
-          init_from_rugged(raw_diff)
+      def initialize(raw_diff, collapse: false)
+        case raw_diff
+        when Hash
+          init_from_hash(raw_diff, collapse: collapse)
+        when Rugged::Patch, Rugged::Diff::Delta
+          init_from_rugged(raw_diff, collapse: collapse)
+        when nil
+          raise "Nil as raw diff passed"
         else
           raise "Invalid raw diff type: #{raw_diff.class}"
         end
@@ -196,12 +203,16 @@ module Gitlab
 
       def too_large?
         if @too_large.nil?
-          @too_large = @diff.bytesize >= 102400 # 100 KB
+          @too_large = @diff.bytesize >= DIFF_SIZE_LIMIT
         else
           @too_large
         end
       end
 
+      def collapsible?
+        @diff.bytesize >= DIFF_COLLAPSE_LIMIT
+      end
+
       def prune_large_diff!
         @diff = ''
         @line_count = 0
@@ -213,10 +224,6 @@ module Gitlab
         false
       end
 
-      def collapsible?
-        @diff.bytesize >= 10240 # 10 KB
-      end
-
       def prune_collapsed_diff!
         @diff = ''
         @line_count = 0
@@ -225,10 +232,14 @@ module Gitlab
 
       private
 
-      def init_from_rugged(rugged)
-        @diff = encode!(strip_diff_headers(rugged.to_s))
+      def init_from_rugged(rugged, collapse: false)
+        if rugged.is_a?(Rugged::Patch)
+          init_from_rugged_patch(rugged, collapse: collapse)
+          d = rugged.delta
+        else
+          d = rugged
+        end
 
-        d = rugged.delta
         @new_path = encode!(d.new_file[:path])
         @old_path = encode!(d.old_file[:path])
         @a_mode = d.old_file[:mode].to_s(8)
@@ -238,12 +249,46 @@ module Gitlab
         @deleted_file = d.deleted?
       end
 
-      def init_from_hash(hash)
+      def init_from_rugged_patch(patch, collapse: false)
+        # Don't bother initializing diffs that are too large. If a diff is
+        # binary we're not going to display anything so we skip the size check.
+        unless patch.delta.binary?
+          diff_size = patch_size(patch)
+
+          if diff_size >= DIFF_SIZE_LIMIT
+            prune_large_diff!
+            return
+          elsif collapse && diff_size >= DIFF_COLLAPSE_LIMIT
+            prune_collapsed_diff!
+            return
+          end
+        end
+
+        @diff = encode!(strip_diff_headers(patch.to_s))
+      end
+
+      def init_from_hash(hash, collapse: false)
         raw_diff = hash.symbolize_keys
 
         serialize_keys.each do |key|
           send(:"#{key}=", raw_diff[key.to_sym])
         end
+
+        prune_large_diff! if too_large?
+        prune_collapsed_diff! if collapse && collapsible?
+      end
+
+      # Returns the size of a diff without taking any diff markers into account.
+      def patch_size(patch)
+        size = 0
+
+        patch.each_hunk do |hunk|
+          hunk.each_line do |line|
+            size += line.content.bytesize
+          end
+        end
+
+        size
       end
 
       # Strip out the information at the beginning of the patch's text to match
diff --git a/lib/gitlab_git/diff_collection.rb b/lib/gitlab_git/diff_collection.rb
index 1468b1b..3862894 100644
--- a/lib/gitlab_git/diff_collection.rb
+++ b/lib/gitlab_git/diff_collection.rb
@@ -15,6 +15,7 @@ module Gitlab
         @safe_max_bytes = @safe_max_files * 5120 # Average 5 KB per file
         @all_diffs = !!options.fetch(:all_diffs, false)
         @no_collapse = !!options.fetch(:no_collapse, true)
+        @deltas_only = !!options.fetch(:deltas_only, false)
 
         @line_count = 0
         @byte_count = 0
@@ -22,52 +23,14 @@ module Gitlab
         @array = Array.new
       end
 
-      def each
-        @iterator.each_with_index do |raw, i|
-          # First yield cached Diff instances from @array
-          if @array[i]
-            yield @array[i]
-            next
-          end
-
-          # We have exhausted @array, time to create new Diff instances or stop.
-          break if @overflow
-
-          if !@all_diffs && i >= @max_files
-            @overflow = true
-            break
-          end
-
-          # Going by the number of files alone it is OK to create a new Diff instance.
-          diff = Gitlab::Git::Diff.new(raw)
-
-          # If a diff is too large we still want to display some information
-          # about it (e.g. the file path) without keeping the raw data around
-          # (as this would be a waste of memory usage).
-          #
-          # This also removes the line count (from the diff itself) so it
-          # doesn't add up to the total amount of lines.
-          if diff.too_large?
-            diff.prune_large_diff!
-          end
-
-          if !@all_diffs && !@no_collapse
-            if diff.collapsible? || over_safe_limits?(i)
-              diff.prune_collapsed_diff!
-            end
-          end
-
-          @line_count += diff.line_count
-          @byte_count += diff.diff.bytesize
-
-          if !@all_diffs && (@line_count >= @max_lines || @byte_count >= @max_bytes)
-            # This last Diff instance pushes us over the lines limit. We stop and
-            # discard it.
-            @overflow = true
-            break
-          end
-
-          yield @array[i] = diff
+      def each(&block)
+        if @populated
+          # @iterator.each is slower than just iterating the array in place
+          @array.each(&block)
+        elsif @deltas_only
+          each_delta(&block)
+        else
+          each_patch(&block)
         end
       end
 
@@ -81,7 +44,7 @@ module Gitlab
       end
 
       def size
-        @size ||= count # forces a loop through @iterator
+        @size ||= count # forces a loop using each method
       end
 
       def real_size
@@ -95,9 +58,11 @@ module Gitlab
       end
 
       def decorate!
-        each_with_index do |element, i|
+        collection = each_with_index do |element, i|
           @array[i] = yield(element)
         end
+        @populated = true
+        collection
       end
 
       private
@@ -113,6 +78,52 @@ module Gitlab
       def over_safe_limits?(files)
         files >= @safe_max_files || @line_count > @safe_max_lines || @byte_count >= @safe_max_bytes
       end
+
+      def each_delta
+        @iterator.each_delta.with_index do |delta, i|
+          diff = Gitlab::Git::Diff.new(delta)
+
+          yield @array[i] = diff
+        end
+      end
+
+      def each_patch
+        @iterator.each_with_index do |raw, i|
+          # First yield cached Diff instances from @array
+          if @array[i]
+            yield @array[i]
+            next
+          end
+
+          # We have exhausted @array, time to create new Diff instances or stop.
+          break if @overflow
+
+          if !@all_diffs && i >= @max_files
+            @overflow = true
+            break
+          end
+
+          collapse = !@all_diffs && !@no_collapse
+
+          diff = Gitlab::Git::Diff.new(raw, collapse: collapse)
+
+          if collapse && over_safe_limits?(i)
+            diff.prune_collapsed_diff!
+          end
+
+          @line_count += diff.line_count
+          @byte_count += diff.diff.bytesize
+
+          if !@all_diffs && (@line_count >= @max_lines || @byte_count >= @max_bytes)
+            # This last Diff instance pushes us over the lines limit. We stop and
+            # discard it.
+            @overflow = true
+            break
+          end
+
+          yield @array[i] = diff
+        end
+      end
     end
   end
 end
diff --git a/lib/gitlab_git/ref.rb b/lib/gitlab_git/ref.rb
index 71d8769..df1747e 100644
--- a/lib/gitlab_git/ref.rb
+++ b/lib/gitlab_git/ref.rb
@@ -2,7 +2,7 @@ module Gitlab
   module Git
     class Ref
       include EncodingHelper
-      
+
       # Branch or tag name
       # without "refs/tags|heads" prefix
       attr_reader :name
@@ -20,18 +20,17 @@ module Gitlab
         str.gsub(/\Arefs\/heads\//, '')
       end
 
-      def initialize(name, target)
+      def self.dereference_object(object)
+        object = object.target while object.is_a?(Rugged::Tag::Annotation)
+
+        object
+      end
+
+      def initialize(repository, name, target)
         encode! name
         @name = name.gsub(/\Arefs\/(tags|heads)\//, '')
-        @target = if target.respond_to?(:oid)
-                    target.oid
-                  elsif target.respond_to?(:name)
-                    target.name
-                  elsif target.is_a? String
-                    target
-                  else
-                    nil
-                  end
+
+        @target = Commit.find(repository, target)
       end
     end
   end
diff --git a/lib/gitlab_git/repository.rb b/lib/gitlab_git/repository.rb
index 6d567c0..2117090 100644
--- a/lib/gitlab_git/repository.rb
+++ b/lib/gitlab_git/repository.rb
@@ -1,7 +1,9 @@
 # Gitlab::Git::Repository is a wrapper around native Rugged::Repository object
 require_relative 'encoding_helper'
 require_relative 'path_helper'
+require 'forwardable'
 require 'tempfile'
+require 'forwardable'
 require "rubygems/package"
 
 module Gitlab
@@ -25,14 +27,12 @@ module Gitlab
       # Rugged repo object
       attr_reader :rugged
 
-      # Define a delegator for the rugged attributes
-      def_delegator :rugged, :attributes
-
       # 'path' must be the path to a _bare_ git repository, e.g.
       # /path/to/my-repo.git
       def initialize(path)
         @path = path
         @name = path.split("/").last
+        @attributes = Attributes.new(path)
       end
 
       # Default branch in the repository
@@ -61,13 +61,37 @@ module Gitlab
       def branches
         rugged.branches.map do |rugged_ref|
           begin
-            Branch.new(rugged_ref.name, rugged_ref.target)
+            Branch.new(self, rugged_ref.name, rugged_ref.target)
           rescue Rugged::ReferenceError
             # Omit invalid branch
           end
         end.compact.sort_by(&:name)
       end
 
+      def reload_rugged
+        @rugged = nil
+      end
+
+      # Directly find a branch with a simple name (e.g. master)
+      #
+      # force_reload causes a new Rugged repository to be instantiated
+      #
+      # This is to work around a bug in libgit2 that causes in-memory refs to
+      # be stale/invalid when packed-refs is changed.
+      # See https://gitlab.com/gitlab-org/gitlab-ce/issues/15392#note_14538333
+      def find_branch(name, force_reload = false)
+        reload_rugged if force_reload
+
+        rugged_ref = rugged.branches[name]
+        Branch.new(self, rugged_ref.name, rugged_ref.target) if rugged_ref
+      end
+
+      def local_branches
+        rugged.branches.each(:local).map do |branch|
+          Branch.new(self, branch.name, branch.target)
+        end
+      end
+
       # Returns the number of valid branches
       def branch_count
         rugged.branches.count do |ref|
@@ -92,14 +116,17 @@ module Gitlab
           message = nil
 
           if ref.target.is_a?(Rugged::Tag::Annotation)
+            object = ref.target
             tag_message = ref.target.message
 
             if tag_message.respond_to?(:chomp)
               message = tag_message.chomp
             end
+          else
+            object = nil # Lightweight tags aren't git objects
           end
 
-          Tag.new(ref.name, ref.target, message)
+          Tag.new(self, object, ref.name, ref.target, message)
         end.sort_by(&:name)
       end
 
@@ -132,7 +159,7 @@ module Gitlab
       # Deprecated. Will be removed in 5.2
       def heads
         rugged.references.each("refs/heads/*").map do |head|
-          Gitlab::Git::Ref.new(head.name, head.target)
+          Gitlab::Git::Ref.new(self, head.name, head.target)
         end.sort_by(&:name)
       end
 
@@ -264,7 +291,6 @@ module Gitlab
           limit: 10,
           offset: 0,
           path: nil,
-          ref: root_ref,
           follow: false,
           skip_merges: false,
           disable_walk: false,
@@ -337,8 +363,7 @@ module Gitlab
       # annotated tag, then return the tag's target instead.
       def rev_parse_target(revspec)
         obj = rugged.rev_parse(revspec)
-        obj = obj.target while obj.is_a?(Rugged::Tag::Annotation)
-        obj
+        Ref.dereference_object(obj)
       end
 
       # Return a collection of Rugged::Commits between the two revspec arguments.
@@ -745,7 +770,7 @@ module Gitlab
       #   create_branch("other-feature", "master")
       def create_branch(ref, start_point = "HEAD")
         rugged_ref = rugged.branches.create(ref, start_point)
-        Branch.new(rugged_ref.name, rugged_ref.target)
+        Branch.new(self, rugged_ref.name, rugged_ref.target)
       rescue Rugged::ReferenceError => e
         raise InvalidRef.new("Branch #{ref} already exists") if e.to_s =~ /'refs\/heads\/#{ref}'/
         raise InvalidRef.new("Invalid reference #{start_point}")
@@ -943,13 +968,22 @@ module Gitlab
         Dir.mkdir(info_dir_path) unless File.directory?(info_dir_path)
 
         # Write the contents of the .gitattributes file to info/attributes
-        File.write(info_attributes_path, gitattributes_content)
+        # Use binary mode to prevent Rails from converting ASCII-8BIT to UTF-8
+        File.open(info_attributes_path, "wb") do |file|
+          file.write(gitattributes_content)
+        end
       end
 
       # Checks if the blob should be diffable according to its attributes
       def diffable?(blob)
-        blob_attributes = attributes(blob.path).to_h
-        blob_attributes.fetch('diff', blob.text?)
+        attributes(blob.path).fetch('diff') { blob.text? }
+      end
+
+      # Returns the Git attributes for the given file path.
+      #
+      # See `Gitlab::Git::Attributes` for more information.
+      def attributes(path)
+        @attributes.attributes(path)
       end
 
       private
diff --git a/lib/gitlab_git/tag.rb b/lib/gitlab_git/tag.rb
index 634fdb5..f8a5d86 100644
--- a/lib/gitlab_git/tag.rb
+++ b/lib/gitlab_git/tag.rb
@@ -1,8 +1,19 @@
 module Gitlab
   module Git
     class Tag < Ref
-      def initialize(name, target, message = nil)
-        super(name, target)
+      attr_reader :object_sha
+
+      def initialize(repository, object, name, target, message = nil)
+        super(repository, name, target)
+        @object_sha = if object.respond_to?(:oid)
+                        object.oid
+                      elsif object.respond_to?(:name)
+                        object.name
+                      elsif object.is_a? String
+                        object
+                      else
+                        nil
+                      end
         @message = message
       end
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-gitlab-git.git



More information about the Pkg-ruby-extras-commits mailing list