1# External dependencies of Gitlab::Git
2require 'rugged'
3require 'linguist/blob_helper'
4require 'securerandom'
5
6# Ruby on Rails mix-ins that GitLab::Git code relies on
7require 'active_support/core_ext/object/blank'
8require 'active_support/core_ext/numeric/bytes'
9require 'active_support/core_ext/numeric/time'
10require 'active_support/core_ext/integer/time'
11require 'active_support/core_ext/module/delegation'
12require 'active_support/core_ext/enumerable'
13
14require_relative 'git_logger.rb'
15require_relative 'rails_logger.rb'
16require_relative 'gollum.rb'
17require_relative 'config.rb'
18
19dir = __dir__
20
21# Some later requires are order-sensitive. Manually require whatever we need.
22require_relative "#{dir}/encoding_helper.rb"
23require_relative "#{dir}/utils/strong_memoize.rb"
24require_relative "#{dir}/ref_matcher.rb"
25require_relative "#{dir}/git/remote_repository.rb"
26require_relative "#{dir}/git/popen.rb"
27require_relative "#{dir}/git/repository_mirroring.rb"
28
29# Require all .rb files we can find in the gitlab lib directory
30Dir["#{dir}/**/*.rb"].sort.each do |ruby_file|
31  require File.expand_path(ruby_file)
32end
33
34class String
35  # Because we are not rendering HTML, this is a no-op in gitaly-ruby.
36  def html_safe
37    self
38  end
39end
40
41module Gitlab
42  module Git
43    # The ID of empty tree.
44    # See http://stackoverflow.com/a/40884093/1856239 and
45    # https://github.com/git/git/blob/3ad8b5bf26362ac67c9020bf8c30eee54a84f56d/cache.h#L1011-L1012
46    EMPTY_TREE_ID = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'.freeze
47    BLANK_SHA = ('0' * 40).freeze
48    TAG_REF_PREFIX = "refs/tags/".freeze
49    BRANCH_REF_PREFIX = "refs/heads/".freeze
50
51    BaseError = Class.new(StandardError)
52    CommandError = Class.new(BaseError)
53    CommitError = Class.new(BaseError)
54    OSError = Class.new(BaseError)
55    UnknownRef = Class.new(BaseError)
56    PreReceiveError = Class.new(BaseError)
57    PatchError = Class.new(BaseError)
58
59    class << self
60      include Gitlab::EncodingHelper
61
62      def ref_name(ref)
63        encode!(ref).sub(%r{\Arefs/(tags|heads|remotes)/}, '')
64      end
65
66      def branch_name(ref)
67        ref = ref.to_s
68        self.ref_name(ref) if self.branch_ref?(ref)
69      end
70
71      def committer_hash(email:, name:, timestamp: nil)
72        return if email.nil? || name.nil?
73
74        # Git strips newlines and angle brackets silently.
75        # libgit2/Rugged doesn't, but aborts if angle brackets are present.
76        # See upstream issue https://github.com/libgit2/libgit2/issues/5342
77        email = email.delete("\n<>")
78        name = name.delete("\n<>")
79        time = timestamp ? Time.at(timestamp.seconds, timestamp.nanos, :nsec, in: "+00:00") : Time.now
80
81        {
82          email: email,
83          name: name,
84          time: time
85        }
86      end
87
88      def tag_name(ref)
89        ref = ref.to_s
90        self.ref_name(ref) if self.tag_ref?(ref)
91      end
92
93      def tag_ref?(ref)
94        ref.start_with?(TAG_REF_PREFIX)
95      end
96
97      def branch_ref?(ref)
98        ref.start_with?(BRANCH_REF_PREFIX)
99      end
100
101      def blank_ref?(ref)
102        ref == BLANK_SHA
103      end
104
105      def version
106        Gitlab::Git::Version.git_version
107      end
108
109      def diff_line_code(file_path, new_line_position, old_line_position)
110        "#{Digest::SHA1.hexdigest(file_path)}_#{old_line_position}_#{new_line_position}"
111      end
112
113      def shas_eql?(sha1, sha2)
114        return false if sha1.nil? || sha2.nil?
115        return false unless sha1.class == sha2.class
116
117        # If either of the shas is below the minimum length, we cannot be sure
118        # that they actually refer to the same commit because of hash collision.
119        length = [sha1.length, sha2.length].min
120        return false if length < Gitlab::Git::Commit::MIN_SHA_LENGTH
121
122        sha1[0, length] == sha2[0, length]
123      end
124    end
125  end
126end
127
128module Gitlab
129  module GlId
130    def self.gl_id(user)
131      user.gl_id
132    end
133
134    def self.gl_id_from_id_value(id)
135      "user-#{id}"
136    end
137  end
138end
139