Class: MergeRequestDiff

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Sortable
Defined in:
app/models/merge_request_diff.rb

Overview

Schema Information

Table name: merge_request_diffs

id               :integer          not null, primary key
state            :string
st_commits       :text
st_diffs         :text
merge_request_id :integer          not null
created_at       :datetime
updated_at       :datetime
base_commit_sha  :string
real_size        :string

Constant Summary collapse

COMMITS_SAFE_SIZE =

Prevent store of diff if commits amount more then 500

100

Instance Method Summary collapse

Instance Method Details

#base_commitObject


78
79
80
81
82
# File 'app/models/merge_request_diff.rb', line 78

def base_commit
  return nil unless self.base_commit_sha

  merge_request.target_project.commit(self.base_commit_sha)
end

#commitsObject


66
67
68
# File 'app/models/merge_request_diff.rb', line 66

def commits
  @commits ||= load_commits(st_commits || [])
end

#compareObject


182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/models/merge_request_diff.rb', line 182

def compare
  @compare ||=
    begin
      # Update ref for merge request
      merge_request.fetch_ref

      Gitlab::Git::Compare.new(
        self.repository.raw_repository,
        self.target_branch,
        self.source_sha
      )
    end
end

#diffs(options = {}) ⇒ Object


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'app/models/merge_request_diff.rb', line 51

def diffs(options={})
  if options[:ignore_whitespace_change]
    @diffs_no_whitespace ||= begin
      compare = Gitlab::Git::Compare.new(
        self.repository.raw_repository,
        self.target_branch,
        self.source_sha,
      )
      compare.diffs(options)
    end
  else
    @diffs ||= load_diffs(st_diffs, options)
  end
end

#dump_commits(commits) ⇒ Object


88
89
90
# File 'app/models/merge_request_diff.rb', line 88

def dump_commits(commits)
  commits.map(&:to_hash)
end

#dump_diffs(diffs) ⇒ Object


96
97
98
99
100
# File 'app/models/merge_request_diff.rb', line 96

def dump_diffs(diffs)
  if diffs.respond_to?(:map)
    diffs.map(&:to_hash)
  end
end

#first_commitObject


74
75
76
# File 'app/models/merge_request_diff.rb', line 74

def first_commit
  commits.last
end

#last_commitObject


70
71
72
# File 'app/models/merge_request_diff.rb', line 70

def last_commit
  commits.first
end

#last_commit_short_shaObject


84
85
86
# File 'app/models/merge_request_diff.rb', line 84

def last_commit_short_sha
  @last_commit_short_sha ||= last_commit.short_id
end

#load_commits(array) ⇒ Object


92
93
94
# File 'app/models/merge_request_diff.rb', line 92

def load_commits(array)
  array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash), merge_request.source_project) }
end

#load_diffs(raw, options) ⇒ Object


102
103
104
105
106
107
108
# File 'app/models/merge_request_diff.rb', line 102

def load_diffs(raw, options)
  if raw.respond_to?(:each)
    Gitlab::Git::DiffCollection.new(raw, options)
  else
    Gitlab::Git::DiffCollection.new([])
  end
end

#reload_commitsObject

Reload all commits related to current merge request from repo and save it as array of hashes in st_commits db field


126
127
128
129
130
131
132
133
134
# File 'app/models/merge_request_diff.rb', line 126

def reload_commits
  commit_objects = unmerged_commits

  if commit_objects.present?
    self.st_commits = dump_commits(commit_objects)
  end

  save
end

#reload_contentObject


42
43
44
45
# File 'app/models/merge_request_diff.rb', line 42

def reload_content
  reload_commits
  reload_diffs
end

#reload_diffsObject

Reload diffs between branches related to current merge request from repo and save it as array of hashes in st_diffs db field


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'app/models/merge_request_diff.rb', line 138

def reload_diffs
  new_diffs = []

  if commits.size.zero?
    self.state = :empty
  else
    diff_collection = unmerged_diffs

    if diff_collection.overflow?
      # Set our state to 'overflow' to make the #empty? and #collected?
      # methods (generated by StateMachine) return false.
      self.state = :overflow
    end

    self.real_size = diff_collection.real_size

    if diff_collection.any?
      new_diffs = dump_diffs(diff_collection)
      self.state = :collected
    end
  end

  self.st_diffs = new_diffs

  self.base_commit_sha = self.repository.merge_base(self.source_sha, self.target_branch)

  self.save
end

#repositoryObject


173
174
175
# File 'app/models/merge_request_diff.rb', line 173

def repository
  merge_request.target_project.repository
end

#sizeObject


47
48
49
# File 'app/models/merge_request_diff.rb', line 47

def size
  real_size.presence || diffs.size
end

#source_shaObject


177
178
179
180
# File 'app/models/merge_request_diff.rb', line 177

def source_sha
  source_commit = merge_request.source_project.commit(source_branch)
  source_commit.try(:sha)
end

#unmerged_commitsObject

Collect array of Git::Commit objects between target and source branches


112
113
114
115
116
117
118
119
120
121
122
# File 'app/models/merge_request_diff.rb', line 112

def unmerged_commits
  commits = compare.commits

  if commits.present?
    commits = Commit.decorate(commits, merge_request.source_project).
      sort_by(&:created_at).
      reverse
  end

  commits
end

#unmerged_diffsObject

Collect array of Git::Diff objects between target and source branches


169
170
171
# File 'app/models/merge_request_diff.rb', line 169

def unmerged_diffs
  compare.diffs(Commit.max_diff_options)
end