2018-10-22 03:00:50 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-29 05:49:08 -04:00
|
|
|
require_dependency 'gitlab/encoding_helper'
|
|
|
|
|
2014-11-03 14:02:12 -05:00
|
|
|
module Gitlab
|
|
|
|
module Git
|
2018-04-11 23:05:07 -04:00
|
|
|
# The ID of empty tree.
|
|
|
|
# https://github.com/git/git/blob/3ad8b5bf26362ac67c9020bf8c30eee54a84f56d/cache.h#L1011-L1012
|
2019-08-31 15:25:25 -04:00
|
|
|
EMPTY_TREE_ID = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'
|
2015-11-03 07:09:18 -05:00
|
|
|
BLANK_SHA = ('0' * 40).freeze
|
2019-06-13 06:44:41 -04:00
|
|
|
COMMIT_ID = /\A[0-9a-f]{40}\z/.freeze
|
2019-08-31 15:25:25 -04:00
|
|
|
TAG_REF_PREFIX = "refs/tags/"
|
|
|
|
BRANCH_REF_PREFIX = "refs/heads/"
|
2015-01-15 13:26:33 -05:00
|
|
|
|
2018-07-31 10:38:03 -04:00
|
|
|
CommandError = Class.new(BaseError)
|
|
|
|
CommitError = Class.new(BaseError)
|
|
|
|
OSError = Class.new(BaseError)
|
|
|
|
UnknownRef = Class.new(BaseError)
|
2020-11-19 10:09:13 -05:00
|
|
|
CommandTimedOut = Class.new(CommandError)
|
2017-02-15 21:08:30 -05:00
|
|
|
|
2015-03-10 06:51:36 -04:00
|
|
|
class << self
|
2017-06-28 08:20:29 -04:00
|
|
|
include Gitlab::EncodingHelper
|
|
|
|
|
2015-03-10 06:51:36 -04:00
|
|
|
def ref_name(ref)
|
2018-01-27 00:35:53 -05:00
|
|
|
encode!(ref).sub(%r{\Arefs/(tags|heads|remotes)/}, '')
|
2015-03-10 06:51:36 -04:00
|
|
|
end
|
|
|
|
|
2016-07-28 00:04:57 -04:00
|
|
|
def branch_name(ref)
|
|
|
|
ref = ref.to_s
|
|
|
|
if self.branch_ref?(ref)
|
|
|
|
self.ref_name(ref)
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def tag_name(ref)
|
|
|
|
ref = ref.to_s
|
|
|
|
if self.tag_ref?(ref)
|
|
|
|
self.ref_name(ref)
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-03-10 06:51:36 -04:00
|
|
|
def tag_ref?(ref)
|
2018-11-22 18:21:29 -05:00
|
|
|
ref =~ /^#{TAG_REF_PREFIX}.+/
|
2015-03-10 06:51:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def branch_ref?(ref)
|
2018-11-22 18:21:29 -05:00
|
|
|
ref =~ /^#{BRANCH_REF_PREFIX}.+/
|
2015-03-10 06:51:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def blank_ref?(ref)
|
|
|
|
ref == BLANK_SHA
|
|
|
|
end
|
2015-12-14 20:30:55 -05:00
|
|
|
|
2019-06-13 06:44:41 -04:00
|
|
|
def commit_id?(ref)
|
|
|
|
COMMIT_ID.match?(ref)
|
|
|
|
end
|
|
|
|
|
2015-12-14 20:30:55 -05:00
|
|
|
def version
|
2018-06-08 05:16:21 -04:00
|
|
|
Gitlab::Git::Version.git_version
|
2015-12-14 20:30:55 -05:00
|
|
|
end
|
2017-09-19 13:09:10 -04:00
|
|
|
|
|
|
|
def check_namespace!(*objects)
|
|
|
|
expected_namespace = self.name + '::'
|
|
|
|
objects.each do |object|
|
|
|
|
unless object.class.name.start_with?(expected_namespace)
|
|
|
|
raise ArgumentError, "expected object in #{expected_namespace}, got #{object}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-10-10 13:44:14 -04:00
|
|
|
|
|
|
|
def diff_line_code(file_path, new_line_position, old_line_position)
|
|
|
|
"#{Digest::SHA1.hexdigest(file_path)}_#{old_line_position}_#{new_line_position}"
|
|
|
|
end
|
2017-11-22 09:48:09 -05:00
|
|
|
|
|
|
|
def shas_eql?(sha1, sha2)
|
2019-12-18 10:08:03 -05:00
|
|
|
return true if sha1.nil? && sha2.nil?
|
2017-11-22 09:48:09 -05:00
|
|
|
return false if sha1.nil? || sha2.nil?
|
2021-07-05 05:07:37 -04:00
|
|
|
return false unless sha1.instance_of?(sha2.class)
|
2017-11-22 09:48:09 -05:00
|
|
|
|
|
|
|
# If either of the shas is below the minimum length, we cannot be sure
|
|
|
|
# that they actually refer to the same commit because of hash collision.
|
|
|
|
length = [sha1.length, sha2.length].min
|
|
|
|
return false if length < Gitlab::Git::Commit::MIN_SHA_LENGTH
|
|
|
|
|
|
|
|
sha1[0, length] == sha2[0, length]
|
|
|
|
end
|
2015-01-15 13:26:33 -05:00
|
|
|
end
|
2014-11-03 14:02:12 -05:00
|
|
|
end
|
|
|
|
end
|