diff options
author | Douwe Maan <douwe@selenight.nl> | 2017-09-22 12:30:37 +0300 |
---|---|---|
committer | Douwe Maan <douwe@selenight.nl> | 2017-09-25 11:22:28 +0300 |
commit | b9857d8b662a2dbbf54f46ecdcecb44702affe55 (patch) | |
tree | 8a25798bc0c8e1c15ae414ac667ff5465f6fefa2 /lib | |
parent | c19d5ac1a2ac75fd7200aacae3514e5600a7f648 (diff) |
Properly compare diff refs and diff positions when shas are truncated
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/diff/diff_refs.rb | 22 | ||||
-rw-r--r-- | lib/gitlab/diff/position.rb | 11 |
2 files changed, 25 insertions, 8 deletions
diff --git a/lib/gitlab/diff/diff_refs.rb b/lib/gitlab/diff/diff_refs.rb index 371cbe04b9b..1c4c1deb7a9 100644 --- a/lib/gitlab/diff/diff_refs.rb +++ b/lib/gitlab/diff/diff_refs.rb @@ -13,9 +13,9 @@ module Gitlab def ==(other) other.is_a?(self.class) && - base_sha == other.base_sha && - start_sha == other.start_sha && - head_sha == other.head_sha + shas_equal?(base_sha, other.base_sha) && + shas_equal?(start_sha, other.start_sha) && + shas_equal?(head_sha, other.head_sha) end alias_method :eql?, :== @@ -47,6 +47,22 @@ module Gitlab CompareService.new(project, head_sha).execute(project, start_sha, straight: straight) end end + + 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 + + # If either of the shas is below 7 characters in length, we cannot be sure + # if they actually refer to the same commit because of hash collision. + return false if length < Commit::MIN_SHA_LENGTH + + sha1[0, length] == sha2[0, length] + end end end end diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb index f80afb20f0c..b8db3adef0a 100644 --- a/lib/gitlab/diff/position.rb +++ b/lib/gitlab/diff/position.rb @@ -49,12 +49,13 @@ module Gitlab coder['attributes'] = self.to_h end - def key - @key ||= [base_sha, start_sha, head_sha, Digest::SHA1.hexdigest(old_path || ""), Digest::SHA1.hexdigest(new_path || ""), old_line, new_line] - end - def ==(other) - other.is_a?(self.class) && key == other.key + other.is_a?(self.class) && + other.diff_refs == diff_refs && + other.old_path == old_path && + other.new_path == new_path && + other.old_line == old_line && + other.new_line == new_line end def to_h |