2016-06-20 12:51:48 -04:00
|
|
|
module Gitlab
|
|
|
|
module Diff
|
|
|
|
class DiffRefs
|
|
|
|
attr_reader :base_sha
|
|
|
|
attr_reader :start_sha
|
|
|
|
attr_reader :head_sha
|
|
|
|
|
|
|
|
def initialize(base_sha:, start_sha: base_sha, head_sha:)
|
|
|
|
@base_sha = base_sha
|
|
|
|
@start_sha = start_sha
|
|
|
|
@head_sha = head_sha
|
|
|
|
end
|
|
|
|
|
|
|
|
def ==(other)
|
|
|
|
other.is_a?(self.class) &&
|
2017-09-22 05:30:37 -04:00
|
|
|
shas_equal?(base_sha, other.base_sha) &&
|
|
|
|
shas_equal?(start_sha, other.start_sha) &&
|
|
|
|
shas_equal?(head_sha, other.head_sha)
|
2016-06-20 12:51:48 -04:00
|
|
|
end
|
|
|
|
|
2017-03-31 19:49:43 -04:00
|
|
|
alias_method :eql?, :==
|
|
|
|
|
|
|
|
def hash
|
|
|
|
[base_sha, start_sha, head_sha].hash
|
|
|
|
end
|
|
|
|
|
2016-07-06 19:28:13 -04:00
|
|
|
# There is only one case in which we will have `start_sha` and `head_sha`,
|
|
|
|
# but not `base_sha`, which is when a diff is generated between an
|
|
|
|
# orphaned branch and another branch, which means there _is_ no base, but
|
|
|
|
# we're still able to highlight it, and to create diff notes, which are
|
|
|
|
# the primary things `DiffRefs` are used for.
|
|
|
|
# `DiffRefs` are "complete" when they have `start_sha` and `head_sha`,
|
|
|
|
# because `base_sha` can always be derived from this, to return an actual
|
|
|
|
# sha, or `nil`.
|
|
|
|
# We have `base_sha` directly available on `DiffRefs` because it's faster#
|
|
|
|
# than having to look it up in the repo every time.
|
2016-06-20 12:51:48 -04:00
|
|
|
def complete?
|
|
|
|
start_sha && head_sha
|
|
|
|
end
|
2017-06-06 12:46:28 -04:00
|
|
|
|
|
|
|
def compare_in(project)
|
|
|
|
# We're at the initial commit, so just get that as we can't compare to anything.
|
|
|
|
if Gitlab::Git.blank_ref?(start_sha)
|
|
|
|
project.commit(head_sha)
|
|
|
|
else
|
|
|
|
straight = start_sha == base_sha
|
|
|
|
CompareService.new(project, head_sha).execute(project, start_sha, straight: straight)
|
|
|
|
end
|
|
|
|
end
|
2017-09-22 05:30:37 -04:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def shas_equal?(sha1, sha2)
|
|
|
|
return true if sha1 == sha2
|
|
|
|
return false if sha1.nil? || sha2.nil?
|
|
|
|
return false unless sha1.class == sha2.class
|
|
|
|
|
|
|
|
length = [sha1.length, sha2.length].min
|
|
|
|
|
2017-09-25 04:23:43 -04: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.
|
2017-09-22 05:30:37 -04:00
|
|
|
return false if length < Commit::MIN_SHA_LENGTH
|
|
|
|
|
|
|
|
sha1[0, length] == sha2[0, length]
|
|
|
|
end
|
2016-06-20 12:51:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|