Commit 54bcb6cc2a863e10abdd76745d3a0d50c301ab77

Authored by Marin Jankovski
2 parents d819d0d1 d1d13856

Merge branch 'master' into reference_relative_links

Conflicts:
	spec/models/project_spec.rb
Showing 138 changed files with 841 additions and 690 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 138 files displayed.

CHANGELOG
  1 +v 6.5.1
  2 + - Fix branch selectbox when create merge request from fork
  3 +
1 4 v 6.5.0
2 5 - Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard)
3 6 - Add color custimization and previewing to broadcast messages
... ...
Gemfile
... ... @@ -14,7 +14,6 @@ gem "protected_attributes"
14 14 gem 'rails-observers'
15 15 gem 'actionpack-page_caching'
16 16 gem 'actionpack-action_caching'
17   -gem 'activerecord-deprecated_finders'
18 17  
19 18 # Supported DBs
20 19 gem "mysql2", group: :mysql
... ...
Gemfile.lock
... ... @@ -551,7 +551,6 @@ PLATFORMS
551 551 DEPENDENCIES
552 552 actionpack-action_caching
553 553 actionpack-page_caching
554   - activerecord-deprecated_finders
555 554 acts-as-taggable-on
556 555 annotate (~> 2.6.0.beta2)
557 556 asciidoctor
... ...
PROCESS.md
... ... @@ -73,7 +73,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue
73 73  
74 74 ### Feature requests
75 75  
76   -Thanks for your interest in GitLab. We don't use the GitHub issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
  76 +Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
77 77  
78 78 ### Issue report for old version
79 79  
... ... @@ -81,7 +81,7 @@ Thanks for the issue report but we only support issues for the latest stable ver
81 81  
82 82 ### Support requests and configuration questions
83 83  
84   -Thanks for your interest in GitLab. We don't use the GitHub issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the unofficial #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
  84 +Thanks for your interest in GitLab. We don't use the issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the unofficial #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
85 85  
86 86 ### Code format
87 87  
... ...
VERSION
1   -6.5.0
  1 +6.5.1
... ...
app/assets/stylesheets/sections/login.scss
... ... @@ -6,11 +6,10 @@
6 6 }
7 7  
8 8 .login-box{
9   - width: 304px;
  9 + max-width: 304px;
10 10 position: relative;
11 11 @include border-radius(5px);
12 12 margin: auto;
13   - padding: 20px;
14 13 background: white;
15 14 }
16 15  
... ... @@ -23,7 +22,7 @@
23 22 background-color: #f1f1f1;
24 23 font-size: 16px;
25 24 padding: 14px 10px;
26   - width: 280px;
  25 + width: 100%;
27 26 height: auto;
28 27  
29 28 &.top {
... ...
app/assets/stylesheets/sections/merge_requests.scss
... ... @@ -89,16 +89,3 @@
89 89 .merge-request-form-info {
90 90 padding-top: 15px;
91 91 }
92   -
93   -.merge-request-branches {
94   - .commit-row-message {
95   - font-weight: normal !important;
96   - }
97   -
98   - .select2-container .select2-single {
99   - span {
100   - font-weight: bold;
101   - color: #555;
102   - }
103   - }
104   -}
... ...
app/controllers/admin/groups_controller.rb
... ... @@ -52,6 +52,6 @@ class Admin::GroupsController < Admin::ApplicationController
52 52 private
53 53  
54 54 def group
55   - @group = Group.find_by_path(params[:id])
  55 + @group = Group.find_by(path: params[:id])
56 56 end
57 57 end
... ...
app/controllers/admin/projects_controller.rb
... ... @@ -5,7 +5,7 @@ class Admin::ProjectsController < Admin::ApplicationController
5 5  
6 6 def index
7 7 owner_id = params[:owner_id]
8   - user = User.find_by_id(owner_id)
  8 + user = User.find_by(id: owner_id)
9 9  
10 10 @projects = user ? user.owned_projects : Project.all
11 11 @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
... ...
app/controllers/admin/users_controller.rb
... ... @@ -100,6 +100,6 @@ class Admin::UsersController < Admin::ApplicationController
100 100 protected
101 101  
102 102 def user
103   - @user ||= User.find_by_username!(params[:id])
  103 + @user ||= User.find_by!(username: params[:id])
104 104 end
105 105 end
... ...
app/controllers/dashboard_controller.rb
... ... @@ -41,7 +41,7 @@ class DashboardController < ApplicationController
41 41 current_user.authorized_projects
42 42 end
43 43  
44   - @projects = @projects.where(namespace_id: Group.find_by_name(params[:group])) if params[:group].present?
  44 + @projects = @projects.where(namespace_id: Group.find_by(name: params[:group])) if params[:group].present?
45 45 @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
46 46 @projects = @projects.includes(:namespace)
47 47 @projects = @projects.tagged_with(params[:label]) if params[:label].present?
... ...
app/controllers/groups_controller.rb
... ... @@ -87,7 +87,7 @@ class GroupsController < ApplicationController
87 87 protected
88 88  
89 89 def group
90   - @group ||= Group.find_by_path(params[:id])
  90 + @group ||= Group.find_by(path: params[:id])
91 91 end
92 92  
93 93 def projects
... ...
app/controllers/profiles/groups_controller.rb
... ... @@ -19,6 +19,6 @@ class Profiles::GroupsController < ApplicationController
19 19 private
20 20  
21 21 def group
22   - @group ||= Group.find_by_path(params[:id])
  22 + @group ||= Group.find_by(path: params[:id])
23 23 end
24 24 end
... ...
app/controllers/projects/issues_controller.rb
... ... @@ -97,7 +97,7 @@ class Projects::IssuesController < Projects::ApplicationController
97 97  
98 98 def issue
99 99 @issue ||= begin
100   - @project.issues.find_by_iid!(params[:id])
  100 + @project.issues.find_by!(iid: params[:id])
101 101 rescue ActiveRecord::RecordNotFound
102 102 redirect_old
103 103 end
... ... @@ -127,7 +127,7 @@ class Projects::IssuesController < Projects::ApplicationController
127 127 # To prevent 404 errors we provide a redirect to correct iids until 7.0 release
128 128 #
129 129 def redirect_old
130   - issue = @project.issues.find_by_id(params[:id])
  130 + issue = @project.issues.find_by(id: params[:id])
131 131  
132 132 if issue
133 133 redirect_to project_issue_path(@project, issue)
... ...
app/controllers/projects/merge_requests_controller.rb
... ... @@ -76,7 +76,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
76 76 @merge_request.author = current_user
77 77 @target_branches ||= []
78 78 if @merge_request.save
79   - @merge_request.reload_code
80 79 redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully created.'
81 80 else
82 81 @source_project = @merge_request.source_project
... ... @@ -152,6 +151,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
152 151 @target_project = selected_target_project
153 152 @target_branches = @target_project.repository.branch_names
154 153 @target_branches
  154 +
  155 + respond_to do |format|
  156 + format.js
  157 + end
155 158 end
156 159  
157 160 def ci_status
... ... @@ -168,7 +171,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
168 171 end
169 172  
170 173 def merge_request
171   - @merge_request ||= @project.merge_requests.find_by_iid!(params[:id])
  174 + @merge_request ||= @project.merge_requests.find_by!(iid: params[:id])
172 175 end
173 176  
174 177 def closes_issues
... ... @@ -213,6 +216,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
213 216 # or from cache if already merged
214 217 @commits = @merge_request.commits
215 218  
  219 + @merge_request_diff = @merge_request.merge_request_diff
216 220 @allowed_to_merge = allowed_to_merge?
217 221 @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
218 222 end
... ...
app/controllers/projects/milestones_controller.rb
... ... @@ -76,7 +76,7 @@ class Projects::MilestonesController < Projects::ApplicationController
76 76 protected
77 77  
78 78 def milestone
79   - @milestone ||= @project.milestones.find_by_iid!(params[:id])
  79 + @milestone ||= @project.milestones.find_by!(iid: params[:id])
80 80 end
81 81  
82 82 def authorize_admin_milestone!
... ...
app/controllers/projects/team_members_controller.rb
... ... @@ -26,7 +26,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
26 26 end
27 27  
28 28 def update
29   - @user_project_relation = project.users_projects.find_by_user_id(member)
  29 + @user_project_relation = project.users_projects.find_by(user_id: member)
30 30 @user_project_relation.update_attributes(params[:team_member])
31 31  
32 32 unless @user_project_relation.valid?
... ... @@ -36,7 +36,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
36 36 end
37 37  
38 38 def destroy
39   - @user_project_relation = project.users_projects.find_by_user_id(member)
  39 + @user_project_relation = project.users_projects.find_by(user_id: member)
40 40 @user_project_relation.destroy
41 41  
42 42 respond_to do |format|
... ... @@ -46,7 +46,7 @@ class Projects::TeamMembersController < Projects::ApplicationController
46 46 end
47 47  
48 48 def leave
49   - project.users_projects.find_by_user_id(current_user).destroy
  49 + project.users_projects.find_by(user_id: current_user).destroy
50 50  
51 51 respond_to do |format|
52 52 format.html { redirect_to :back }
... ... @@ -65,6 +65,6 @@ class Projects::TeamMembersController < Projects::ApplicationController
65 65 protected
66 66  
67 67 def member
68   - @member ||= User.find_by_username(params[:id])
  68 + @member ||= User.find_by(username: params[:id])
69 69 end
70 70 end
... ...
app/controllers/search_controller.rb
... ... @@ -2,8 +2,8 @@ class SearchController < ApplicationController
2 2 include SearchHelper
3 3  
4 4 def show
5   - @project = Project.find_by_id(params[:project_id]) if params[:project_id].present?
6   - @group = Group.find_by_id(params[:group_id]) if params[:group_id].present?
  5 + @project = Project.find_by(id: params[:project_id]) if params[:project_id].present?
  6 + @group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
7 7  
8 8 if @project
9 9 return access_denied! unless can?(current_user, :download_code, @project)
... ...
app/controllers/snippets_controller.rb
... ... @@ -18,7 +18,7 @@ class SnippetsController < ApplicationController
18 18 end
19 19  
20 20 def user_index
21   - @user = User.find_by_username(params[:username])
  21 + @user = User.find_by(username: params[:username])
22 22 @snippets = @user.snippets.fresh.non_expired
23 23  
24 24 if @user == current_user
... ...
app/controllers/users_controller.rb
... ... @@ -2,7 +2,7 @@ class UsersController < ApplicationController
2 2 layout 'navless'
3 3  
4 4 def show
5   - @user = User.find_by_username!(params[:username])
  5 + @user = User.find_by!(username: params[:username])
6 6 @projects = @user.authorized_projects.where(id: current_user.authorized_projects.pluck(:id)).includes(:namespace)
7 7 @events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20)
8 8  
... ...
app/controllers/users_groups_controller.rb
... ... @@ -30,7 +30,7 @@ class UsersGroupsController < ApplicationController
30 30 protected
31 31  
32 32 def group
33   - @group ||= Group.find_by_path(params[:group_id])
  33 + @group ||= Group.find_by(path: params[:group_id])
34 34 end
35 35  
36 36 def authorize_admin_group!
... ...
app/helpers/application_helper.rb
... ... @@ -50,7 +50,7 @@ module ApplicationHelper
50 50 end
51 51  
52 52 def avatar_icon(user_email = '', size = nil)
53   - user = User.find_by_email(user_email)
  53 + user = User.find_by(email: user_email)
54 54 if user && user.avatar.present?
55 55 user.avatar.url
56 56 else
... ...
app/mailers/emails/issues.rb
... ... @@ -8,7 +8,7 @@ module Emails
8 8  
9 9 def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
10 10 @issue = Issue.find(issue_id)
11   - @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
  11 + @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
12 12 @project = @issue.project
13 13 mail(to: recipient(recipient_id), subject: subject("Changed issue ##{@issue.iid}", @issue.title))
14 14 end
... ...
app/mailers/emails/merge_requests.rb
... ... @@ -8,7 +8,7 @@ module Emails
8 8  
9 9 def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
10 10 @merge_request = MergeRequest.find(merge_request_id)
11   - @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
  11 + @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
12 12 @project = @merge_request.project
13 13 mail(to: recipient(recipient_id), subject: subject("Changed merge request ##{@merge_request.iid}", @merge_request.title))
14 14 end
... ...
app/models/merge_request.rb
... ... @@ -31,6 +31,11 @@ class MergeRequest < ActiveRecord::Base
31 31 belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project"
32 32 belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project"
33 33  
  34 + has_one :merge_request_diff, dependent: :destroy
  35 + after_create :create_merge_request_diff
  36 +
  37 + delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
  38 +
34 39 attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :author_id_of_changes, :state_event, :description
35 40  
36 41 attr_accessor :should_remove_source_branch
... ... @@ -53,11 +58,8 @@ class MergeRequest < ActiveRecord::Base
53 58 end
54 59  
55 60 state :opened
56   -
57 61 state :reopened
58   -
59 62 state :closed
60   -
61 63 state :merged
62 64 end
63 65  
... ... @@ -75,15 +77,10 @@ class MergeRequest < ActiveRecord::Base
75 77 end
76 78  
77 79 state :unchecked
78   -
79 80 state :can_be_merged
80   -
81 81 state :cannot_be_merged
82 82 end
83 83  
84   - serialize :st_commits
85   - serialize :st_diffs
86   -
87 84 validates :source_project, presence: true, unless: :allow_broken
88 85 validates :source_branch, presence: true
89 86 validates :target_project, presence: true
... ... @@ -105,7 +102,7 @@ class MergeRequest < ActiveRecord::Base
105 102 scope :closed, -> { with_states(:closed, :merged) }
106 103  
107 104 def validate_branches
108   - if target_project==source_project && target_branch == source_branch
  105 + if target_project == source_project && target_branch == source_branch
109 106 errors.add :branch_conflict, "You can not use same project/branch for source and target"
110 107 end
111 108  
... ... @@ -120,8 +117,7 @@ class MergeRequest < ActiveRecord::Base
120 117 end
121 118  
122 119 def reload_code
123   - self.reloaded_commits
124   - self.reloaded_diffs
  120 + merge_request_diff.reload_content if opened?
125 121 end
126 122  
127 123 def check_if_can_be_merged
... ... @@ -132,42 +128,6 @@ class MergeRequest < ActiveRecord::Base
132 128 end
133 129 end
134 130  
135   - def diffs
136   - @diffs ||= (load_diffs(st_diffs) || [])
137   - end
138   -
139   - def reloaded_diffs
140   - if opened? && unmerged_diffs.any?
141   - self.st_diffs = dump_diffs(unmerged_diffs)
142   - self.save
143   - end
144   - end
145   -
146   - def broken_diffs?
147   - diffs == broken_diffs
148   - rescue
149   - true
150   - end
151   -
152   - def valid_diffs?
153   - !broken_diffs?
154   - end
155   -
156   - def unmerged_diffs
157   - diffs = if for_fork?
158   - Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite
159   - else
160   - Gitlab::Git::Diff.between(target_project.repository, source_branch, target_branch)
161   - end
162   -
163   - diffs ||= []
164   - diffs
165   - end
166   -
167   - def last_commit
168   - commits.first
169   - end
170   -
171 131 def merge_event
172 132 self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last
173 133 end
... ... @@ -176,46 +136,13 @@ class MergeRequest < ActiveRecord::Base
176 136 self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
177 137 end
178 138  
179   - def commits
180   - load_commits(st_commits || [])
181   - end
182   -
183   - def probably_merged?
184   - unmerged_commits.empty? &&
185   - commits.any? && opened?
186   - end
187   -
188   - def reloaded_commits
189   - if opened? && unmerged_commits.any?
190   - self.st_commits = dump_commits(unmerged_commits)
191   - save
192   -
193   - end
194   - commits
195   - end
196   -
197   - def unmerged_commits
198   - if for_fork?
199   - commits = Gitlab::Satellite::MergeAction.new(self.author, self).commits_between
200   - else
201   - commits = target_project.repository.commits_between(self.target_branch, self.source_branch)
202   - end
203   -
204   - if commits.present?
205   - commits = Commit.decorate(commits).
206   - sort_by(&:created_at).
207   - reverse
208   - end
209   - commits
210   - end
211   -
212 139 def merge!(user_id)
213 140 self.author_id_of_changes = user_id
214 141 self.merge
215 142 end
216 143  
217 144 def automerge!(current_user, commit_message = nil)
218   - if Gitlab::Satellite::MergeAction.new(current_user, self).merge!(commit_message) && self.unmerged_commits.empty?
  145 + if Gitlab::Satellite::MergeAction.new(current_user, self).merge!(commit_message)
219 146 self.merge!(current_user.id)
220 147 true
221 148 end
... ... @@ -225,7 +152,10 @@ class MergeRequest < ActiveRecord::Base
225 152 end
226 153  
227 154 def mr_and_commit_notes
228   - commit_ids = commits.map(&:id)
  155 + # Fetch comments only from last 100 commits
  156 + commits_for_notes_limit = 100
  157 + commit_ids = commits.last(commits_for_notes_limit).map(&:id)
  158 +
229 159 project.notes.where(
230 160 "(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))",
231 161 mr_id: id,
... ... @@ -247,10 +177,6 @@ class MergeRequest < ActiveRecord::Base
247 177 Gitlab::Satellite::MergeAction.new(current_user, self).format_patch
248 178 end
249 179  
250   - def last_commit_short_sha
251   - @last_commit_short_sha ||= last_commit.sha[0..10]
252   - end
253   -
254 180 def for_fork?
255 181 target_project != source_project
256 182 end
... ... @@ -327,34 +253,4 @@ class MergeRequest < ActiveRecord::Base
327 253 message << description.to_s
328 254 message
329 255 end
330   -
331   - private
332   -
333   - def dump_commits(commits)
334   - commits.map(&:to_hash)
335   - end
336   -
337   - def load_commits(array)
338   - array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) }
339   - end
340   -
341   - def dump_diffs(diffs)
342   - if diffs == broken_diffs
343   - broken_diffs
344   - elsif diffs.respond_to?(:map)
345   - diffs.map(&:to_hash)
346   - end
347   - end
348   -
349   - def load_diffs(raw)
350   - if raw == broken_diffs
351   - broken_diffs
352   - elsif raw.respond_to?(:map)
353   - raw.map { |hash| Gitlab::Git::Diff.new(hash) }
354   - end
355   - end
356   -
357   - def broken_diffs
358   - [Gitlab::Git::Diff::BROKEN_DIFF]
359   - end
360 256 end
... ...
app/models/merge_request_diff.rb 0 → 100644
... ... @@ -0,0 +1,163 @@
  1 +require Rails.root.join("app/models/commit")
  2 +
  3 +class MergeRequestDiff < ActiveRecord::Base
  4 + # Prevent store of diff
  5 + # if commits amount more then 200
  6 + COMMITS_SAFE_SIZE = 200
  7 +
  8 + attr_reader :commits, :diffs
  9 +
  10 + belongs_to :merge_request
  11 +
  12 + attr_accessible :state, :st_commits, :st_diffs
  13 +
  14 + delegate :target_branch, :source_branch, to: :merge_request, prefix: nil
  15 +
  16 + state_machine :state, initial: :empty do
  17 + state :collected
  18 + state :timeout
  19 + state :overflow_commits_safe_size
  20 + state :overflow_diff_files_limit
  21 + state :overflow_diff_lines_limit
  22 + end
  23 +
  24 + serialize :st_commits
  25 + serialize :st_diffs
  26 +
  27 + after_create :reload_content
  28 +
  29 + def reload_content
  30 + reload_commits
  31 + reload_diffs
  32 + end
  33 +
  34 + def diffs
  35 + @diffs ||= (load_diffs(st_diffs) || [])
  36 + end
  37 +
  38 + def commits
  39 + @commits ||= load_commits(st_commits || [])
  40 + end
  41 +
  42 + def last_commit
  43 + commits.first
  44 + end
  45 +
  46 + def last_commit_short_sha
  47 + @last_commit_short_sha ||= last_commit.sha[0..10]
  48 + end
  49 +
  50 + private
  51 +
  52 + def dump_commits(commits)
  53 + commits.map(&:to_hash)
  54 + end
  55 +
  56 + def load_commits(array)
  57 + array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) }
  58 + end
  59 +
  60 + def dump_diffs(diffs)
  61 + if diffs.respond_to?(:map)
  62 + diffs.map(&:to_hash)
  63 + end
  64 + end
  65 +
  66 + def load_diffs(raw)
  67 + if raw.respond_to?(:map)
  68 + raw.map { |hash| Gitlab::Git::Diff.new(hash) }
  69 + end
  70 + end
  71 +
  72 + # When Git::Diff is not able to get diff
  73 + # because of git timeout it return this value
  74 + def broken_diffs
  75 + [Gitlab::Git::Diff::BROKEN_DIFF]
  76 + end
  77 +
  78 + # Collect array of Git::Commit objects
  79 + # between target and source branches
  80 + def unmerged_commits
  81 + commits = if merge_request.for_fork?
  82 + Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between
  83 + else
  84 + repository.commits_between(target_branch, source_branch)
  85 + end
  86 +
  87 + if commits.present?
  88 + commits = Commit.decorate(commits).
  89 + sort_by(&:created_at).
  90 + reverse
  91 + end
  92 +
  93 + commits
  94 + end
  95 +
  96 + # Reload all commits related to current merge request from repo
  97 + # and save it as array of hashes in st_commits db field
  98 + def reload_commits
  99 + commit_objects = unmerged_commits
  100 +
  101 + if commit_objects.present?
  102 + self.st_commits = dump_commits(commit_objects)
  103 + end
  104 +
  105 + save
  106 + end
  107 +
  108 + # Reload diffs between branches related to current merge request from repo
  109 + # and save it as array of hashes in st_diffs db field
  110 + def reload_diffs
  111 + new_diffs = []
  112 +
  113 + if commits.size.zero?
  114 + self.state = :empty
  115 + elsif commits.size > COMMITS_SAFE_SIZE
  116 + self.state = :overflow_commits_safe_size
  117 + else
  118 + new_diffs = unmerged_diffs
  119 + end
  120 +
  121 + if new_diffs.any?
  122 + if new_diffs.size > Commit::DIFF_HARD_LIMIT_FILES
  123 + self.state = :overflow_diff_files_limit
  124 + new_diffs = []
  125 + end
  126 +
  127 + if new_diffs.sum { |diff| diff.diff.lines.count } > Commit::DIFF_HARD_LIMIT_LINES
  128 + self.state = :overflow_diff_lines_limit
  129 + new_diffs = []
  130 + end
  131 + end
  132 +
  133 + if new_diffs.present?
  134 + new_diffs = dump_commits(new_diffs)
  135 + self.state = :collected
  136 + end
  137 +
  138 + self.st_diffs = new_diffs
  139 + self.save
  140 + end
  141 +
  142 + # Collect array of Git::Diff objects
  143 + # between target and source branches
  144 + def unmerged_diffs
  145 + diffs = if merge_request.for_fork?
  146 + Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite
  147 + else
  148 + Gitlab::Git::Diff.between(repository, source_branch, target_branch)
  149 + end
  150 +
  151 + if diffs == broken_diffs
  152 + self.state = :timeout
  153 + diffs = []
  154 + end
  155 +
  156 + diffs ||= []
  157 + diffs
  158 + end
  159 +
  160 + def repository
  161 + merge_request.target_project.repository
  162 + end
  163 +end
... ...
app/models/note.rb
... ... @@ -123,8 +123,8 @@ class Note &lt; ActiveRecord::Base
123 123  
124 124 def commit_author
125 125 @commit_author ||=
126   - project.users.find_by_email(noteable.author_email) ||
127   - project.users.find_by_name(noteable.author_name)
  126 + project.users.find_by(email: noteable.author_email) ||
  127 + project.users.find_by(name: noteable.author_name)
128 128 rescue
129 129 nil
130 130 end
... ...
app/models/project.rb
... ... @@ -145,10 +145,10 @@ class Project &lt; ActiveRecord::Base
145 145 def find_with_namespace(id)
146 146 if id.include?("/")
147 147 id = id.split("/")
148   - namespace = Namespace.find_by_path(id.first)
  148 + namespace = Namespace.find_by(path: id.first)
149 149 return nil unless namespace
150 150  
151   - where(namespace_id: namespace.id).find_by_path(id.second)
  151 + where(namespace_id: namespace.id).find_by(path: id.second)
152 152 else
153 153 where(path: id, namespace_id: nil).last
154 154 end
... ... @@ -296,7 +296,7 @@ class Project &lt; ActiveRecord::Base
296 296  
297 297 # Get Team Member record by user id
298 298 def team_member_by_id(user_id)
299   - users_projects.find_by_user_id(user_id)
  299 + users_projects.find_by(user_id: user_id)
300 300 end
301 301  
302 302 def name_with_namespace
... ...
app/models/project_services/assembla_service.rb
... ... @@ -16,6 +16,8 @@
16 16 #
17 17  
18 18 class AssemblaService < Service
  19 + attr_accessible :subdomain
  20 +
19 21 include HTTParty
20 22  
21 23 validates :token, presence: true, if: :activated?
... ... @@ -34,12 +36,13 @@ class AssemblaService &lt; Service
34 36  
35 37 def fields
36 38 [
37   - { type: 'text', name: 'token', placeholder: '' }
  39 + { type: 'text', name: 'token', placeholder: '' },
  40 + { type: 'text', name: 'subdomain', placeholder: '' }
38 41 ]
39 42 end
40 43  
41 44 def execute(push)
42   - url = "https://atlas.assembla.com/spaces/ouposp/github_tool?secret_key=#{token}"
  45 + url = "https://atlas.assembla.com/spaces/#{subdomain}/github_tool?secret_key=#{token}"
43 46 AssemblaService.post(url, body: { payload: push }.to_json, headers: { 'Content-Type' => 'application/json' })
44 47 end
45 48 end
... ...
app/models/project_team.rb
... ... @@ -22,22 +22,22 @@ class ProjectTeam
22 22 end
23 23  
24 24 def find(user_id)
25   - user = project.users.find_by_id(user_id)
  25 + user = project.users.find_by(id: user_id)
26 26  
27 27 if group
28   - user ||= group.users.find_by_id(user_id)
  28 + user ||= group.users.find_by(id: user_id)
29 29 end
30 30  
31 31 user
32 32 end
33 33  
34 34 def find_tm(user_id)
35   - tm = project.users_projects.find_by_user_id(user_id)
  35 + tm = project.users_projects.find_by(user_id: user_id)
36 36  
37 37 # If user is not in project members
38 38 # we should check for group membership
39 39 if group && !tm
40   - tm = group.users_groups.find_by_user_id(user_id)
  40 + tm = group.users_groups.find_by(user_id: user_id)
41 41 end
42 42  
43 43 tm
... ...
app/models/user.rb
... ... @@ -239,7 +239,7 @@ class User &lt; ActiveRecord::Base
239 239  
240 240 def namespace_uniq
241 241 namespace_name = self.username
242   - if Namespace.find_by_path(namespace_name)
  242 + if Namespace.find_by(path: namespace_name)
243 243 self.errors.add :username, "already exist"
244 244 end
245 245 end
... ... @@ -383,7 +383,7 @@ class User &lt; ActiveRecord::Base
383 383 end
384 384  
385 385 def created_by
386   - User.find_by_id(created_by_id) if created_by_id
  386 + User.find_by(id: created_by_id) if created_by_id
387 387 end
388 388  
389 389 def sanitize_attrs
... ...
app/services/notification_service.rb
... ... @@ -195,10 +195,10 @@ class NotificationService
195 195 users.reject do |user|
196 196 next user.notification.disabled? unless project
197 197  
198   - tm = project.users_projects.find_by_user_id(user.id)
  198 + tm = project.users_projects.find_by(user_id: user.id)
199 199  
200 200 if !tm && project.group
201   - tm = project.group.users_groups.find_by_user_id(user.id)
  201 + tm = project.group.users_groups.find_by(user_id: user.id)
202 202 end
203 203  
204 204 # reject users who globally disabled notification and has no membership
... ...
app/services/projects/create_service.rb
... ... @@ -73,7 +73,7 @@ module Projects
73 73 end
74 74  
75 75 def allowed_namespace?(user, namespace_id)
76   - namespace = Namespace.find_by_id(namespace_id)
  76 + namespace = Namespace.find_by(id: namespace_id)
77 77 current_user.can?(:manage_namespace, namespace)
78 78 end
79 79 end
... ...
app/services/search/global_service.rb
... ... @@ -15,7 +15,7 @@ module Search
15 15 authorized_projects_ids += current_user.authorized_projects.pluck(:id) if current_user
16 16 authorized_projects_ids += Project.public_or_internal_only(current_user).pluck(:id)
17 17  
18   - group = Group.find_by_id(params[:group_id]) if params[:group_id].present?
  18 + group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
19 19 projects = Project.where(id: authorized_projects_ids)
20 20 projects = projects.where(namespace_id: group.id) if group
21 21 projects = projects.search(query)
... ...
app/views/help/_layout.html.haml
1 1 .row
2   - .col-md-3{:"data-spy" => 'affix'}
  2 + .col-md-3
3 3 %h3.page-title Help
4 4 %ul.nav.nav-pills.nav-stacked
5 5 - links = {:"Workflow" => help_workflow_path, :"SSH Keys" => help_ssh_path, :"GitLab Markdown" => help_markdown_path, :"Permissions" => help_permissions_path, :"API" => help_api_path, :"Web Hooks" => help_web_hooks_path, :"Rake Tasks" => help_raketasks_path, :"System Hooks" => help_system_hooks_path, :"Public Access" => help_public_access_path, :"Security" => help_security_path}
... ... @@ -7,5 +7,5 @@
7 7 %li{class: current_page?(path) ? 'active' : nil}
8 8 = link_to title, path
9 9  
10   - .col-md-9.pull-right
  10 + .col-md-9
11 11 = yield
... ...
app/views/help/ssh.html.haml
... ... @@ -5,13 +5,24 @@
5 5 SSH key allows you to establish a secure connection between your computer and GitLab
6 6  
7 7 %p.slead
8   - To generate a new SSH key just open your terminal and use code below. Press enter to accept the defaults when generating the key.
  8 + Before generating an SSH key, check if your system already has one by running cat ~/.ssh/id_rsa.pub
  9 + If your see a long string starting with 'ssh-rsa' or 'ssh-dsa', you can skip the ssh-keygen step.
  10 +
  11 + %p.slead
  12 + To generate a new SSH key just open your terminal and use code below. The ssh-keygen command prompts you for a location and filename to store the key pair and for a password.
  13 + When prompted for the location and filename you can press enter to use the default.
  14 + It is a best practice to use a password for an SSH key but it is not required and you can skip creating a password by pressing enter.
  15 + Note that the password you choose here can't be altered or retrieved.
9 16  
10 17 %pre.dark
11 18 ssh-keygen -t rsa -C "#{current_user.email}"
12 19  
13 20 %p.slead
14   - Next just use code below to dump your public key and add to GitLab SSH Keys
  21 + Use code below to show your public key.
15 22  
16 23 %pre.dark
17 24 cat ~/.ssh/id_rsa.pub
  25 +
  26 + %p.slead
  27 + Copy-paste the key to the 'My SSH Keys' section under the 'SSH' tab in your user profile.
  28 + Please copy the complete key starting with 'ssh-' and ending with your username and host.
... ...
app/views/projects/commits/_inline_commit.html.haml
... ... @@ -2,5 +2,7 @@
2 2 .commit-row-title
3 3 = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id"
4 4 &nbsp;
5   - = link_to_gfm truncate(commit.title, length: 40), project_commit_path(project, commit.id), class: "commit-row-message"
6   - #{time_ago_with_tooltip(commit.committed_date)} &nbsp;
  5 + %span.str-truncated
  6 + = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message"
  7 + .pull-right
  8 + #{time_ago_with_tooltip(commit.committed_date)}
... ...
app/views/projects/merge_requests/show/_commits.html.haml
... ... @@ -12,9 +12,16 @@
12 12 8 of #{@commits.count} commits displayed.
13 13 %strong
14 14 %a.show-all-commits Click here to show all
15   - %ul.all-commits.hide.well-list
16   - - @commits.each do |commit|
17   - = render "projects/commits/commit", commit: commit, project: @merge_request.source_project
  15 + - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
  16 + %ul.all-commits.hide.well-list
  17 + - @commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE).each do |commit|
  18 + = render "projects/commits/inline_commit", commit: commit, project: @merge_request.source_project
  19 + %li
  20 + other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden top prevent performance issues.
  21 + - else
  22 + %ul.all-commits.hide.well-list
  23 + - @commits.each do |commit|
  24 + = render "projects/commits/inline_commit", commit: commit, project: @merge_request.source_project
18 25  
19 26 - else
20 27 %ul.well-list
... ...
app/views/projects/merge_requests/show/_diffs.html.haml
1   -- if @merge_request.valid_diffs?
  1 +- if @merge_request_diff.collected?
2 2 = render "projects/commits/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
3   -- elsif @merge_request.broken_diffs?
  3 +- elsif @merge_request_diff.empty?
  4 + %h4.nothing_here_message Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
  5 +- else
4 6 %h4.nothing_here_message
5 7 Can't load diff.
6 8 You can
7 9 = link_to "download it", project_merge_request_path(@merge_request.source_project, @merge_request), format: :diff, class: "vlink"
8 10 instead.
9   -- else
10   - %h4.nothing_here_message Nothing to merge
... ...
app/views/projects/merge_requests/update_branches.js.haml
1 1 :plain
2 2 $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}");
3   - $(".target_branch").trigger("select2:updated");
  3 +
  4 + $('select.target_branch').select2({
  5 + width: 'resolve',
  6 + dropdownAutoWidth: true
  7 + });
  8 +
4 9 $(".mr_target_commit").html("");
5   - $(".target_branch").trigger("change");
... ...
config.ru
1 1 # This file is used by Rack-based servers to start the application.
2 2  
3   -unless defined?(PhusionPassenger)
  3 +if defined?(Unicorn)
4 4 require 'unicorn'
5 5 # Unicorn self-process killer
6 6 require 'unicorn/worker_killer'
... ...
db/fixtures/development/04_project.rb
... ... @@ -19,7 +19,7 @@ project_urls = [
19 19 project_urls.each_with_index do |url, i|
20 20 group_path, project_path = url.split('/')[-2..-1]
21 21  
22   - group = Group.find_by_path(group_path)
  22 + group = Group.find_by(path: group_path)
23 23  
24 24 unless group
25 25 group = Group.new(
... ... @@ -40,7 +40,7 @@ project_urls.each_with_index do |url, i|
40 40 description: Faker::Lorem.sentence
41 41 }
42 42  
43   - project = Projects::CreateContext.new(User.first, params).execute
  43 + project = Projects::CreateService.new(User.first, params).execute
44 44  
45 45 if project.valid?
46 46 print '.'
... ...
db/migrate/20130506095501_remove_project_id_from_key.rb
... ... @@ -4,7 +4,7 @@ class RemoveProjectIdFromKey &lt; ActiveRecord::Migration
4 4 Key.where('project_id IS NOT NULL').update_all(type: 'DeployKey')
5 5  
6 6 DeployKey.all.each do |key|
7   - project = Project.find_by_id(key.project_id)
  7 + project = Project.find_by(id: key.project_id)
8 8 if project
9 9 project.deploy_keys << key
10 10 print '.'
... ...
db/migrate/20140122112253_create_merge_request_diffs.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class CreateMergeRequestDiffs < ActiveRecord::Migration
  2 + def change
  3 + create_table :merge_request_diffs do |t|
  4 + t.string :state, null: false, default: 'collected'
  5 + t.text :st_commits, null: true, limit: 2147483647
  6 + t.text :st_diffs, null: true, limit: 2147483647
  7 + t.integer :merge_request_id, null: false
  8 +
  9 + t.timestamps
  10 + end
  11 + end
  12 +end
... ...
db/migrate/20140122114406_migrate_mr_diffs.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class MigrateMrDiffs < ActiveRecord::Migration
  2 + def self.up
  3 + execute "INSERT INTO merge_request_diffs ( merge_request_id ) SELECT id FROM merge_requests"
  4 + execute "UPDATE merge_requests mr, merge_request_diffs md SET md.st_commits = mr.st_commits WHERE md.merge_request_id = mr.id"
  5 + execute "UPDATE merge_requests mr, merge_request_diffs md SET md.st_diffs = mr.st_diffs WHERE md.merge_request_id = mr.id"
  6 + end
  7 +
  8 + def self.down
  9 + MergeRequestDiff.delete_all
  10 + end
  11 +end
... ...
db/migrate/20140122122549_remove_m_rdiff_fields.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class RemoveMRdiffFields < ActiveRecord::Migration
  2 + def up
  3 + remove_column :merge_requests, :st_commits
  4 + remove_column :merge_requests, :st_diffs
  5 + end
  6 +
  7 + def down
  8 + add_column :merge_requests, :st_commits, :text, null: true, limit: 2147483647
  9 + add_column :merge_requests, :st_diffs, :text, null: true, limit: 2147483647
  10 + execute "UPDATE merge_requests mr, merge_request_diffs md SET mr.st_commits = md.st_commits WHERE md.merge_request_id = mr.id"
  11 + execute "UPDATE merge_requests mr, merge_request_diffs md SET mr.st_diffs = md.st_diffs WHERE md.merge_request_id = mr.id"
  12 + end
  13 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended that you check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(version: 20140116231608) do
  14 +ActiveRecord::Schema.define(version: 20140122122549) do
15 15  
16 16 create_table "broadcast_messages", force: true do |t|
17 17 t.text "message", null: false
... ... @@ -66,8 +66,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
66 66 t.integer "assignee_id"
67 67 t.integer "author_id"
68 68 t.integer "project_id"
69   - t.datetime "created_at", null: false
70   - t.datetime "updated_at", null: false
  69 + t.datetime "created_at"
  70 + t.datetime "updated_at"
71 71 t.integer "position", default: 0
72 72 t.string "branch_name"
73 73 t.text "description"
... ... @@ -85,8 +85,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
85 85  
86 86 create_table "keys", force: true do |t|
87 87 t.integer "user_id"
88   - t.datetime "created_at", null: false
89   - t.datetime "updated_at", null: false
  88 + t.datetime "created_at"
  89 + t.datetime "updated_at"
90 90 t.text "key"
91 91 t.string "title"
92 92 t.string "type"
... ... @@ -95,21 +95,28 @@ ActiveRecord::Schema.define(version: 20140116231608) do
95 95  
96 96 add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree
97 97  
  98 + create_table "merge_request_diffs", force: true do |t|
  99 + t.string "state", default: "collected", null: false
  100 + t.text "st_commits", limit: 2147483647
  101 + t.text "st_diffs", limit: 2147483647
  102 + t.integer "merge_request_id", null: false
  103 + t.datetime "created_at"
  104 + t.datetime "updated_at"
  105 + end
  106 +
98 107 create_table "merge_requests", force: true do |t|
99   - t.string "target_branch", null: false
100   - t.string "source_branch", null: false
101   - t.integer "source_project_id", null: false
  108 + t.string "target_branch", null: false
  109 + t.string "source_branch", null: false
  110 + t.integer "source_project_id", null: false
102 111 t.integer "author_id"
103 112 t.integer "assignee_id"
104 113 t.string "title"
105   - t.datetime "created_at", null: false
106   - t.datetime "updated_at", null: false
107   - t.text "st_commits", limit: 2147483647
108   - t.text "st_diffs", limit: 2147483647
  114 + t.datetime "created_at"
  115 + t.datetime "updated_at"
109 116 t.integer "milestone_id"
110 117 t.string "state"
111 118 t.string "merge_status"
112   - t.integer "target_project_id", null: false
  119 + t.integer "target_project_id", null: false
113 120 t.integer "iid"
114 121 t.text "description"
115 122 end
... ... @@ -156,8 +163,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
156 163 t.text "note"
157 164 t.string "noteable_type"
158 165 t.integer "author_id"
159   - t.datetime "created_at", null: false
160   - t.datetime "updated_at", null: false
  166 + t.datetime "created_at"
  167 + t.datetime "updated_at"
161 168 t.integer "project_id"
162 169 t.string "attachment"
163 170 t.string "line_code"
... ... @@ -179,8 +186,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
179 186 t.string "name"
180 187 t.string "path"
181 188 t.text "description"
182   - t.datetime "created_at", null: false
183   - t.datetime "updated_at", null: false
  189 + t.datetime "created_at"
  190 + t.datetime "updated_at"
184 191 t.integer "creator_id"
185 192 t.boolean "issues_enabled", default: true, null: false
186 193 t.boolean "wall_enabled", default: true, null: false
... ... @@ -231,8 +238,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
231 238 t.text "content", limit: 2147483647
232 239 t.integer "author_id", null: false
233 240 t.integer "project_id"
234   - t.datetime "created_at", null: false
235   - t.datetime "updated_at", null: false
  241 + t.datetime "created_at"
  242 + t.datetime "updated_at"
236 243 t.string "file_name"
237 244 t.datetime "expires_at"
238 245 t.boolean "private", default: true, null: false
... ... @@ -254,45 +261,42 @@ ActiveRecord::Schema.define(version: 20140116231608) do
254 261 t.datetime "created_at"
255 262 end
256 263  
257   - add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree
258   - add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
259   -
260 264 create_table "tags", force: true do |t|
261 265 t.string "name"
262 266 end
263 267  
264 268 create_table "users", force: true do |t|
265   - t.string "email", default: "", null: false
266   - t.string "encrypted_password", default: "", null: false
  269 + t.string "email", default: "", null: false
  270 + t.string "encrypted_password", limit: 128, default: "", null: false
267 271 t.string "reset_password_token"
268 272 t.datetime "reset_password_sent_at"
269 273 t.datetime "remember_created_at"
270   - t.integer "sign_in_count", default: 0
  274 + t.integer "sign_in_count", default: 0
271 275 t.datetime "current_sign_in_at"
272 276 t.datetime "last_sign_in_at"
273 277 t.string "current_sign_in_ip"
274 278 t.string "last_sign_in_ip"
275   - t.datetime "created_at", null: false
276   - t.datetime "updated_at", null: false
  279 + t.datetime "created_at"
  280 + t.datetime "updated_at"
277 281 t.string "name"
278   - t.boolean "admin", default: false, null: false
279   - t.integer "projects_limit", default: 10
280   - t.string "skype", default: "", null: false
281   - t.string "linkedin", default: "", null: false
282   - t.string "twitter", default: "", null: false
  282 + t.boolean "admin", default: false, null: false
  283 + t.integer "projects_limit", default: 10
  284 + t.string "skype", default: "", null: false
  285 + t.string "linkedin", default: "", null: false
  286 + t.string "twitter", default: "", null: false
283 287 t.string "authentication_token"
284   - t.integer "theme_id", default: 1, null: false
  288 + t.integer "theme_id", default: 1, null: false
285 289 t.string "bio"
286   - t.integer "failed_attempts", default: 0
  290 + t.integer "failed_attempts", default: 0
287 291 t.datetime "locked_at"
288 292 t.string "extern_uid"
289 293 t.string "provider"
290 294 t.string "username"
291   - t.boolean "can_create_group", default: true, null: false
292   - t.boolean "can_create_team", default: true, null: false
  295 + t.boolean "can_create_group", default: true, null: false
  296 + t.boolean "can_create_team", default: true, null: false
293 297 t.string "state"
294   - t.integer "color_scheme_id", default: 1, null: false
295   - t.integer "notification_level", default: 1, null: false
  298 + t.integer "color_scheme_id", default: 1, null: false
  299 + t.integer "notification_level", default: 1, null: false
296 300 t.datetime "password_expires_at"
297 301 t.integer "created_by_id"
298 302 t.string "avatar"
... ... @@ -300,15 +304,14 @@ ActiveRecord::Schema.define(version: 20140116231608) do
300 304 t.datetime "confirmed_at"
301 305 t.datetime "confirmation_sent_at"
302 306 t.string "unconfirmed_email"
303   - t.boolean "hide_no_ssh_key", default: false
304   - t.string "website_url", default: "", null: false
  307 + t.boolean "hide_no_ssh_key", default: false
  308 + t.string "website_url", default: "", null: false
305 309 end
306 310  
307 311 add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
308 312 add_index "users", ["authentication_token"], name: "index_users_on_authentication_token", unique: true, using: :btree
309 313 add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
310 314 add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
311   - add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree
312 315 add_index "users", ["name"], name: "index_users_on_name", using: :btree
313 316 add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
314 317 add_index "users", ["username"], name: "index_users_on_username", using: :btree
... ... @@ -327,8 +330,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
327 330 create_table "users_projects", force: true do |t|
328 331 t.integer "user_id", null: false
329 332 t.integer "project_id", null: false
330   - t.datetime "created_at", null: false
331   - t.datetime "updated_at", null: false
  333 + t.datetime "created_at"
  334 + t.datetime "updated_at"
332 335 t.integer "project_access", default: 0, null: false
333 336 t.integer "notification_level", default: 3, null: false
334 337 end
... ... @@ -340,8 +343,8 @@ ActiveRecord::Schema.define(version: 20140116231608) do
340 343 create_table "web_hooks", force: true do |t|
341 344 t.string "url"
342 345 t.integer "project_id"
343   - t.datetime "created_at", null: false
344   - t.datetime "updated_at", null: false
  346 + t.datetime "created_at"
  347 + t.datetime "updated_at"
345 348 t.string "type", default: "ProjectHook"
346 349 t.integer "service_id"
347 350 t.boolean "push_events", default: true, null: false
... ...
doc/install/installation.md
... ... @@ -10,7 +10,7 @@ If this is unclear check the [GitLab Blog](http://blog.gitlab.org/) for installa
10 10  
11 11 This guide is long because it covers many cases and includes all commands you need, this is [one of the few installation scripts that actually works out of the box](https://twitter.com/robinvdvleuten/status/424163226532986880).
12 12  
13   -This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and operating system requirements.
  13 +This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements.
14 14  
15 15 This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please consult [the installation section in the readme](https://github.com/gitlabhq/gitlabhq#installation).
16 16  
... ... @@ -113,6 +113,8 @@ Then select &#39;Internet Site&#39; and press enter to confirm the hostname.
113 113  
114 114 # 2. Ruby
115 115  
  116 +The use of ruby version managers such as [RVM](http://rvm.io/), [rbenv](https://github.com/sstephenson/rbenv) or [chruby](https://github.com/postmodern/chruby) with GitLab in production frequently leads to hard to diagnose problems. Version managers are not supported and we stronly advise everyone to follow the instructions below to use a system ruby.
  117 +
116 118 Remove the old Ruby 1.8 if present
117 119  
118 120 sudo apt-get remove ruby1.8
... ...
doc/integration/external-issue-tracker.md 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +GitLab has a great issue tracker but you can also use an external issue tracker such as JIRA or Redmine. This is something that you can turn on per GitLab project. If for example you configure JIRA it provides the following functionality:
  2 +
  3 +- the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index;
  4 +- clicking 'New issue' on the project dashboard creates a new JIRA issue;
  5 +- textual references to PROJECT-1234 in comments, commit messages get turned into HTML links to the corresponding JIRA issue.
  6 +
  7 +![jira screenshot](jira-intergration-points.png)
... ...
doc/integration/jira-integration-points.png 0 → 100644

66.3 KB

doc/release/monthly.md
... ... @@ -58,12 +58,13 @@ Check if changed since last release (~22nd of last month depending on when last
58 58  
59 59 After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows:
60 60  
61   -* 17th: feature freeze (branch and stop merging new features)
62   -* 18th: UI freeze (stop cherry-picking changes to the user interface)
63   -* 19th: code freeze (stop cherry-picking non-essential code improvements)
64   -* 20th: release candidate 1 (tag and tweet about x.x.rc1)
65   -* 21st: release candidate 2 (optional, only if rc1 had problems)
66   -* 22nd: release (update VERSION and CHANGELOG, tag, blog and tweet)
  61 +* 17th: feature freeze (stop merging new features in master)
  62 +* 18th: UI freeze (stop merging changes to the user interface)
  63 +* 19th: code freeze (stop merging non-essential code improvements)
  64 +* 20th: release candidate 1 (VERSION x.x.0.pre, tag and tweet about x.x.0.rc1)
  65 +* 21st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems)
  66 +* 22nd: release (VERSION x.x.0, create x-x-stable branch, tag, blog and tweet)
  67 +* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems)
67 68  
68 69 # Write a blog post
69 70  
... ...
doc/update/6.0-to-6.4.md
... ... @@ -1,127 +0,0 @@
1   -# From 6.0 to 6.4
2   -
3   -# In 6.1 we remove a lot of deprecated code.
4   -# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
5   -
6   -### Deprecations
7   -
8   -#### Global issue numbers
9   -
10   -As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects.
11   -
12   -### 0. Backup
13   -
14   -It's useful to make a backup just in case things go south:
15   -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
16   -
17   -```bash
18   -cd /home/git/gitlab
19   -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
20   -```
21   -
22   -### 1. Stop server
23   -
24   - sudo service gitlab stop
25   -
26   -### 2. Get latest code
27   -
28   -```bash
29   -cd /home/git/gitlab
30   -sudo -u git -H git fetch --all
31   -sudo -u git -H git checkout 6-4-stable
32   -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-4-stable-ee
33   -```
34   -
35   -
36   -### 3. Install additional packages
37   -
38   -```bash
39   -# Add support for lograte for better log file handling
40   -sudo apt-get install logrotate
41   -```
42   -
43   -### 4. Update gitlab-shell
44   -
45   -```bash
46   -cd /home/git/gitlab-shell
47   -sudo -u git -H git fetch
48   -sudo -u git -H git checkout v1.8.0 # Addresses multiple critical security vulnerabilities
49   -```
50   -
51   -### 5. Install libs, migrations, etc.
52   -
53   -```bash
54   -cd /home/git/gitlab
55   -
56   -# MySQL
57   -sudo -u git -H bundle install --without development test postgres --deployment
58   -
59   -#PostgreSQL
60   -sudo -u git -H bundle install --without development test mysql --deployment
61   -
62   -
63   -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
64   -sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production
65   -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production
66   -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
67   -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
68   -```
69   -
70   -### 6. Update config files
71   -
72   -TIP: to see what changed in gitlab.yml.example in this release use next command:
73   -
74   -```
75   -git diff 6-0-stable:config/gitlab.yml.example 6-4-stable:config/gitlab.yml.example
76   -```
77   -
78   -* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-4-stable/config/gitlab.yml.example but with your settings.
79   -* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-4-stable/config/unicorn.rb.example but with your settings.
80   -* Copy rack attack middleware config
81   -
82   -```bash
83   -sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
84   -```
85   -
86   -* Set up logrotate
87   -
88   -```bash
89   -sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
90   -```
91   -
92   -### 7. Update Init script
93   -
94   -```bash
95   -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
96   -```
97   -
98   -### 8. Start application
99   -
100   - sudo service gitlab start
101   - sudo service nginx restart
102   -
103   -### 9. Check application status
104   -
105   -Check if GitLab and its environment are configured correctly:
106   -
107   - cd /home/git/gitlab
108   - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
109   -
110   -To make sure you didn't miss anything run a more thorough check with:
111   -
112   - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
113   -
114   -If all items are green, then congratulations upgrade complete!
115   -
116   -## Things went south? Revert to previous version (6.0)
117   -
118   -### 1. Revert the code to the previous version
119   -Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration
120   -(The backup is already migrated to the previous version)
121   -
122   -### 2. Restore from the backup:
123   -
124   -```bash
125   -cd /home/git/gitlab
126   -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
127   -```
doc/update/6.0-to-6.5.md 0 → 100644
... ... @@ -0,0 +1,127 @@
  1 +# From 6.0 to 6.5
  2 +
  3 +# In 6.1 we remove a lot of deprecated code.
  4 +# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
  5 +
  6 +### Deprecations
  7 +
  8 +#### Global issue numbers
  9 +
  10 +As of 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their url. If you use an old issue number url and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects.
  11 +
  12 +### 0. Backup
  13 +
  14 +It's useful to make a backup just in case things go south:
  15 +(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
  16 +
  17 +```bash
  18 +cd /home/git/gitlab
  19 +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
  20 +```
  21 +
  22 +### 1. Stop server
  23 +
  24 + sudo service gitlab stop
  25 +
  26 +### 2. Get latest code
  27 +
  28 +```bash
  29 +cd /home/git/gitlab
  30 +sudo -u git -H git fetch --all
  31 +sudo -u git -H git checkout 6-5-stable
  32 +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-5-stable-ee
  33 +```
  34 +
  35 +
  36 +### 3. Install additional packages
  37 +
  38 +```bash
  39 +# Add support for lograte for better log file handling
  40 +sudo apt-get install logrotate
  41 +```
  42 +
  43 +### 4. Update gitlab-shell
  44 +
  45 +```bash
  46 +cd /home/git/gitlab-shell
  47 +sudo -u git -H git fetch
  48 +sudo -u git -H git checkout v1.8.0 # Addresses multiple critical security vulnerabilities
  49 +```
  50 +
  51 +### 5. Install libs, migrations, etc.
  52 +
  53 +```bash
  54 +cd /home/git/gitlab
  55 +
  56 +# MySQL
  57 +sudo -u git -H bundle install --without development test postgres --deployment
  58 +
  59 +#PostgreSQL
  60 +sudo -u git -H bundle install --without development test mysql --deployment
  61 +
  62 +
  63 +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
  64 +sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production
  65 +sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production
  66 +sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
  67 +sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
  68 +```
  69 +
  70 +### 6. Update config files
  71 +
  72 +TIP: to see what changed in gitlab.yml.example in this release use next command:
  73 +
  74 +```
  75 +git diff 6-0-stable:config/gitlab.yml.example 6-5-stable:config/gitlab.yml.example
  76 +```
  77 +
  78 +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/gitlab.yml.example but with your settings.
  79 +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/unicorn.rb.example but with your settings.
  80 +* Copy rack attack middleware config
  81 +
  82 +```bash
  83 +sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
  84 +```
  85 +
  86 +* Set up logrotate
  87 +
  88 +```bash
  89 +sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
  90 +```
  91 +
  92 +### 7. Update Init script
  93 +
  94 +```bash
  95 +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
  96 +```
  97 +
  98 +### 8. Start application
  99 +
  100 + sudo service gitlab start
  101 + sudo service nginx restart
  102 +
  103 +### 9. Check application status
  104 +
  105 +Check if GitLab and its environment are configured correctly:
  106 +
  107 + cd /home/git/gitlab
  108 + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
  109 +
  110 +To make sure you didn't miss anything run a more thorough check with:
  111 +
  112 + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
  113 +
  114 +If all items are green, then congratulations upgrade complete!
  115 +
  116 +## Things went south? Revert to previous version (6.0)
  117 +
  118 +### 1. Revert the code to the previous version
  119 +Follow the [`upgrade guide from 5.4 to 6.0`](5.4-to-6.0.md), except for the database migration
  120 +(The backup is already migrated to the previous version)
  121 +
  122 +### 2. Restore from the backup:
  123 +
  124 +```bash
  125 +cd /home/git/gitlab
  126 +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
  127 +```
... ...
features/project/merge_requests.feature
... ... @@ -55,18 +55,18 @@ Feature: Project Merge Requests
55 55 Given project "Shop" have "Bug NS-05" open merge request with diffs inside
56 56 And I visit merge request page "Bug NS-05"
57 57 And I click on the first commit in the merge request
58   - And I leave a comment like "Line is wrong" on line 185 of the first file
  58 + And I leave a comment like "Line is wrong" on line 185 of the first file in commit
59 59 And I switch to the merge request's comments tab
60   - Then I should see a discussion has started on commit bcf03b5de6c:L185
  60 + Then I should see a discussion has started on commit b1e6a9dbf1:L185
61 61  
62 62 @javascript
63 63 Scenario: I comment on a commit in merge request
64 64 Given project "Shop" have "Bug NS-05" open merge request with diffs inside
65 65 And I visit merge request page "Bug NS-05"
66 66 And I click on the first commit in the merge request
67   - And I leave a comment on the diff page
  67 + And I leave a comment on the diff page in commit
68 68 And I switch to the merge request's comments tab
69   - Then I should see a discussion has started on commit bcf03b5de6c
  69 + Then I should see a discussion has started on commit b1e6a9dbf1
70 70  
71 71 @javascript
72 72 Scenario: I accept merge request with custom commit message
... ...
features/steps/admin/admin_groups.rb
... ... @@ -40,7 +40,7 @@ class AdminGroups &lt; Spinach::FeatureSteps
40 40 end
41 41  
42 42 When 'I select user "John" from user list as "Reporter"' do
43   - user = User.find_by_name("John")
  43 + user = User.find_by(name: "John")
44 44 select2(user.id, from: "#user_ids", multiple: true)
45 45 within "#new_team_member" do
46 46 select "Reporter", from: "group_access"
... ...
features/steps/dashboard/dashboard.rb
... ... @@ -43,7 +43,7 @@ class Dashboard &lt; Spinach::FeatureSteps
43 43 end
44 44  
45 45 And 'user with name "John Doe" left project "Shop"' do
46   - user = User.find_by_name "John Doe"
  46 + user = User.find_by(name: "John Doe")
47 47 Event.create(
48 48 project: project,
49 49 author_id: user.id,
... ... @@ -85,6 +85,6 @@ class Dashboard &lt; Spinach::FeatureSteps
85 85 end
86 86  
87 87 def project
88   - @project ||= Project.find_by_name "Shop"
  88 + @project ||= Project.find_by(name: "Shop")
89 89 end
90 90 end
... ...
features/steps/dashboard/dashboard_issues.rb
... ... @@ -66,7 +66,7 @@ class DashboardIssues &lt; Spinach::FeatureSteps
66 66  
67 67 def project
68 68 @project ||= begin
69   - project =create :project_with_code
  69 + project =create :project
70 70 project.team << [current_user, :master]
71 71 project
72 72 end
... ...
features/steps/dashboard/dashboard_merge_requests.rb
... ... @@ -66,7 +66,7 @@ class DashboardMergeRequests &lt; Spinach::FeatureSteps
66 66  
67 67 def project
68 68 @project ||= begin
69   - project =create :project_with_code
  69 + project =create :project
70 70 project.team << [current_user, :master]
71 71 project
72 72 end
... ...
features/steps/dashboard/dashboard_with_archived_projects.rb
... ... @@ -4,7 +4,7 @@ class DashboardWithArchivedProjects &lt; Spinach::FeatureSteps
4 4 include SharedProject
5 5  
6 6 When 'project "Forum" is archived' do
7   - project = Project.find_by_name "Forum"
  7 + project = Project.find_by(name: "Forum")
8 8 project.update_attribute(:archived, true)
9 9 end
10 10  
... ...
features/steps/group/group.rb
... ... @@ -39,7 +39,7 @@ class Groups &lt; Spinach::FeatureSteps
39 39 end
40 40  
41 41 And 'I select user "John" from list with role "Reporter"' do
42   - user = User.find_by_name("John")
  42 + user = User.find_by(name: "John")
43 43 within ".users-group-form" do
44 44 select2(user.id, from: "#user_ids", multiple: true)
45 45 select "Reporter", from: "group_access"
... ...
features/steps/profile/profile_ssh_keys.rb
... ... @@ -18,7 +18,7 @@ class ProfileSshKeys &lt; Spinach::FeatureSteps
18 18 end
19 19  
20 20 Then 'I should see new ssh key "Laptop"' do
21   - key = Key.find_by_title("Laptop")
  21 + key = Key.find_by(title: "Laptop")
22 22 page.should have_content(key.title)
23 23 page.should have_content(key.key)
24 24 current_path.should == profile_key_path(key)
... ...
features/steps/project/deploy_keys.rb
... ... @@ -34,7 +34,7 @@ class Spinach::Features::ProjectDeployKeys &lt; Spinach::FeatureSteps
34 34 end
35 35  
36 36 step 'other project has deploy key' do
37   - @second_project = create :project, namespace: current_user.namespace
  37 + @second_project = create :project, namespace: create(:group)
38 38 @second_project.team << [current_user, :master]
39 39 create(:deploy_keys_project, project: @second_project)
40 40 end
... ...
features/steps/project/project_archived.rb
... ... @@ -4,17 +4,17 @@ class ProjectArchived &lt; Spinach::FeatureSteps
4 4 include SharedPaths
5 5  
6 6 When 'project "Forum" is archived' do
7   - project = Project.find_by_name "Forum"
  7 + project = Project.find_by(name: "Forum")
8 8 project.update_attribute(:archived, true)
9 9 end
10 10  
11 11 When 'project "Shop" is archived' do
12   - project = Project.find_by_name "Shop"
  12 + project = Project.find_by(name: "Shop")
13 13 project.update_attribute(:archived, true)
14 14 end
15 15  
16 16 When 'I visit project "Forum" page' do
17   - project = Project.find_by_name "Forum"
  17 + project = Project.find_by(name: "Forum")
18 18 visit project_path(project)
19 19 end
20 20  
... ...
features/steps/project/project_browse_branches.rb
... ... @@ -29,7 +29,7 @@ class ProjectBrowseBranches &lt; Spinach::FeatureSteps
29 29 end
30 30  
31 31 And 'project "Shop" has protected branches' do
32   - project = Project.find_by_name("Shop")
  32 + project = Project.find_by(name: "Shop")
33 33 project.protected_branches.create(name: "stable")
34 34 end
35 35 end
... ...
features/steps/project/project_fork.rb
... ... @@ -11,22 +11,22 @@ class ForkProject &lt; Spinach::FeatureSteps
11 11 end
12 12  
13 13 step 'I am a member of project "Shop"' do
14   - @project = Project.find_by_name "Shop"
15   - @project ||= create(:project_with_code, name: "Shop", group: create(:group))
  14 + @project = Project.find_by(name: "Shop")
  15 + @project ||= create(:project, name: "Shop", group: create(:group))
16 16 @project.team << [@user, :reporter]
17 17 end
18 18  
19 19 step 'I should see the forked project page' do
20 20 page.should have_content "Project was successfully forked."
21 21 current_path.should include current_user.namespace.path
22   - @forked_project = Project.find_by_namespace_id(current_user.namespace.path)
  22 + @forked_project = Project.find_by(namespace_id: current_user.namespace.path)
23 23 end
24 24  
25 25 step 'I already have a project named "Shop" in my namespace' do
26 26 current_user.namespace ||= create(:namespace)
27 27 current_user.namespace.should_not be_nil
28 28 current_user.namespace.path.should_not be_nil
29   - @my_project = create(:project_with_code, name: "Shop", namespace: current_user.namespace)
  29 + @my_project = create(:project, name: "Shop", namespace: current_user.namespace)
30 30 end
31 31  
32 32 step 'I should see a "Name has already been taken" warning' do
... ...
features/steps/project/project_forked_merge_requests.rb
... ... @@ -6,16 +6,16 @@ class ProjectForkedMergeRequests &lt; Spinach::FeatureSteps
6 6 include Select2Helper
7 7  
8 8 step 'I am a member of project "Shop"' do
9   - @project = Project.find_by_name "Shop"
10   - @project ||= create(:project_with_code, name: "Shop")
  9 + @project = Project.find_by(name: "Shop")
  10 + @project ||= create(:project, name: "Shop")
11 11 @project.team << [@user, :reporter]
12 12 end
13 13  
14 14 step 'I have a project forked off of "Shop" called "Forked Shop"' do
15 15 @forking_user = @user
16 16 forked_project_link = build(:forked_project_link)
17   - @forked_project = Project.find_by_name "Forked Shop"
18   - @forked_project ||= create(:source_project_with_code, name: "Forked Shop", forked_project_link: forked_project_link, creator_id: @forking_user.id , namespace: @forking_user.namespace)
  17 + @forked_project = Project.find_by(name: "Forked Shop")
  18 + @forked_project ||= create(:project, name: "Forked Shop", forked_project_link: forked_project_link, creator_id: @forking_user.id , namespace: @forking_user.namespace)
19 19  
20 20 forked_project_link.forked_from_project = @project
21 21 forked_project_link.forked_to_project = @forked_project
... ... @@ -114,7 +114,7 @@ class ProjectForkedMergeRequests &lt; Spinach::FeatureSteps
114 114 end
115 115  
116 116 step 'project "Forked Shop" has push event' do
117   - @forked_project = Project.find_by_name("Forked Shop")
  117 + @forked_project = Project.find_by(name: "Forked Shop")
118 118  
119 119 data = {
120 120 before: "0000000000000000000000000000000000000000",
... ... @@ -172,7 +172,7 @@ class ProjectForkedMergeRequests &lt; Spinach::FeatureSteps
172 172 end
173 173  
174 174 def project
175   - @project ||= Project.find_by_name!("Shop")
  175 + @project ||= Project.find_by!(name: "Shop")
176 176 end
177 177  
178 178 # Verify a link is generated against the correct project
... ...
features/steps/project/project_graph.rb
... ... @@ -7,7 +7,7 @@ class ProjectGraph &lt; Spinach::FeatureSteps
7 7 end
8 8  
9 9 When 'I visit project "Shop" graph page' do
10   - project = Project.find_by_name("Shop")
  10 + project = Project.find_by(name: "Shop")
11 11 visit project_graph_path(project, "master")
12 12 end
13 13 end
... ...
features/steps/project/project_issue_tracker.rb
... ... @@ -4,8 +4,8 @@ class ProjectIssueTracker &lt; Spinach::FeatureSteps
4 4 include SharedPaths
5 5  
6 6 step 'project "Shop" has issues enabled' do
7   - @project = Project.find_by_name "Shop"
8   - @project ||= create(:project_with_code, name: "Shop", namespace: @user.namespace)
  7 + @project = Project.find_by(name: "Shop")
  8 + @project ||= create(:project, name: "Shop", namespace: @user.namespace)
9 9 @project.issues_enabled = true
10 10 end
11 11  
... ...
features/steps/project/project_issues.rb
... ... @@ -54,7 +54,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps
54 54 end
55 55  
56 56 Then 'I should see issue "500 error on profile"' do
57   - issue = Issue.find_by_title("500 error on profile")
  57 + issue = Issue.find_by(title: "500 error on profile")
58 58 page.should have_content issue.title
59 59 page.should have_content issue.author_name
60 60 page.should have_content issue.project.name
... ... @@ -81,14 +81,14 @@ class ProjectIssues &lt; Spinach::FeatureSteps
81 81 end
82 82  
83 83 Given 'project "Shop" has milestone "v2.2"' do
84   - project = Project.find_by_name("Shop")
  84 + project = Project.find_by(name: "Shop")
85 85 milestone = create(:milestone, title: "v2.2", project: project)
86 86  
87 87 3.times { create(:issue, project: project, milestone: milestone) }
88 88 end
89 89  
90 90 And 'project "Shop" has milestone "v3.0"' do
91   - project = Project.find_by_name("Shop")
  91 + project = Project.find_by(name: "Shop")
92 92 milestone = create(:milestone, title: "v3.0", project: project)
93 93  
94 94 3.times { create(:issue, project: project, milestone: milestone) }
... ... @@ -104,20 +104,20 @@ class ProjectIssues &lt; Spinach::FeatureSteps
104 104 end
105 105  
106 106 When 'I select first assignee from "Shop" project' do
107   - project = Project.find_by_name "Shop"
  107 + project = Project.find_by(name: "Shop")
108 108 first_assignee = project.users.first
109 109 select first_assignee.name, from: "assignee_id"
110 110 end
111 111  
112 112 Then 'I should see first assignee from "Shop" as selected assignee' do
113 113 issues_assignee_selector = "#issue_assignee_id_chzn > a"
114   - project = Project.find_by_name "Shop"
  114 + project = Project.find_by(name: "Shop")
115 115 assignee_name = project.users.first.name
116 116 page.find(issues_assignee_selector).should have_content(assignee_name)
117 117 end
118 118  
119 119 And 'project "Shop" have "Release 0.4" open issue' do
120   - project = Project.find_by_name("Shop")
  120 + project = Project.find_by(name: "Shop")
121 121 create(:issue,
122 122 title: "Release 0.4",
123 123 project: project,
... ... @@ -125,7 +125,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps
125 125 end
126 126  
127 127 And 'project "Shop" have "Tweet control" open issue' do
128   - project = Project.find_by_name("Shop")
  128 + project = Project.find_by(name: "Shop")
129 129 create(:issue,
130 130 title: "Tweet control",
131 131 project: project,
... ... @@ -133,7 +133,7 @@ class ProjectIssues &lt; Spinach::FeatureSteps
133 133 end
134 134  
135 135 And 'project "Shop" have "Release 0.3" closed issue' do
136   - project = Project.find_by_name("Shop")
  136 + project = Project.find_by(name: "Shop")
137 137 create(:closed_issue,
138 138 title: "Release 0.3",
139 139 project: project,
... ...
features/steps/project/project_labels.rb
... ... @@ -16,7 +16,7 @@ class ProjectLabels &lt; Spinach::FeatureSteps
16 16 end
17 17  
18 18 And 'project "Shop" have issues tags: "bug", "feature"' do
19   - project = Project.find_by_name("Shop")
  19 + project = Project.find_by(name: "Shop")
20 20 ['bug', 'feature'].each do |label|
21 21 create(:issue, project: project, label_list: label)
22 22 end
... ...
features/steps/project/project_markdown_render.rb
... ... @@ -3,8 +3,8 @@ class Spinach::Features::ProjectMarkdownRender &lt; Spinach::FeatureSteps
3 3 include SharedPaths
4 4  
5 5 And 'I own project "Delta"' do
6   - @project = Project.find_by_name "Delta"
7   - @project ||= create(:project_with_code, name: "Delta", namespace: @user.namespace)
  6 + @project = Project.find_by(name: "Delta")
  7 + @project ||= create(:project, name: "Delta", namespace: @user.namespace)
8 8 @project.team << [@user, :master]
9 9 end
10 10  
... ...
features/steps/project/project_merge_requests.rb
... ... @@ -27,7 +27,7 @@ class ProjectMergeRequests &lt; Spinach::FeatureSteps
27 27 end
28 28  
29 29 step 'I should see closed merge request "Bug NS-04"' do
30   - merge_request = MergeRequest.find_by_title!("Bug NS-04")
  30 + merge_request = MergeRequest.find_by!(title: "Bug NS-04")
31 31 merge_request.closed?.should be_true
32 32 page.should have_content "Closed by"
33 33 end
... ... @@ -81,6 +81,8 @@ class ProjectMergeRequests &lt; Spinach::FeatureSteps
81 81 title: "Bug NS-04",
82 82 source_project: project,
83 83 target_project: project,
  84 + source_branch: 'stable',
  85 + target_branch: 'master',
84 86 author: project.users.first)
85 87 end
86 88  
... ... @@ -109,33 +111,29 @@ class ProjectMergeRequests &lt; Spinach::FeatureSteps
109 111 end
110 112  
111 113 step 'I click on the first commit in the merge request' do
112   - click_link merge_request.commits.first.short_id(8)
  114 + within '.first-commits' do
  115 + click_link merge_request.commits.first.short_id(8)
  116 + end
113 117 end
114 118  
115 119 step 'I leave a comment on the diff page' do
116 120 init_diff_note
  121 + leave_comment "One comment to rule them all"
  122 + end
117 123  
118   - within('.js-discussion-note-form') do
119   - fill_in "note_note", with: "One comment to rule them all"
120   - click_button "Add Comment"
121   - end
122   -
123   - within ".note-text" do
124   - page.should have_content "One comment to rule them all"
125   - end
  124 + step 'I leave a comment on the diff page in commit' do
  125 + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
  126 + leave_comment "One comment to rule them all"
126 127 end
127 128  
128 129 step 'I leave a comment like "Line is wrong" on line 185 of the first file' do
129 130 init_diff_note
  131 + leave_comment "Line is wrong"
  132 + end
130 133  
131   - within(".js-discussion-note-form") do
132   - fill_in "note_note", with: "Line is wrong"
133   - click_button "Add Comment"
134   - end
135   -
136   - within ".note-text" do
137   - page.should have_content "Line is wrong"
138   - end
  134 + step 'I leave a comment like "Line is wrong" on line 185 of the first file in commit' do
  135 + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
  136 + leave_comment "Line is wrong"
139 137 end
140 138  
141 139 step 'I should see a discussion has started on line 185' do
... ... @@ -144,14 +142,14 @@ class ProjectMergeRequests &lt; Spinach::FeatureSteps
144 142 page.should have_content "Line is wrong"
145 143 end
146 144  
147   - step 'I should see a discussion has started on commit bcf03b5de6c:L185' do
  145 + step 'I should see a discussion has started on commit b1e6a9dbf1:L185' do
148 146 page.should have_content "#{current_user.name} started a discussion on commit"
149 147 page.should have_content "app/assets/stylesheets/tree.scss:L185"
150 148 page.should have_content "Line is wrong"
151 149 end
152 150  
153   - step 'I should see a discussion has started on commit bcf03b5de6c' do
154   - page.should have_content "#{current_user.name} started a discussion on commit bcf03b5de6c"
  151 + step 'I should see a discussion has started on commit b1e6a9dbf1' do
  152 + page.should have_content "#{current_user.name} started a discussion on commit"
155 153 page.should have_content "One comment to rule them all"
156 154 page.should have_content "app/assets/stylesheets/tree.scss:L185"
157 155 end
... ... @@ -180,14 +178,25 @@ class ProjectMergeRequests &lt; Spinach::FeatureSteps
180 178 end
181 179  
182 180 def project
183   - @project ||= Project.find_by_name!("Shop")
  181 + @project ||= Project.find_by!(name: "Shop")
184 182 end
185 183  
186 184 def merge_request
187   - @merge_request ||= MergeRequest.find_by_title!("Bug NS-05")
  185 + @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05")
188 186 end
189 187  
190 188 def init_diff_note
191   - find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click
  189 + find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click
  190 + end
  191 +
  192 + def leave_comment(message)
  193 + within(".js-discussion-note-form") do
  194 + fill_in "note_note", with: message
  195 + click_button "Add Comment"
  196 + end
  197 +
  198 + within ".note-text" do
  199 + page.should have_content message
  200 + end
192 201 end
193 202 end
... ...
features/steps/project/project_milestones.rb
... ... @@ -4,7 +4,7 @@ class ProjectMilestones &lt; Spinach::FeatureSteps
4 4 include SharedPaths
5 5  
6 6 Then 'I should see milestone "v2.2"' do
7   - milestone = @project.milestones.find_by_title("v2.2")
  7 + milestone = @project.milestones.find_by(title: "v2.2")
8 8 page.should have_content(milestone.title[0..10])
9 9 page.should have_content(milestone.expires_at)
10 10 page.should have_content("Browse Issues")
... ... @@ -24,22 +24,22 @@ class ProjectMilestones &lt; Spinach::FeatureSteps
24 24 end
25 25  
26 26 Then 'I should see milestone "v2.3"' do
27   - milestone = @project.milestones.find_by_title("v2.3")
  27 + milestone = @project.milestones.find_by(title: "v2.3")
28 28 page.should have_content(milestone.title[0..10])
29 29 page.should have_content(milestone.expires_at)
30 30 page.should have_content("Browse Issues")
31 31 end
32 32  
33 33 And 'project "Shop" has milestone "v2.2"' do
34   - project = Project.find_by_name("Shop")
  34 + project = Project.find_by(name: "Shop")
35 35 milestone = create(:milestone, title: "v2.2", project: project)
36 36  
37 37 3.times { create(:issue, project: project, milestone: milestone) }
38 38 end
39 39  
40 40 Given 'the milestone has open and closed issues' do
41   - project = Project.find_by_name("Shop")
42   - milestone = project.milestones.find_by_title('v2.2')
  41 + project = Project.find_by(name: "Shop")
  42 + milestone = project.milestones.find_by(title: 'v2.2')
43 43  
44 44 # 3 Open issues created above; create one closed issue
45 45 create(:closed_issue, project: project, milestone: milestone)
... ...
features/steps/project/project_network_graph.rb
... ... @@ -10,7 +10,7 @@ class ProjectNetworkGraph &lt; Spinach::FeatureSteps
10 10 # Stub Graph max_size to speed up test (10 commits vs. 650)
11 11 Network::Graph.stub(max_count: 10)
12 12  
13   - project = Project.find_by_name("Shop")
  13 + project = Project.find_by(name: "Shop")
14 14 visit project_network_path(project, "master")
15 15 end
16 16  
... ...
features/steps/project/project_snippets.rb
... ... @@ -90,10 +90,10 @@ class ProjectSnippets &lt; Spinach::FeatureSteps
90 90 end
91 91  
92 92 def project
93   - @project ||= Project.find_by_name!("Shop")
  93 + @project ||= Project.find_by!(name: "Shop")
94 94 end
95 95  
96 96 def project_snippet
97   - @project_snippet ||= ProjectSnippet.find_by_title!("Snippet One")
  97 + @project_snippet ||= ProjectSnippet.find_by!(title: "Snippet one")
98 98 end
99 99 end
... ...
features/steps/project/project_team_management.rb
... ... @@ -10,7 +10,7 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
10 10 end
11 11  
12 12 And 'I should see "Sam" in team list' do
13   - user = User.find_by_name("Sam")
  13 + user = User.find_by(name: "Sam")
14 14 page.should have_content(user.name)
15 15 page.should have_content(user.username)
16 16 end
... ... @@ -20,7 +20,7 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
20 20 end
21 21  
22 22 And 'I select "Mike" as "Reporter"' do
23   - user = User.find_by_name("Mike")
  23 + user = User.find_by(name: "Mike")
24 24  
25 25 select2(user.id, from: "#user_ids", multiple: true)
26 26 within "#new_team_member" do
... ... @@ -42,7 +42,7 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
42 42 end
43 43  
44 44 And 'I change "Sam" role to "Reporter"' do
45   - user = User.find_by_name("Sam")
  45 + user = User.find_by(name: "Sam")
46 46 within "#user_#{user.id}" do
47 47 select "Reporter", from: "team_member_project_access"
48 48 end
... ... @@ -59,7 +59,7 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
59 59 end
60 60  
61 61 And 'I should not see "Sam" in team list' do
62   - user = User.find_by_name("Sam")
  62 + user = User.find_by(name: "Sam")
63 63 page.should_not have_content(user.name)
64 64 page.should_not have_content(user.username)
65 65 end
... ... @@ -73,19 +73,19 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
73 73 end
74 74  
75 75 And '"Sam" is "Shop" developer' do
76   - user = User.find_by_name("Sam")
77   - project = Project.find_by_name("Shop")
  76 + user = User.find_by(name: "Sam")
  77 + project = Project.find_by(name: "Shop")
78 78 project.team << [user, :developer]
79 79 end
80 80  
81 81 Given 'I own project "Website"' do
82   - @project = create(:project, name: "Website", namespace: @user.namespace)
  82 + @project = create(:empty_project, name: "Website", namespace: @user.namespace)
83 83 @project.team << [@user, :master]
84 84 end
85 85  
86 86 And '"Mike" is "Website" reporter' do
87   - user = User.find_by_name("Mike")
88   - project = Project.find_by_name("Website")
  87 + user = User.find_by(name: "Mike")
  88 + project = Project.find_by(name: "Website")
89 89 project.team << [user, :reporter]
90 90 end
91 91  
... ... @@ -94,13 +94,13 @@ class ProjectTeamManagement &lt; Spinach::FeatureSteps
94 94 end
95 95  
96 96 When 'I submit "Website" project for import team' do
97   - project = Project.find_by_name("Website")
  97 + project = Project.find_by(name: "Website")
98 98 select project.name_with_namespace, from: 'source_project_id'
99 99 click_button 'Import'
100 100 end
101 101  
102 102 step 'I click cancel link for "Sam"' do
103   - within "#user_#{User.find_by_name('Sam').id}" do
  103 + within "#user_#{User.find_by(name: 'Sam').id}" do
104 104 click_link('Remove user from team')
105 105 end
106 106 end
... ...
features/steps/project/redirects.rb
... ... @@ -4,7 +4,7 @@ class Spinach::Features::ProjectRedirects &lt; Spinach::FeatureSteps
4 4 include SharedProject
5 5  
6 6 step 'public project "Community"' do
7   - create :project_with_code, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
  7 + create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
8 8 end
9 9  
10 10 step 'private project "Enterprise"' do
... ... @@ -12,7 +12,7 @@ class Spinach::Features::ProjectRedirects &lt; Spinach::FeatureSteps
12 12 end
13 13  
14 14 step 'I visit project "Community" page' do
15   - project = Project.find_by_name('Community')
  15 + project = Project.find_by(name: 'Community')
16 16 visit project_path(project)
17 17 end
18 18  
... ... @@ -23,12 +23,12 @@ class Spinach::Features::ProjectRedirects &lt; Spinach::FeatureSteps
23 23 end
24 24  
25 25 step 'I visit project "Enterprise" page' do
26   - project = Project.find_by_name('Enterprise')
  26 + project = Project.find_by(name: 'Enterprise')
27 27 visit project_path(project)
28 28 end
29 29  
30 30 step 'I visit project "CommunityDoesNotExist" page' do
31   - project = Project.find_by_name('Community')
  31 + project = Project.find_by(name: 'Community')
32 32 visit project_path(project) + 'DoesNotExist'
33 33 end
34 34 end
... ...
features/steps/public/projects_feature.rb
... ... @@ -25,20 +25,20 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
25 25 end
26 26  
27 27 step 'public project "Community"' do
28   - create :project_with_code, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
  28 + create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
29 29 end
30 30  
31 31 step 'public empty project "Empty Public Project"' do
32   - create :project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC
  32 + create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC
33 33 end
34 34  
35 35 step 'I visit empty project page' do
36   - project = Project.find_by_name('Empty Public Project')
  36 + project = Project.find_by(name: 'Empty Public Project')
37 37 visit project_path(project)
38 38 end
39 39  
40 40 step 'I visit project "Community" page' do
41   - project = Project.find_by_name('Community')
  41 + project = Project.find_by(name: 'Community')
42 42 visit project_path(project)
43 43 end
44 44  
... ... @@ -47,14 +47,14 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
47 47 end
48 48  
49 49 step 'I should see empty public project details with http clone info' do
50   - project = Project.find_by_name('Empty Public Project')
  50 + project = Project.find_by(name: 'Empty Public Project')
51 51 page.all(:css, '.git-empty .clone').each do |element|
52 52 element.text.should include(project.http_url_to_repo)
53 53 end
54 54 end
55 55  
56 56 step 'I should see empty public project details with ssh clone info' do
57   - project = Project.find_by_name('Empty Public Project')
  57 + project = Project.find_by(name: 'Empty Public Project')
58 58 page.all(:css, '.git-empty .clone').each do |element|
59 59 element.text.should include(project.url_to_repo)
60 60 end
... ... @@ -65,7 +65,7 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
65 65 end
66 66  
67 67 step 'I visit project "Enterprise" page' do
68   - project = Project.find_by_name('Enterprise')
  68 + project = Project.find_by(name: 'Enterprise')
69 69 visit project_path(project)
70 70 end
71 71  
... ... @@ -76,7 +76,7 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
76 76 end
77 77  
78 78 step 'internal project "Internal"' do
79   - create :project_with_code, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL
  79 + create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL
80 80 end
81 81  
82 82 step 'I should see project "Internal"' do
... ... @@ -88,7 +88,7 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
88 88 end
89 89  
90 90 step 'I visit project "Internal" page' do
91   - project = Project.find_by_name('Internal')
  91 + project = Project.find_by(name: 'Internal')
92 92 visit project_path(project)
93 93 end
94 94  
... ... @@ -99,12 +99,12 @@ class Spinach::Features::PublicProjectsFeature &lt; Spinach::FeatureSteps
99 99 end
100 100  
101 101 step 'I should see an http link to the repository' do
102   - project = Project.find_by_name 'Community'
  102 + project = Project.find_by(name: 'Community')
103 103 page.should have_field('project_clone', with: project.http_url_to_repo)
104 104 end
105 105  
106 106 step 'I should see an ssh link to the repository' do
107   - project = Project.find_by_name 'Community'
  107 + project = Project.find_by(name: 'Community')
108 108 page.should have_field('project_clone', with: project.url_to_repo)
109 109 end
110 110 end
... ...
features/steps/shared/paths.rb
... ... @@ -241,7 +241,7 @@ module SharedPaths
241 241 end
242 242  
243 243 step 'I visit issue page "Release 0.4"' do
244   - issue = Issue.find_by_title("Release 0.4")
  244 + issue = Issue.find_by(title: "Release 0.4")
245 245 visit project_issue_path(issue.project, issue)
246 246 end
247 247  
... ... @@ -250,12 +250,12 @@ module SharedPaths
250 250 end
251 251  
252 252 step 'I visit merge request page "Bug NS-04"' do
253   - mr = MergeRequest.find_by_title("Bug NS-04")
  253 + mr = MergeRequest.find_by(title: "Bug NS-04")
254 254 visit project_merge_request_path(mr.target_project, mr)
255 255 end
256 256  
257 257 step 'I visit merge request page "Bug NS-05"' do
258   - mr = MergeRequest.find_by_title("Bug NS-05")
  258 + mr = MergeRequest.find_by(title: "Bug NS-05")
259 259 visit project_merge_request_path(mr.target_project, mr)
260 260 end
261 261  
... ... @@ -292,7 +292,7 @@ module SharedPaths
292 292 end
293 293  
294 294 step 'I visit public page for "Community" project' do
295   - visit public_project_path(Project.find_by_name("Community"))
  295 + visit public_project_path(Project.find_by(name: "Community"))
296 296 end
297 297  
298 298 # ----------------------------------------
... ... @@ -316,6 +316,6 @@ module SharedPaths
316 316 end
317 317  
318 318 def project
319   - project = Project.find_by_name!("Shop")
  319 + project = Project.find_by!(name: "Shop")
320 320 end
321 321 end
... ...
features/steps/shared/project.rb
... ... @@ -3,26 +3,26 @@ module SharedProject
3 3  
4 4 # Create a project without caring about what it's called
5 5 And "I own a project" do
6   - @project = create(:project_with_code, namespace: @user.namespace)
  6 + @project = create(:project, namespace: @user.namespace)
7 7 @project.team << [@user, :master]
8 8 end
9 9  
10 10 # Create a specific project called "Shop"
11 11 And 'I own project "Shop"' do
12   - @project = Project.find_by_name "Shop"
13   - @project ||= create(:project_with_code, name: "Shop", namespace: @user.namespace)
  12 + @project = Project.find_by(name: "Shop")
  13 + @project ||= create(:project, name: "Shop", namespace: @user.namespace)
14 14 @project.team << [@user, :master]
15 15 end
16 16  
17 17 # Create another specific project called "Forum"
18 18 And 'I own project "Forum"' do
19   - @project = Project.find_by_name "Forum"
20   - @project ||= create(:project_with_code, name: "Forum", namespace: @user.namespace, path: 'forum_project')
  19 + @project = Project.find_by(name: "Forum")
  20 + @project ||= create(:project, name: "Forum", namespace: @user.namespace, path: 'forum_project')
21 21 @project.team << [@user, :master]
22 22 end
23 23  
24 24 And 'project "Shop" has push event' do
25   - @project = Project.find_by_name("Shop")
  25 + @project = Project.find_by(name: "Shop")
26 26  
27 27 data = {
28 28 before: "0000000000000000000000000000000000000000",
... ... @@ -48,7 +48,7 @@ module SharedProject
48 48 end
49 49  
50 50 Then 'I should see project "Shop" activity feed' do
51   - project = Project.find_by_name("Shop")
  51 + project = Project.find_by(name: "Shop")
52 52 page.should have_content "#{@user.name} pushed new branch new_design at #{project.name_with_namespace}"
53 53 end
54 54  
... ...
features/steps/snippets/discover_snippets.rb
... ... @@ -12,6 +12,6 @@ class DiscoverSnippets &lt; Spinach::FeatureSteps
12 12 end
13 13  
14 14 def snippet
15   - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
  15 + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one")
16 16 end
17 17 end
... ...
features/steps/snippets/snippets.rb
... ... @@ -59,6 +59,6 @@ class SnippetsFeature &lt; Spinach::FeatureSteps
59 59 end
60 60  
61 61 def snippet
62   - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
  62 + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one")
63 63 end
64 64 end
... ...
features/steps/snippets/user_snippets.rb
... ... @@ -36,6 +36,6 @@ class UserSnippets &lt; Spinach::FeatureSteps
36 36 end
37 37  
38 38 def snippet
39   - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one")
  39 + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one")
40 40 end
41 41 end
... ...
lib/api/deploy_keys.rb
... ... @@ -38,14 +38,14 @@ module API
38 38 attrs[:key].strip!
39 39  
40 40 # check if key already exist in project
41   - key = user_project.deploy_keys.find_by_key(attrs[:key])
  41 + key = user_project.deploy_keys.find_by(key: attrs[:key])
42 42 if key
43 43 present key, with: Entities::SSHKey
44 44 return
45 45 end
46 46  
47 47 # Check for available deploy keys in other projects
48   - key = current_user.accessible_deploy_keys.find_by_key(attrs[:key])
  48 + key = current_user.accessible_deploy_keys.find_by(key: attrs[:key])
49 49 if key
50 50 user_project.deploy_keys << key
51 51 present key, with: Entities::SSHKey
... ...
lib/api/entities.rb
... ... @@ -48,19 +48,19 @@ module API
48 48  
49 49 class ProjectMember < UserBasic
50 50 expose :project_access, as: :access_level do |user, options|
51   - options[:project].users_projects.find_by_user_id(user.id).project_access
  51 + options[:project].users_projects.find_by(user_id: user.id).project_access
52 52 end
53 53 end
54 54  
55 55 class TeamMember < UserBasic
56 56 expose :permission, as: :access_level do |user, options|
57   - options[:user_team].user_team_user_relationships.find_by_user_id(user.id).permission
  57 + options[:user_team].user_team_user_relationships.find_by(user_id: user.id).permission
58 58 end
59 59 end
60 60  
61 61 class TeamProject < Project
62 62 expose :greatest_access, as: :greatest_access_level do |project, options|
63   - options[:user_team].user_team_project_relationships.find_by_project_id(project.id).greatest_access
  63 + options[:user_team].user_team_project_relationships.find_by(project_id: project.id).greatest_access
64 64 end
65 65 end
66 66  
... ... @@ -74,7 +74,7 @@ module API
74 74  
75 75 class GroupMember < UserBasic
76 76 expose :group_access, as: :access_level do |user, options|
77   - options[:group].users_groups.find_by_user_id(user.id).group_access
  77 + options[:group].users_groups.find_by(user_id: user.id).group_access
78 78 end
79 79 end
80 80  
... ...
lib/api/groups.rb
... ... @@ -121,11 +121,11 @@ module API
121 121 render_api_error!("Wrong access level", 422)
122 122 end
123 123 group = find_group(params[:id])
124   - if group.users_groups.find_by_user_id(params[:user_id])
  124 + if group.users_groups.find_by(user_id: params[:user_id])
125 125 render_api_error!("Already exists", 409)
126 126 end
127 127 group.add_users([params[:user_id]], params[:access_level])
128   - member = group.users_groups.find_by_user_id(params[:user_id])
  128 + member = group.users_groups.find_by(user_id: params[:user_id])
129 129 present member.user, with: Entities::GroupMember, group: group
130 130 end
131 131  
... ... @@ -139,7 +139,7 @@ module API
139 139 # DELETE /groups/:id/members/:user_id
140 140 delete ":id/members/:user_id" do
141 141 group = find_group(params[:id])
142   - member = group.users_groups.find_by_user_id(params[:user_id])
  142 + member = group.users_groups.find_by(user_id: params[:user_id])
143 143 if member.nil?
144 144 render_api_error!("404 Not Found - user_id:#{params[:user_id]} not a member of group #{group.name}",404)
145 145 else
... ...
lib/api/helpers.rb
... ... @@ -7,7 +7,7 @@ module API
7 7  
8 8 def current_user
9 9 private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s
10   - @current_user ||= User.find_by_authentication_token(private_token)
  10 + @current_user ||= User.find_by(authentication_token: private_token)
11 11 identifier = sudo_identifier()
12 12  
13 13 # If the sudo is the current user do nothing
... ... @@ -47,7 +47,7 @@ module API
47 47 end
48 48  
49 49 def find_project(id)
50   - project = Project.find_by_id(id) || Project.find_with_namespace(id)
  50 + project = Project.find_by(id: id) || Project.find_with_namespace(id)
51 51  
52 52 if project && can?(current_user, :read_project, project)
53 53 project
... ...
lib/api/merge_requests.rb
... ... @@ -81,14 +81,13 @@ module API
81 81 merge_request.target_project = user_project
82 82 else
83 83 if target_matches_fork(target_project_id,user_project)
84   - merge_request.target_project = Project.find_by_id(attrs[:target_project_id])
  84 + merge_request.target_project = Project.find_by(id: attrs[:target_project_id])
85 85 else
86 86 render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
87 87 end
88 88 end
89 89  
90 90 if merge_request.save
91   - merge_request.reload_code
92 91 present merge_request, with: Entities::MergeRequest
93 92 else
94 93 handle_merge_request_errors! merge_request.errors
... ...
lib/api/projects.rb
... ... @@ -266,7 +266,7 @@ module API
266 266 authorize! :admin_project, user_project
267 267 required_attributes! [:access_level]
268 268  
269   - team_member = user_project.users_projects.find_by_user_id(params[:user_id])
  269 + team_member = user_project.users_projects.find_by(user_id: params[:user_id])
270 270 not_found!("User can not be found") if team_member.nil?
271 271  
272 272 if team_member.update_attributes(project_access: params[:access_level])
... ... @@ -286,7 +286,7 @@ module API
286 286 # DELETE /projects/:id/members/:user_id
287 287 delete ":id/members/:user_id" do
288 288 authorize! :admin_project, user_project
289   - team_member = user_project.users_projects.find_by_user_id(params[:user_id])
  289 + team_member = user_project.users_projects.find_by(user_id: params[:user_id])
290 290 unless team_member.nil?
291 291 team_member.destroy
292 292 else
... ...
lib/api/repositories.rb
... ... @@ -51,7 +51,7 @@ module API
51 51  
52 52 @branch = user_project.repository.find_branch(params[:branch])
53 53 not_found! unless @branch
54   - protected_branch = user_project.protected_branches.find_by_name(@branch.name)
  54 + protected_branch = user_project.protected_branches.find_by(name: @branch.name)
55 55 user_project.protected_branches.create(name: @branch.name) unless protected_branch
56 56  
57 57 present @branch, with: Entities::RepoObject, project: user_project
... ... @@ -69,7 +69,7 @@ module API
69 69  
70 70 @branch = user_project.repository.find_branch(params[:branch])
71 71 not_found! unless @branch
72   - protected_branch = user_project.protected_branches.find_by_name(@branch.name)
  72 + protected_branch = user_project.protected_branches.find_by(name: @branch.name)
73 73 protected_branch.destroy if protected_branch
74 74  
75 75 present @branch, with: Entities::RepoObject, project: user_project
... ...
lib/api/users.rb
... ... @@ -119,7 +119,7 @@ module API
119 119 # DELETE /users/:id
120 120 delete ":id" do
121 121 authenticated_as_admin!
122   - user = User.find_by_id(params[:id])
  122 + user = User.find_by(id: params[:id])
123 123  
124 124 if user
125 125 user.destroy
... ...
lib/backup/database.rb
... ... @@ -11,23 +11,29 @@ module Backup
11 11 end
12 12  
13 13 def dump
14   - case config["adapter"]
  14 + success = case config["adapter"]
15 15 when /^mysql/ then
  16 + print "Dumping MySQL database #{config['database']} ... "
16 17 system('mysqldump', *mysql_args, config['database'], out: db_file_name)
17 18 when "postgresql" then
  19 + print "Dumping PostgreSQL database #{config['database']} ... "
18 20 pg_env
19 21 system('pg_dump', config['database'], out: db_file_name)
20 22 end
  23 + report_success(success)
21 24 end
22 25  
23 26 def restore
24   - case config["adapter"]
  27 + success = case config["adapter"]
25 28 when /^mysql/ then
  29 + print "Restoring MySQL database #{config['database']} ... "
26 30 system('mysql', *mysql_args, config['database'], in: db_file_name)
27 31 when "postgresql" then
  32 + print "Restoring PostgreSQL database #{config['database']} ... "
28 33 pg_env
29 34 system('psql', config['database'], '-f', db_file_name)
30 35 end
  36 + report_success(success)
31 37 end
32 38  
33 39 protected
... ... @@ -54,5 +60,13 @@ module Backup
54 60 ENV['PGPORT'] = config["port"].to_s if config["port"]
55 61 ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
56 62 end
  63 +
  64 + def report_success(success)
  65 + if success
  66 + puts '[DONE]'.green
  67 + else
  68 + puts '[FAILED]'.red
  69 + end
  70 + end
57 71 end
58 72 end
... ...
lib/gitlab/auth.rb
1 1 module Gitlab
2 2 class Auth
3 3 def find(login, password)
4   - user = User.find_by_email(login) || User.find_by_username(login)
  4 + user = User.find_by(email: login) || User.find_by(username: login)
5 5  
6 6 if user.nil? || user.ldap_user?
7 7 # Second chance - try LDAP authentication
... ...
lib/gitlab/identifier.rb
... ... @@ -6,17 +6,17 @@ module Gitlab
6 6 if identifier.blank?
7 7 # Local push from gitlab
8 8 email = project.repository.commit(newrev).author_email rescue nil
9   - User.find_by_email(email) if email
  9 + User.find_by(email: email) if email
10 10  
11 11 elsif identifier =~ /\Auser-\d+\Z/
12 12 # git push over http
13 13 user_id = identifier.gsub("user-", "")
14   - User.find_by_id(user_id)
  14 + User.find_by(id: user_id)
15 15  
16 16 elsif identifier =~ /\Akey-\d+\Z/
17 17 # git push over ssh
18 18 key_id = identifier.gsub("key-", "")
19   - Key.find_by_id(key_id).try(:user)
  19 + Key.find_by(id: key_id).try(:user)
20 20 end
21 21 end
22 22 end
... ...
lib/gitlab/ldap/user.rb
... ... @@ -44,13 +44,13 @@ module Gitlab
44 44 end
45 45  
46 46 def find_user(email)
47   - user = model.find_by_email(email)
  47 + user = model.find_by(email: email)
48 48  
49 49 # If no user found and allow_username_or_email_login is true
50 50 # we look for user by extracting part of their email
51 51 if !user && email && ldap_conf['allow_username_or_email_login']
52 52 uname = email.partition('@').first
53   - user = model.find_by_username(uname)
  53 + user = model.find_by(username: uname)
54 54 end
55 55  
56 56 user
... ...
lib/support/init.d/gitlab
... ... @@ -3,7 +3,6 @@
3 3 # GITLAB
4 4 # Maintainer: @randx
5 5 # Authors: rovanion.luckey@gmail.com, @randx
6   -# App Version: 6.0
7 6  
8 7 ### BEGIN INIT INFO
9 8 # Provides: gitlab
... ...
lib/support/nginx/gitlab
1 1 # GITLAB
2 2 # Maintainer: @randx
3   -# App Version: 5.0
4 3  
5 4 upstream gitlab {
6 5 server unix:/home/git/gitlab/tmp/sockets/gitlab.socket;
... ...
lib/tasks/gitlab/bulk_add_permission.rake
... ... @@ -15,7 +15,7 @@ namespace :gitlab do
15 15  
16 16 desc "GITLAB | Add a specific user to all projects (as a developer)"
17 17 task :user_to_projects, [:email] => :environment do |t, args|
18   - user = User.find_by_email args.email
  18 + user = User.find_by(email: args.email)
19 19 project_ids = Project.pluck(:id)
20 20 puts "Importing #{user.email} users into #{project_ids.size} projects"
21 21 UsersProject.add_users_into_projects(project_ids, Array.wrap(user.id), UsersProject::DEVELOPER)
... ...
lib/tasks/gitlab/enable_namespaces.rake
... ... @@ -43,13 +43,13 @@ namespace :gitlab do
43 43 username.gsub!("+", ".")
44 44  
45 45 # return username if no matches
46   - return username unless User.find_by_username(username)
  46 + return username unless User.find_by(username: username)
47 47  
48 48 # look for same username
49 49 (1..10).each do |i|
50 50 suffixed_username = "#{username}#{i}"
51 51  
52   - return suffixed_username unless User.find_by_username(suffixed_username)
  52 + return suffixed_username unless User.find_by(username: suffixed_username)
53 53 end
54 54 end
55 55  
... ...
lib/tasks/gitlab/import.rake
... ... @@ -50,7 +50,7 @@ namespace :gitlab do
50 50  
51 51 # find group namespace
52 52 if group_name
53   - group = Group.find_by_path(group_name)
  53 + group = Group.find_by(path: group_name)
54 54 # create group namespace
55 55 if !group
56 56 group = Group.new(:name => group_name)
... ...