summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorIzaak Alpert <ihalpert@blackberry.com>2013-04-25 10:15:33 -0400
committerIzaak Alpert <ialpert@blackberry.com>2013-07-17 22:41:30 -0400
commit3d7194f0112da12e8732df9ffe8b34fe7d0a9f6b (patch)
tree9b3c68c04b5ead5e35456595a07453b036b2dbc8 /app
parentfd033671933fcc0f472480d98c907aefde357416 (diff)
downloadgitlab-ce-3d7194f0112da12e8732df9ffe8b34fe7d0a9f6b.tar.gz
Merge Request on forked projects
The good: - You can do a merge request for a forked commit and it will merge properly (i.e. it does work). - Push events take into account merge requests on forked projects - Tests around merge_actions now present, spinach, and other rspec tests - Satellites now clean themselves up rather then recreate The questionable: - Events only know about target projects - Project's merge requests only hold on to MR's where they are the target - All operations performed in the satellite The bad: - Duplication between project's repositories and satellites (e.g. commits_between) (for reference: http://feedback.gitlab.com/forums/176466-general/suggestions/3456722-merge-requests-between-projects-repos) Fixes: Make test repos/satellites only create when needed -Spinach/Rspec now only initialize test directory, and setup stubs (things that are relatively cheap) -project_with_code, source_project_with_code, and target_project_with_code now create/destroy their repos individually -fixed remote removal -How to merge renders properly -Update emails to show project/branches -Edit MR doesn't set target branch -Fix some failures on editing/creating merge requests, added a test -Added back a test around merge request observer -Clean up project_transfer_spec, Remove duplicate enable/disable observers -Ensure satellite lock files are cleaned up, Attempted to add some testing around these as well -Signifant speed ups for tests -Update formatting ordering in notes_on_merge_requests -Remove wiki schema update Fixes for search/search results -Search results was using by_project for a list of projects, updated this to use in_projects -updated search results to reference the correct (target) project -udpated search results to print both sides of the merge request Change-Id: I19407990a0950945cc95d62089cbcc6262dab1a8
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/common.scss11
-rw-r--r--app/contexts/filter_context.rb14
-rw-r--r--app/contexts/merge_requests_load_context.rb2
-rw-r--r--app/contexts/search_context.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb48
-rw-r--r--app/helpers/commits_helper.rb4
-rw-r--r--app/helpers/merge_requests_helper.rb26
-rw-r--r--app/mailers/emails/merge_requests.rb47
-rw-r--r--app/models/concerns/issuable.rb5
-rw-r--r--app/models/issue.rb10
-rw-r--r--app/models/merge_request.rb103
-rw-r--r--app/models/note.rb40
-rw-r--r--app/models/project.rb2
-rw-r--r--app/observers/activity_observer.rb42
-rw-r--r--app/observers/issue_observer.rb2
-rw-r--r--app/observers/merge_request_observer.rb39
-rw-r--r--app/services/notification_service.rb38
-rw-r--r--app/views/events/_event_last_push.html.haml5
-rw-r--r--app/views/merge_requests/update_branches.js.haml8
-rw-r--r--app/views/notify/closed_merge_request_email.html.haml2
-rw-r--r--app/views/notify/closed_merge_request_email.text.haml4
-rw-r--r--app/views/notify/merged_merge_request_email.html.haml4
-rw-r--r--app/views/notify/merged_merge_request_email.text.haml4
-rw-r--r--app/views/notify/new_merge_request_email.html.haml4
-rw-r--r--app/views/notify/new_merge_request_email.text.erb5
-rw-r--r--app/views/notify/note_merge_request_email.html.haml4
-rw-r--r--app/views/notify/note_merge_request_email.text.erb2
-rw-r--r--app/views/notify/reassigned_merge_request_email.html.haml2
-rw-r--r--app/views/notify/reassigned_merge_request_email.text.erb2
-rw-r--r--app/views/projects/commits/_commit.html.haml8
-rw-r--r--app/views/projects/commits/_commits.html.haml3
-rw-r--r--app/views/projects/compare/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/_form.html.haml46
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml7
-rw-r--r--app/views/projects/merge_requests/branch_from.js.haml2
-rw-r--r--app/views/projects/merge_requests/branch_to.js.haml2
-rw-r--r--app/views/projects/merge_requests/show/_commits.html.haml6
-rw-r--r--app/views/projects/merge_requests/show/_how_to_merge.html.haml60
-rw-r--r--app/views/projects/merge_requests/show/_mr_accept.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_mr_title.html.haml2
-rw-r--r--app/views/search/_result.html.haml4
-rw-r--r--app/views/shared/_merge_requests.html.haml2
42 files changed, 412 insertions, 215 deletions
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 20c772d8e94..2f98df3fe41 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -415,6 +415,17 @@ img.emoji {
@extend .light-well;
@extend .light;
margin-bottom: 10px;
+
+.label-project {
+ @include border-radius(4px);
+ padding: 2px 4px;
+ border: none;
+ font-size: 14px;
+ background: #474D57;
+ color: #fff;
+ font-family: $monospace_font;
+ text-shadow: 0 1px 1px #111;
+ font-weight: normal;
}
.group-name {
diff --git a/app/contexts/filter_context.rb b/app/contexts/filter_context.rb
index 401d19b31c8..7349abb8d6e 100644
--- a/app/contexts/filter_context.rb
+++ b/app/contexts/filter_context.rb
@@ -12,7 +12,7 @@ class FilterContext
def apply_filter items
if params[:project_id]
- items = items.where(project_id: params[:project_id])
+ items = items.by_project(params[:project_id])
end
if params[:search].present?
@@ -20,12 +20,12 @@ class FilterContext
end
case params[:status]
- when 'closed'
- items.closed
- when 'all'
- items
- else
- items.opened
+ when 'closed'
+ items.closed
+ when 'all'
+ items
+ else
+ items.opened
end
end
end
diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb
index fd44572c0eb..9eba81295a9 100644
--- a/app/contexts/merge_requests_load_context.rb
+++ b/app/contexts/merge_requests_load_context.rb
@@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext
end
merge_requests = merge_requests.page(params[:page]).per(20)
- merge_requests = merge_requests.includes(:author, :project).order("created_at desc")
+ merge_requests = merge_requests.includes(:author, :source_project, :target_project).order("created_at desc")
# Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present?
diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb
index 22cda709f69..4b1be84a2e1 100644
--- a/app/contexts/search_context.rb
+++ b/app/contexts/search_context.rb
@@ -19,7 +19,7 @@ class SearchContext
if params[:search_code].present?
result[:blobs] = project.repository.search_files(query, params[:repository_ref]) unless project.empty_repo?
else
- result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
+ result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).limit(10)
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
result[:wiki_pages] = []
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 33c1a1feff7..6c5285be0a2 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -24,8 +24,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
format.html
format.js
- format.diff { render text: @merge_request.to_diff }
- format.patch { render text: @merge_request.to_patch }
+ format.diff { render text: @merge_request.to_diff(current_user) }
+ format.patch { render text: @merge_request.to_patch(current_user) }
end
end
@@ -33,25 +33,39 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commit = @merge_request.last_commit
@comments_allowed = @reply_allowed = true
- @comments_target = { noteable_type: 'MergeRequest',
- noteable_id: @merge_request.id }
+ @comments_target = {noteable_type: 'MergeRequest',
+ noteable_id: @merge_request.id}
@line_notes = @merge_request.notes.where("line_code is not null")
end
def new
@merge_request = @project.merge_requests.new(params[:merge_request])
+
+ if params[:merge_request] && params[:merge_request][:source_project_id]
+ @merge_request.source_project = Project.find_by_id(params[:merge_request][:source_project_id])
+ else
+ @merge_request.source_project = @project
+ end
+ if params[:merge_request] && params[:merge_request][:target_project_id]
+ @merge_request.target_project = Project.find_by_id(params[:merge_request][:target_project_id])
+ end
+ @target_branches = @merge_request.target_project.nil? ? [] : @merge_request.target_project.repository.branch_names
+ @merge_request
end
def edit
+ @target_branches = @merge_request.target_project.repository.branch_names
end
def create
@merge_request = @project.merge_requests.new(params[:merge_request])
@merge_request.author = current_user
-
+ @merge_request.source_project_id = params[:merge_request][:source_project_id].to_i
+ @merge_request.target_project_id = params[:merge_request][:target_project_id].to_i
+ @target_branches ||= []
if @merge_request.save
@merge_request.reload_code
- redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.'
+ redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully created.'
else
render "new"
end
@@ -89,22 +103,36 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def branch_from
+ #This is always source
@commit = @repository.commit(params[:ref])
end
def branch_to
- @commit = @repository.commit(params[:ref])
+ @target_project = selected_target_project
+ @commit = @target_project.repository.commit(params[:ref])
end
+ def update_branches
+ @target_project = selected_target_project
+ @target_branches = (@target_project.repository.branch_names).unshift("Select branch")
+ @target_branches
+ end
+
+
def ci_status
status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
- response = { status: status }
+ response = {status: status}
render json: response
end
protected
+ def selected_target_project
+ ((@project.id.to_s == params[:target_project_id]) || @project.forked_project_link.nil?) ? @project : @project.forked_project_link.forked_from_project
+ end
+
+
def merge_request
@merge_request ||= @project.merge_requests.find(params[:id])
end
@@ -123,11 +151,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def validates_merge_request
# Show git not found page if target branch doesn't exist
- return invalid_mr unless @project.repository.branch_names.include?(@merge_request.target_branch)
+ return invalid_mr unless @merge_request.target_project.repository.branch_names.include?(@merge_request.target_branch)
# Show git not found page if source branch doesn't exist
# and there is no saved commits between source & target branch
- return invalid_mr if !@project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
+ return invalid_mr if !@merge_request.source_project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
end
def define_show_vars
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 86979156d94..ed0d4d34585 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -108,8 +108,8 @@ module CommitsHelper
end
end
- def commit_to_html commit
- escape_javascript(render 'projects/commits/commit', commit: commit)
+ def commit_to_html commit, project
+ escape_javascript(render 'projects/commits/commit', commit: commit, project: project) unless commit.nil?
end
def diff_line_content(line)
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 05ffec066f8..e8e7bf990ac 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,13 +1,27 @@
module MergeRequestsHelper
def new_mr_path_from_push_event(event)
new_project_merge_request_path(
- event.project,
- merge_request: {
+ event.project,
+ new_mr_from_push_event(event, event.project)
+ )
+ end
+
+ def new_mr_path_for_fork_from_push_event(event)
+ new_project_merge_request_path(
+ event.project,
+ new_mr_from_push_event(event, event.project.forked_from_project)
+ )
+ end
+
+
+ def new_mr_from_push_event(event, target_project)
+ return :merge_request => {
+ source_project_id: event.project.id,
+ target_project_id: target_project.id,
source_branch: event.branch_name,
- target_branch: event.project.repository.root_ref,
+ target_branch: target_project.repository.root_ref,
title: event.branch_name.titleize
- }
- )
+ }
end
def mr_css_classes mr
@@ -18,6 +32,6 @@ module MergeRequestsHelper
end
def ci_build_details_path merge_request
- merge_request.project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
+ merge_request.source_project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
end
end
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index de47903c0d4..3dc3ddc3efd 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -2,28 +2,65 @@ module Emails
module MergeRequests
def new_merge_request_email(recipient_id, merge_request_id)
@merge_request = MergeRequest.find(merge_request_id)
- @project = @merge_request.project
- mail(to: recipient(recipient_id), subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
+ mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
end
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
@merge_request = MergeRequest.find(merge_request_id)
@previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
- @project = @merge_request.project
mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title))
end
def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
@merge_request = MergeRequest.find(merge_request_id)
- @project = @merge_request.project
@updated_by = User.find updated_by_user_id
mail(to: recipient(recipient_id), subject: subject("Closed merge request !#{@merge_request.id}", @merge_request.title))
end
def merged_merge_request_email(recipient_id, merge_request_id)
@merge_request = MergeRequest.find(merge_request_id)
- @project = @merge_request.project
mail(to: recipient(recipient_id), subject: subject("Accepted merge request !#{@merge_request.id}", @merge_request.title))
end
end
+
+
+ # Over rides default behavour to show source/target
+ # Formats arguments into a String suitable for use as an email subject
+ #
+ # extra - Extra Strings to be inserted into the subject
+ #
+ # Examples
+ #
+ # >> subject('Lorem ipsum')
+ # => "GitLab Merge Request | Lorem ipsum"
+ #
+ # # Automatically inserts Project name:
+ # Forked MR
+ # => source project => <Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
+ # => target project => <Project id: 2, name: "My Ror", path: "ruby_on_rails", ...>
+ # => source branch => source
+ # => target branch => target
+ # >> subject('Lorem ipsum')
+ # => "GitLab Merge Request | Ruby on Rails:source >> My Ror:target | Lorem ipsum "
+ #
+ # Non Forked MR
+ # => source project => <Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
+ # => target project => <Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
+ # => source branch => source
+ # => target branch => target
+ # >> subject('Lorem ipsum')
+ # => "GitLab Merge Request | Ruby on Rails | source >> target | Lorem ipsum "
+ # # Accepts multiple arguments
+ # >> subject('Lorem ipsum', 'Dolor sit amet')
+ # => "GitLab Merge Request | Lorem ipsum | Dolor sit amet"
+ def subject(*extra)
+ subject = "GitLab Merge Request |"
+ if @merge_request.for_fork?
+ subject << "#{@merge_request.source_project.name_with_namespace}:#{merge_request.source_branch} >> #{@merge_request.target_project.name_with_namespace}:#{merge_request.target_branch}"
+ else
+ subject << "#{@merge_request.source_project.name_with_namespace} | #{merge_request.source_branch} >> #{merge_request.target_branch}"
+ end
+ subject << " | " + extra.join(' | ') if extra.present?
+ subject
+ end
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 8868e818daa..88de1a037aa 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -9,19 +9,14 @@ module Issuable
include Mentionable
included do
- belongs_to :project
belongs_to :author, class_name: "User"
belongs_to :assignee, class_name: "User"
belongs_to :milestone
has_many :notes, as: :noteable, dependent: :destroy
- validates :project, presence: true
validates :author, presence: true
validates :title, presence: true, length: { within: 0..255 }
- scope :opened, -> { with_state(:opened) }
- scope :closed, -> { with_state(:closed) }
- scope :of_group, ->(group) { where(project_id: group.project_ids) }
scope :assigned_to, ->(u) { where(assignee_id: u.id)}
scope :recent, -> { order("created_at DESC") }
scope :assigned, -> { where("assignee_id IS NOT NULL") }
diff --git a/app/models/issue.rb b/app/models/issue.rb
index f56928891dc..c171941928c 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -17,8 +17,18 @@
#
class Issue < ActiveRecord::Base
+
include Issuable
+ belongs_to :project
+ validates :project, presence: true
+
+ scope :of_group, ->(group) { where(project_id: group.project_ids) }
+ scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
+ scope :opened, -> { with_state(:opened) }
+ scope :closed, -> { with_state(:closed) }
+ scope :by_project, ->(project_id) {where(project_id:project_id)}
+
attr_accessible :title, :assignee_id, :position, :description,
:milestone_id, :label_list, :author_id_of_changes,
:state_event
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 2a476355404..0e0ae3c3a07 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -2,30 +2,37 @@
#
# Table name: merge_requests
#
-# id :integer not null, primary key
-# target_branch :string(255) not null
-# source_branch :string(255) not null
-# project_id :integer not null
-# author_id :integer
-# assignee_id :integer
-# title :string(255)
-# created_at :datetime
-# updated_at :datetime
-# st_commits :text(2147483647)
-# st_diffs :text(2147483647)
-# milestone_id :integer
-# state :string(255)
-# merge_status :string(255)
+# id :integer not null, primary key
+# target_project_id :integer not null
+# target_branch :string(255) not null
+# source_project_id :integer not null
+# source_branch :string(255) not null
+# author_id :integer
+# assignee_id :integer
+# title :string(255)
+# created_at :datetime
+# updated_at :datetime
+# st_commits :text(2147483647)
+# st_diffs :text(2147483647)
+# milestone_id :integer
+# state :string(255)
+# merge_status :string(255)
#
require Rails.root.join("app/models/commit")
require Rails.root.join("lib/static_model")
class MergeRequest < ActiveRecord::Base
+
include Issuable
- attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
- :author_id_of_changes, :state_event
+ belongs_to :target_project,:foreign_key => :target_project_id, class_name: "Project"
+ belongs_to :source_project, :foreign_key => :source_project_id,class_name: "Project"
+
+ BROKEN_DIFF = "--broken-diff"
+
+ attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id,:author_id_of_changes, :state_event
+
attr_accessor :should_remove_source_branch
@@ -74,22 +81,29 @@ class MergeRequest < ActiveRecord::Base
serialize :st_commits
serialize :st_diffs
+ validates :source_project, presence: true
validates :source_branch, presence: true
+ validates :target_project, presence: true
validates :target_branch, presence: true
- validate :validate_branches
+ validate :validate_branches
+ scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)",group_project_ids:group.project_ids) }
+ scope :of_user_team, ->(team) { where("(source_project_id in (:team_project_ids) OR target_project_id in (:team_project_ids) AND assignee_id in (:team_member_ids))",team_project_ids:team.project_ids,team_member_ids:team.member_ids) }
+ scope :opened, -> { with_state(:opened) }
+ scope :closed, -> { with_state(:closed) }
scope :merged, -> { with_state(:merged) }
- scope :by_branch, ->(branch_name) { where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) }
+ scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
-
+ scope :by_project, ->(project_id) { where("source_project_id = :project_id OR target_project_id = :project_id", project_id: project_id) }
+ scope :in_projects, ->(project_ids) { where("source_project_id in (:project_ids) OR target_project_id in (:project_ids)", project_ids: project_ids) }
# Closed scope for merge request should return
# both merged and closed mr's
scope :closed, -> { with_states(:closed, :merged) }
def validate_branches
- if target_branch == source_branch
- errors.add :branch_conflict, "You can not use same branch for source and target branches"
+ if target_project==source_project && target_branch == source_branch
+ errors.add :branch_conflict, "You can not use same project/branch for source and target"
end
if opened? || reopened?
@@ -137,7 +151,14 @@ class MergeRequest < ActiveRecord::Base
end
def unmerged_diffs
- project.repository.diffs_between(source_branch, target_branch)
+ #TODO:[IA-8] this needs to be handled better -- logged etc
+ diffs = Gitlab::Satellite::MergeAction.new(author, self).diffs_between_satellite
+ if diffs
+ diffs = diffs.map { |diff| Gitlab::Git::Diff.new(diff) }
+ else
+ diffs = []
+ end
+ diffs
end
def last_commit
@@ -145,11 +166,11 @@ class MergeRequest < ActiveRecord::Base
end
def merge_event
- self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last
+ self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last
end
def closed_event
- self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
+ self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
end
def commits
@@ -158,24 +179,30 @@ class MergeRequest < ActiveRecord::Base
def probably_merged?
unmerged_commits.empty? &&
- commits.any? && opened?
+ commits.any? && opened?
end
def reloaded_commits
if opened? && unmerged_commits.any?
self.st_commits = dump_commits(unmerged_commits)
save
+
end
commits
end
def unmerged_commits
- self.project.repository.
- commits_between(self.target_branch, self.source_branch).
- sort_by(&:created_at).
- reverse
+ commits = Gitlab::Satellite::MergeAction.new(self.author,self).commits_between
+ commits = commits.map{ |commit| Gitlab::Git::Commit.new(commit, nil) }
+ if commits.present?
+ commits = Commit.decorate(commits).
+ sort_by(&:created_at).
+ reverse
+ end
+ commits
end
+
def merge!(user_id)
self.author_id_of_changes = user_id
self.merge
@@ -195,25 +222,33 @@ class MergeRequest < ActiveRecord::Base
commit_ids = commits.map(&:id)
Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
end
-
# Returns the raw diff for this merge request
#
# see "git diff"
- def to_diff
- project.repo.git.native(:diff, {timeout: 30, raise: true}, "#{target_branch}...#{source_branch}")
+ def to_diff(current_user)
+ Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite
end
+
# Returns the commit as a series of email patches.
#
# see "git format-patch"
- def to_patch
- project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}")
+ def to_patch(current_user)
+ Gitlab::Satellite::MergeAction.new(current_user, self).format_patch
end
def last_commit_short_sha
@last_commit_short_sha ||= last_commit.sha[0..10]
end
+ def for_fork?
+ target_project != source_project
+ end
+
+ def disallow_source_branch_removal?
+ (source_project.root_ref? source_branch) || for_fork?
+ end
+
private
def dump_commits(commits)
diff --git a/app/models/note.rb b/app/models/note.rb
index c23aab03bcc..0175430be4d 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -32,8 +32,8 @@ class Note < ActiveRecord::Base
delegate :name, :email, to: :author, prefix: true
validates :note, :project, presence: true
- validates :line_code, format: { with: /\A[a-z0-9]+_\d+_\d+\Z/ }, allow_blank: true
- validates :attachment, file_size: { maximum: 10.megabytes.to_i }
+ validates :line_code, format: {with: /\A[a-z0-9]+_\d+_\d+\Z/}, allow_blank: true
+ validates :attachment, file_size: {maximum: 10.megabytes.to_i}
validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' }
validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' }
@@ -45,24 +45,24 @@ class Note < ActiveRecord::Base
scope :inline, -> { where("line_code IS NOT NULL") }
scope :not_inline, -> { where(line_code: [nil, '']) }
- scope :common, ->{ where(noteable_type: ["", nil]) }
- scope :fresh, ->{ order("created_at ASC, id ASC") }
- scope :inc_author_project, ->{ includes(:project, :author) }
- scope :inc_author, ->{ includes(:author) }
+ scope :common, -> { where(noteable_type: ["", nil]) }
+ scope :fresh, -> { order("created_at ASC, id ASC") }
+ scope :inc_author_project, -> { includes(:project, :author) }
+ scope :inc_author, -> { includes(:author) }
- def self.create_status_change_note(noteable, author, status)
+ def self.create_status_change_note(noteable, project, author, status)
create({
- noteable: noteable,
- project: noteable.project,
- author: author,
- note: "_Status changed to #{status}_"
- }, without_protection: true)
+ noteable: noteable,
+ project: project,
+ author: author,
+ note: "_Status changed to #{status}_"
+ }, without_protection: true)
end
def commit_author
@commit_author ||=
- project.users.find_by_email(noteable.author_email) ||
- project.users.find_by_name(noteable.author_name)
+ project.users.find_by_email(noteable.author_email) ||
+ project.users.find_by_name(noteable.author_name)
rescue
nil
end
@@ -97,8 +97,8 @@ class Note < ActiveRecord::Base
# otherwise false is returned
def downvote?
votable? && (note.start_with?('-1') ||
- note.start_with?(':-1:')
- )
+ note.start_with?(':-1:')
+ )
end
def for_commit?
@@ -136,8 +136,8 @@ class Note < ActiveRecord::Base
else
super
end
- # Temp fix to prevent app crash
- # if note commit id doesn't exist
+ # Temp fix to prevent app crash
+ # if note commit id doesn't exist
rescue
nil
end
@@ -146,8 +146,8 @@ class Note < ActiveRecord::Base
# otherwise false is returned
def upvote?
votable? && (note.start_with?('+1') ||
- note.start_with?(':+1:')
- )
+ note.start_with?(':+1:')
+ )
end
def votable?
diff --git a/app/models/project.rb b/app/models/project.rb
index 8297c11ba8a..f373446f579 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -53,7 +53,7 @@ class Project < ActiveRecord::Base
has_many :services, dependent: :destroy
has_many :events, dependent: :destroy
- has_many :merge_requests, dependent: :destroy
+ has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id"
has_many :issues, dependent: :destroy, order: "state DESC, created_at DESC"
has_many :milestones, dependent: :destroy
has_many :notes, dependent: :destroy
diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb
index ee3e4629b4c..3740274db2d 100644
--- a/app/observers/activity_observer.rb
+++ b/app/observers/activity_observer.rb
@@ -1,5 +1,5 @@
class ActivityObserver < BaseObserver
- observe :issue, :merge_request, :note, :milestone
+ observe :issue, :note, :milestone
def after_create(record)
event_author_id = record.author_id
@@ -13,47 +13,27 @@ class ActivityObserver < BaseObserver
end
if event_author_id
- Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: Event.determine_action(record),
- author_id: event_author_id
- )
+ create_event(record, Event.determine_action(record))
end
end
def after_close(record, transition)
- Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: Event::CLOSED,
- author_id: record.author_id_of_changes
- )
+ create_event(record, Event::CLOSED)
end
def after_reopen(record, transition)
- Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: Event::REOPENED,
- author_id: record.author_id_of_changes
- )
+ create_event(record, Event::REOPENED)
end
- def after_merge(record, transition)
- # Since MR can be merged via sidekiq
- # to prevent event duplication do this check
- return true if record.merge_event
+ protected
+ def create_event(record, status)
Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: Event::MERGED,
- author_id: record.author_id_of_changes
+ project: record.project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: status,
+ author_id: record.author_id
)
end
end
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 888fa7f6b73..50538419776 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -23,6 +23,6 @@ class IssueObserver < BaseObserver
# Create issue note with service comment like 'Status changed to closed'
def create_note(issue)
- Note.create_status_change_note(issue, current_user, issue.state)
+ Note.create_status_change_note(issue, issue.project, current_user, issue.state)
end
end
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index 03d4a22c1e6..6260b79593a 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -1,23 +1,56 @@
-class MergeRequestObserver < BaseObserver
+class MergeRequestObserver < ActivityObserver
+ observe :merge_request
+ cattr_accessor :current_user
+
def after_create(merge_request)
+ event_author_id = merge_request.author_id
+ if event_author_id
+ create_event(merge_request, Event.determine_action(merge_request))
+ end
+
notification.new_merge_request(merge_request, current_user)
end
def after_close(merge_request, transition)
- Note.create_status_change_note(merge_request, current_user, merge_request.state)
+ create_event(merge_request, Event::CLOSED)
+ Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state)
notification.close_mr(merge_request, current_user)
end
def after_merge(merge_request, transition)
notification.merge_mr(merge_request)
+ # Since MR can be merged via sidekiq
+ # to prevent event duplication do this check
+ return true if merge_request.merge_event
+
+ Event.create(
+ project: merge_request.target_project,
+ target_id: merge_request.id,
+ target_type: merge_request.class.name,
+ action: Event::MERGED,
+ author_id: merge_request.author_id_of_changes
+ )
end
def after_reopen(merge_request, transition)
- Note.create_status_change_note(merge_request, current_user, merge_request.state)
+ create_event(merge_request, Event::REOPENED)
+ Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state)
end
def after_update(merge_request)
notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned?
end
+
+
+ def create_event(record, status)
+ Event.create(
+ project: record.target_project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: status,
+ author_id: record.author_id
+ )
+ end
+
end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index f3dc552a8e7..75704e2eb0e 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -23,7 +23,7 @@ class NotificationService
# * project team members with notification level higher then Participating
#
def new_issue(issue, current_user)
- new_resource_email(issue, 'new_issue_email')
+ new_resource_email(issue, issue.project, 'new_issue_email')
end
# When we close an issue we should send next emails:
@@ -33,7 +33,7 @@ class NotificationService
# * project team members with notification level higher then Participating
#
def close_issue(issue, current_user)
- close_resource_email(issue, current_user, 'closed_issue_email')
+ close_resource_email(issue, issue.project, current_user, 'closed_issue_email')
end
# When we reassign an issue we should send next emails:
@@ -42,7 +42,7 @@ class NotificationService
# * issue new assignee if his notification level is not Disabled
#
def reassigned_issue(issue, current_user)
- reassign_resource_email(issue, current_user, 'reassigned_issue_email')
+ reassign_resource_email(issue, issue.project, current_user, 'reassigned_issue_email')
end
@@ -51,7 +51,7 @@ class NotificationService
# * mr assignee if his notification level is not Disabled
#
def new_merge_request(merge_request, current_user)
- new_resource_email(merge_request, 'new_merge_request_email')
+ new_resource_email(merge_request, merge_request.target_project, 'new_merge_request_email')
end
# When we reassign a merge_request we should send next emails:
@@ -60,7 +60,7 @@ class NotificationService
# * merge_request assignee if his notification level is not Disabled
#
def reassigned_merge_request(merge_request, current_user)
- reassign_resource_email(merge_request, current_user, 'reassigned_merge_request_email')
+ reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email')
end
# When we close a merge request we should send next emails:
@@ -70,7 +70,7 @@ class NotificationService
# * project team members with notification level higher then Participating
#
def close_mr(merge_request, current_user)
- close_resource_email(merge_request, current_user, 'closed_merge_request_email')
+ close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
end
# When we merge a merge request we should send next emails:
@@ -80,8 +80,10 @@ class NotificationService
# * project team members with notification level higher then Participating
#
def merge_mr(merge_request)
- recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.project)
- recipients = recipients.concat(project_watchers(merge_request.project)).uniq
+ recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.source_project)
+ recipients = recipients.concat(reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project))
+ recipients = recipients.concat(project_watchers(merge_request.source_project))
+ recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
recipients.each do |recipient|
mailer.merged_merge_request_email(recipient.id, merge_request.id)
@@ -102,7 +104,7 @@ class NotificationService
# ignore wall messages
return true unless note.noteable_type.present?
- opts = { noteable_type: note.noteable_type, project_id: note.project_id }
+ opts = {noteable_type: note.noteable_type, project_id: note.project_id}
if note.commit_id.present?
opts.merge!(commit_id: note.commit_id)
@@ -191,14 +193,14 @@ class NotificationService
end
end
- def new_resource_email(target, method)
+ def new_resource_email(target, project, method)
if target.respond_to?(:participants)
recipients = target.participants
else
recipients = []
end
- recipients = reject_muted_users(recipients, target.project)
- recipients = recipients.concat(project_watchers(target.project)).uniq
+ recipients = reject_muted_users(recipients, project)
+ recipients = recipients.concat(project_watchers(project)).uniq
recipients.delete(target.author)
recipients.each do |recipient|
@@ -206,9 +208,9 @@ class NotificationService
end
end
- def close_resource_email(target, current_user, method)
- recipients = reject_muted_users([target.author, target.assignee], target.project)
- recipients = recipients.concat(project_watchers(target.project)).uniq
+ def close_resource_email(target, project, current_user, method)
+ recipients = reject_muted_users([target.author, target.assignee], project)
+ recipients = recipients.concat(project_watchers(project)).uniq
recipients.delete(current_user)
recipients.each do |recipient|
@@ -216,14 +218,14 @@ class NotificationService
end
end
- def reassign_resource_email(target, current_user, method)
+ def reassign_resource_email(target, project, current_user, method)
recipients = User.where(id: [target.assignee_id, target.assignee_id_was])
# Add watchers to email list
- recipients = recipients.concat(project_watchers(target.project))
+ recipients = recipients.concat(project_watchers(project))
# reject users with disabled notifications
- recipients = reject_muted_users(recipients, target.project)
+ recipients = reject_muted_users(recipients, project)
# Reject me from recipients if I reassign an item
recipients.delete(current_user)
diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml
index de5634d3c55..a634365ff3e 100644
--- a/app/views/events/_event_last_push.html.haml
+++ b/app/views/events/_event_last_push.html.haml
@@ -9,6 +9,9 @@
= time_ago_in_words(event.created_at)
ago.
.pull-right
- = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-small" do
+ = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-new-mr" do
Create Merge Request
+ - if !event.project.nil? && event.project.forked?
+ = link_to new_mr_path_for_fork_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-small" do
+ Create Merge Request on fork
%hr
diff --git a/app/views/merge_requests/update_branches.js.haml b/app/views/merge_requests/update_branches.js.haml
new file mode 100644
index 00000000000..c9171622669
--- /dev/null
+++ b/app/views/merge_requests/update_branches.js.haml
@@ -0,0 +1,8 @@
+:plain
+ $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}");
+ $(".target_branch").trigger("liszt:updated");
+ $(".mr_target_commit").html("");
+
+
+
+
diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml
index 0c6c79e097a..306c1ff8f60 100644
--- a/app/views/notify/closed_merge_request_email.html.haml
+++ b/app/views/notify/closed_merge_request_email.html.haml
@@ -3,7 +3,7 @@
%p
= link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
%p
- Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
+ Projects:Branches: #{@merge_request.source_project.path_with_namespace}:#{@merge_request.source_branch} &rarr; #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}
%p
Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml
index ee4648e3d09..1c92e004ff6 100644
--- a/app/views/notify/closed_merge_request_email.text.haml
+++ b/app/views/notify/closed_merge_request_email.text.haml
@@ -1,8 +1,8 @@
= "Merge Request #{@merge_request.id} was closed by #{@updated_by.name}"
-Merge Request url: #{project_merge_request_url(@merge_request.project, @merge_request)}
+Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
-Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch}
+Project:Branches: #{@merge_request.source_project.path_with_namespace}/#{@merge_request.source_branch} - #{@merge_request.target_project.path_with_namespace}#{@merge_request.target_branch}
Author: #{@merge_request.author_name}
Assignee: #{@merge_request.assignee_name}
diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml
index 2b8cc030b23..4115adf1b42 100644
--- a/app/views/notify/merged_merge_request_email.html.haml
+++ b/app/views/notify/merged_merge_request_email.html.haml
@@ -1,9 +1,9 @@
%p
= "Merge Request #{@merge_request.id} was merged"
%p
- = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
+ = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
%p
- Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
+ Projects:Branches: #{@merge_request.source_project.path_with_namespace}:#{@merge_request.source_branch} &rarr; #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}
%p
Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml
index 91c23360195..5f19473fae0 100644
--- a/app/views/notify/merged_merge_request_email.text.haml
+++ b/app/views/notify/merged_merge_request_email.text.haml
@@ -1,8 +1,8 @@
= "Merge Request #{@merge_request.id} was merged"
-Merge Request Url: #{project_merge_request_url(@merge_request.project, @merge_request)}
+Merge Request Url: #{project_merge_request_url(@merge_request.target_project, @merge_request)}
-Branches: #{@merge_request.source_branch} - #{@merge_request.target_branch}
+Project:Branches: #{@merge_request.source_project.path_with_namespace}/#{@merge_request.source_branch} - #{@merge_request.target_project.path_with_namespace}#{@merge_request.target_branch}
Author: #{@merge_request.author_name}
Assignee: #{@merge_request.assignee_name}
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 0f1cfff5831..fc4ffba1102 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -1,9 +1,9 @@
%p
= "New Merge Request !#{@merge_request.id}"
%p
- = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.project, @merge_request)
+ = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
%p
- Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
+ Project:Branches: #{@merge_request.source_project.path_with_namespace}/#{@merge_request.source_branch} - #{@merge_request.target_project.path_with_namespace}#{@merge_request.target_branch}
%p
Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb
index 3393d8384f1..4c1a93f7dcc 100644
--- a/app/views/notify/new_merge_request_email.text.erb
+++ b/app/views/notify/new_merge_request_email.text.erb
@@ -1,9 +1,8 @@
New Merge Request <%= @merge_request.id %>
-<%= url_for(project_merge_request_url(@merge_request.project, @merge_request)) %>
-
+<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
-Branches: <%= @merge_request.source_branch %> to <%= @merge_request.target_branch %>
+From: <%= @merge_request.source_project.path_with_namespace%>:<%= @merge_request.source_branch %> to <%= @merge_request.target_project.path_with_namespace%>:<%= @merge_request.target_branch %>
Author: <%= @merge_request.author_name %>
Asignee: <%= @merge_request.assignee_name %>
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 4f97867e49d..14abcca6070 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,8 +1,8 @@
%p
- if @note.for_diff_line?
- = link_to "New comment on diff", diffs_project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
+ = link_to "New comment on diff", diffs_project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")
- else
- = link_to "New comment", project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
+ = link_to "New comment", project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")
for Merge Request ##{@merge_request.id}
%cite "#{truncate(@merge_request.title, length: 20)}"
= render 'note_message'
diff --git a/app/views/notify/note_merge_request_email.text.erb b/app/views/notify/note_merge_request_email.text.erb
index 26c73bdaa38..3daa091db81 100644
--- a/app/views/notify/note_merge_request_email.text.erb
+++ b/app/views/notify/note_merge_request_email.text.erb
@@ -1,6 +1,6 @@
New comment for Merge Request <%= @merge_request.id %>
-<%= url_for(project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")) %>
+<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")) %>
<%= @note.author_name %>
diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml
index 5ad72764e38..314b2882672 100644
--- a/app/views/notify/reassigned_merge_request_email.html.haml
+++ b/app/views/notify/reassigned_merge_request_email.html.haml
@@ -1,6 +1,6 @@
%p
= "Reassigned Merge Request !#{@merge_request.id}"
- = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.project, @merge_request)
+ = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.target_project, @merge_request)
%p
Assignee changed
- if @previous_assignee
diff --git a/app/views/notify/reassigned_merge_request_email.text.erb b/app/views/notify/reassigned_merge_request_email.text.erb
index 25b2a43fcdd..05a9797165d 100644
--- a/app/views/notify/reassigned_merge_request_email.text.erb
+++ b/app/views/notify/reassigned_merge_request_email.text.erb
@@ -1,6 +1,6 @@
Reassigned Merge Request <%= @merge_request.id %>
-<%= url_for(project_merge_request_url(@merge_request.project, @merge_request)) %>
+<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee %> to <%= @merge_request.assignee_name %>
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index eba6c206c46..eb5bdb886e2 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -1,12 +1,12 @@
%li.commit
.browse_code_link_holder
%p
- %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
+ %strong= link_to "Browse Code »", project_tree_path(project, commit), class: "right"
%p
- = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
+ = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id"
= commit_author_link(commit, avatar: true, size: 24)
&nbsp;
- = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title"
+ = link_to_gfm truncate(commit.title, length: 70), project_commit_path(project, commit.id), class: "row_title"
%time.committed_ago{ datetime: commit.committed_date, title: commit.committed_date.stamp("Aug 21, 2011 9:23pm") }
= time_ago_in_words(commit.committed_date)
@@ -14,7 +14,7 @@
&nbsp;
%span.notes_count
- - notes = @project.notes.for_commit_id(commit.id)
+ - notes = project.notes.for_commit_id(commit.id)
- if notes.any?
%span.badge.badge-info
%i.icon-comment
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index acdb8891344..d8b84aa5041 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -3,7 +3,6 @@
.title
%i.icon-calendar
%span= day.stamp("28 Aug, 2010")
-
.pull-right
%small= pluralize(commits.count, 'commit')
- %ul.well-list= render commits
+ %ul.well-list= render commits, :project => @project
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 5e6b5b71753..e18fd6cc093 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -15,7 +15,7 @@
%div.ui-box
.title
Commits (#{@commits.count})
- %ul.well-list= render Commit.decorate(@commits)
+ %ul.well-list= render Commit.decorate(@commits), project: @project
- unless @diffs.empty?
%h4 Diff
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index 86c442142bf..c378739c111 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |f|
+= form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |form_helper|
-if @merge_request.errors.any?
.alert.alert-error
%ul
@@ -12,18 +12,20 @@
.row
.span5
.light-well
- %h5.cgray From (Head Branch)
- = f.select(:source_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
+ %h5.cgray From
+ .padded= form_helper.select(:source_project_id,[[@merge_request.source_project.path_with_namespace,@merge_request.source_project.id]] , {}, {class: 'source_project chosen span4'})
+ .padded= form_helper.select(:source_branch, @merge_request.source_project.repository.branch_names, { include_blank: "Select branch" }, {class: 'source_branch chosen span4'})
.mr_source_commit.prepend-top-10
-
.span2
%h1.merge-request-angle
%i.icon-angle-right
.span5
.light-well
- %h5.cgray To (Base Branch)
- = f.select(:target_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
- .mr_target_commit.prepend-top-10
+ %h5.cgray To
+ - projects = @project.forked_from_project.nil? ? [@project] : [ @project,@project.forked_from_project]
+ .padded= form_helper.select(:target_project_id, projects.map { |proj| [proj.path_with_namespace,proj.id] }, {include_blank: "Select Target Project" }, {class: 'target_project chosen span4'})
+ .padded= form_helper.select(:target_branch, @target_branches, { include_blank: "Select branch" }, {class: 'target_branch chosen span4'})
+ .mr_target_commit.prepend-top-10
%hr
@@ -47,12 +49,11 @@
Milestone
.input= f.select(:milestone_id, @project.milestones.active.all.map {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
-
.form-actions
- if @merge_request.new_record?
- = f.submit 'Submit merge request', class: "btn btn-create"
+ = form_helper.submit 'Submit merge request', class: "btn btn-create"
-else
- = f.submit 'Save changes', class: "btn btn-save"
+ = form_helper.submit 'Save changes', class: "btn btn-save"
- if @merge_request.new_record?
= link_to project_merge_requests_path(@project), class: "btn btn-cancel" do
Cancel
@@ -63,16 +64,23 @@
:javascript
disableButtonIfEmptyField("#merge_request_title", ".btn-save");
- var source_branch = $("#merge_request_source_branch")
- , target_branch = $("#merge_request_target_branch");
+ var source_branch = $("#merge_request_source_branch")
+ , target_branch = $("#merge_request_target_branch")
+ , target_project = $("#merge_request_target_project_id");
- $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: source_branch.val() });
- $.get("#{branch_to_project_merge_requests_path(@project)}", {ref: target_branch.val() });
+ $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: source_branch.val() });
+ $.get("#{branch_to_project_merge_requests_path(@project)}", {target_project_id: target_project.val(),ref: target_branch.val() });
- source_branch.live("change", function() {
- $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: $(this).val() });
- });
+ target_project.live("change", function() {
+ $.get("#{update_branches_project_merge_requests_path(@project)}", {target_project_id: $(this).val() });
+ });
+ source_branch.live("change", function() {
+ $.get("#{branch_from_project_merge_requests_path(@project)}", {ref: $(this).val() });
+ });
+ target_branch.live("change", function() {
+ $.get("#{branch_to_project_merge_requests_path(@project)}", {target_project_id: target_project.val(),ref: $(this).val() });
+ });
- target_branch.live("change", function() {
- $.get("#{branch_to_project_merge_requests_path(@project)}", {ref: $(this).val() });
});
+
+
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index ffc6b8fda1e..84bdde756d4 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -1,18 +1,19 @@
%li{ class: mr_css_classes(merge_request) }
.merge-request-title
%span.light= "##{merge_request.id}"
- = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title"
+ = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.target_project, merge_request), class: "row_title"
- if merge_request.merged?
%small.pull-right
%i.icon-ok
= "MERGED"
- else
%span.pull-right
+ = "#{merge_request.source_project.path_with_namespace}/#{merge_request.source_branch}"
%i.icon-angle-right
- = merge_request.target_branch
+ = "#{merge_request.target_project.path_with_namespace}/#{merge_request.target_branch}"
.merge-request-info
- if merge_request.author
- authored by #{link_to_member(@project, merge_request.author)}
+ authored by #{link_to_member(merge_request.source_project, merge_request.author)}
- if merge_request.votes_count > 0
= render 'votes/votes_inline', votable: merge_request
- if merge_request.notes.any?
diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
index 0637fdcb72e..a680c708d63 100644
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ b/app/views/projects/merge_requests/branch_from.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".mr_source_commit").html("#{commit_to_html(@commit)}");
+ $(".mr_source_commit").html("#{commit_to_html(@commit, @project)}");
diff --git a/app/views/projects/merge_requests/branch_to.js.haml b/app/views/projects/merge_requests/branch_to.js.haml
index 974100d1ba7..f4e2886ee44 100644
--- a/app/views/projects/merge_requests/branch_to.js.haml
+++ b/app/views/projects/merge_requests/branch_to.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".mr_target_commit").html("#{commit_to_html(@commit)}");
+ $(".mr_target_commit").html("#{commit_to_html(@commit, @target_project)}");
diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml
index 40876d16ddd..7b0e67053a5 100644
--- a/app/views/projects/merge_requests/show/_commits.html.haml
+++ b/app/views/projects/merge_requests/show/_commits.html.haml
@@ -7,19 +7,19 @@
- if @commits.count > 8
%ul.first-commits.well-list
- @commits.first(8).each do |commit|
- = render "projects/commits/commit", commit: commit
+ = render "projects/commits/commit", commit: commit, project: @merge_request.source_project
%li.bottom
8 of #{@commits.count} commits displayed.
%strong
%a.show-all-commits Click here to show all
%ul.all-commits.hide.well-list
- @commits.each do |commit|
- = render "projects/commits/commit", commit: commit
+ = render "projects/commits/commit", commit: commit, project: @merge_request.source_project
- else
%ul.well-list
- @commits.each do |commit|
- = render "projects/commits/commit", commit: commit
+ = render "projects/commits/commit", commit: commit, project: @merge_request.source_project
- else
%h4.nothing_here_message
diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
index 7f1e33418de..a0eb2309585 100644
--- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
@@ -3,17 +3,49 @@
%a.close{href: "#"} ×
%h3 How To Merge
.modal-body
- %p
- %strong Step 1.
- Checkout target branch and get recent objects from GitLab
- %pre.dark
- :preserve
- git checkout #{@merge_request.target_branch}
- git fetch origin
- %p
- %strong Step 2.
- Merge source branch into target branch and push changes to GitLab
- %pre.dark
- :preserve
- git merge origin/#{@merge_request.source_branch}
- git push origin #{@merge_request.target_branch}
+ - if @merge_request.for_fork?
+ - source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path
+ - target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path
+ %p
+ %strong Step 1.
+ Checkout target branch and get recent objects from GitLab
+ Assuming remote for #{@merge_request.target_project.path_with_namespace} is called #{target_remote}
+ remote for #{@merge_request.source_project.path_with_namespace} is called #{source_remote}
+ %pre.dark
+ :preserve
+ git checkout #{target_remote} #{@merge_request.target_branch}
+ git fetch #{source_remote}
+ %p
+ %strong Step 2.
+ Merge source branch into target branch and push changes to GitLab
+ %pre.dark
+ :preserve
+ git merge #{source_remote}/#{@merge_request.source_branch}
+ git push #{target_remote} #{@merge_request.target_branch}
+ - else
+ %p
+ %strong Step 1.
+ Checkout target branch and get recent objects from GitLab
+ %pre.dark
+ :preserve
+ git checkout #{@merge_request.target_branch}
+ git fetch origin
+ %p
+ %strong Step 2.
+ Merge source branch into target branch and push changes to GitLab
+ %pre.dark
+ :preserve
+ git merge origin/#{@merge_request.source_branch}
+ git push origin #{@merge_request.target_branch}
+
+
+:javascript
+ $(function(){
+ var modal = $('#modal_merge_info').modal({modal: true, show:false});
+ $('.how_to_merge_link').bind("click", function(){
+ modal.show();
+ });
+ $('.modal-header .close').bind("click", function(){
+ modal.hide();
+ })
+ })
diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml
index 01378d99c99..47db8cdc8d2 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -15,7 +15,7 @@
for instructions
.accept_group
= f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request"
- - unless @project.root_ref? @merge_request.source_branch
+ - unless @merge_request.disallow_source_branch_removal?
.remove_branch_holder
= label_tag :should_remove_source_branch, class: "checkbox" do
= check_box_tag :should_remove_source_branch
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index 5a07258f91c..2c31c2dbf31 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -1,8 +1,10 @@
%h3.page-title
= "Merge Request ##{@merge_request.id}:"
&nbsp;
+ %span.label-project= @merge_request.source_project.path_with_namespace
%span.label-branch= @merge_request.source_branch
&rarr;
+ %span.label-project= @merge_request.target_project.path_with_namespace
%span.label-branch= @merge_request.target_branch
%span.pull-right
diff --git a/app/views/search/_result.html.haml b/app/views/search/_result.html.haml
index 4e56eea084e..064c683e3d7 100644
--- a/app/views/search/_result.html.haml
+++ b/app/views/search/_result.html.haml
@@ -22,11 +22,11 @@
- @merge_requests.each do |merge_request|
%li
merge request:
- = link_to [merge_request.project, merge_request] do
+ = link_to [merge_request.target_project, merge_request] do
%span ##{merge_request.id}
%strong.term
= truncate merge_request.title, length: 50
- %span.light (#{merge_request.project.name_with_namespace})
+ %span.light (#{merge_request.source_project.name_with_namespace}:#{merge_request.source_branch} &rarr; #{merge_request.target_project.name_with_namespace}:#{merge_request.target_branch})
- @issues.each do |issue|
%li
issue:
diff --git a/app/views/shared/_merge_requests.html.haml b/app/views/shared/_merge_requests.html.haml
index 935a7a7f7c0..5276f4bae31 100644
--- a/app/views/shared/_merge_requests.html.haml
+++ b/app/views/shared/_merge_requests.html.haml
@@ -1,5 +1,5 @@
- if @merge_requests.any?
- - @merge_requests.group_by(&:project).each do |group|
+ - @merge_requests.group_by(&:target_project).each do |group|
.ui-box
- project = group[0]
.title