Commit 4773f38e authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'improve-merge-requests' into 'master'

Improve merge requests

- [x] Fetch merge request refs by IID
- [x] Ability to fetch any merge request
- [x] Link commits and diffs in merge request to target project
- [x] Improve merge request UI and command line instructions
- [x] Check merge request widget loading test coverage double

See merge request !1115
parents 0d5d80b7 fd2f907b
...@@ -49,10 +49,8 @@ class @MergeRequestWidget ...@@ -49,10 +49,8 @@ class @MergeRequestWidget
@setMergeButtonClass('btn-danger') @setMergeButtonClass('btn-danger')
showCiCoverage: (coverage) -> showCiCoverage: (coverage) ->
cov_html = $('<span>') text = 'Coverage ' + coverage + '%'
cov_html.addClass('ci-coverage') $('.ci_widget:visible .ci-coverage').text(text)
cov_html.text('Coverage ' + coverage + '%')
$('.ci_widget:visible').append(cov_html)
setMergeButtonClass: (css_class) -> setMergeButtonClass: (css_class) ->
$('.accept_merge_request').removeClass("btn-create").addClass(css_class) $('.accept_merge_request').removeClass("btn-create").addClass(css_class)
/**
/** * MR -> show: Automerge widget
* MR -> show: Automerge widget
* *
*/ */
.mr-state-widget { .mr-state-widget {
background: #FAFAFA;
margin-bottom: 20px;
color: #666;
border: 1px solid #e5e5e5;
@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
@include border-radius(3px);
form { form {
margin-bottom: 0; margin-bottom: 0;
.clearfix { .clearfix {
...@@ -20,16 +26,67 @@ ...@@ -20,16 +26,67 @@
display: inline-block; display: inline-block;
margin: 0; margin: 0;
margin-left: 20px; margin-left: 20px;
padding: 10px 0; padding: 5px;
line-height: 20px; line-height: 20px;
font-weight: bold;
.remove_source_checkbox { .remove_source_checkbox {
margin: 0; margin: 0;
font-weight: bold;
} }
} }
} }
.ci_widget {
border-bottom: 1px solid #EEE;
i {
margin-right: 4px;
}
&.ci-success {
color: $gl-success;
}
&.ci-skipped {
background-color: #eee;
color: #888;
}
&.ci-pending,
&.ci-running {
color: $gl-warning;
}
&.ci-failed,
&.ci-canceled,
&.ci-error {
color: $gl-danger;
}
}
.mr-widget-body,
.ci_widget,
.mr-widget-footer {
padding: 15px;
}
.mr-widget-body {
h4 {
font-weight: bold;
margin: 5px 0;
}
p:last-child {
margin-bottom: 0;
}
}
.mr-widget-footer {
border-top: 1px solid #EEE;
}
.ci-coverage {
float: right;
}
} }
@media(min-width: $screen-sm-max) { @media(min-width: $screen-sm-max) {
...@@ -58,23 +115,10 @@ ...@@ -58,23 +115,10 @@
} }
.label-branch { .label-branch {
@include border-radius(4px); color: #222;
padding: 3px 4px;
border: none;
background: $hover;
color: #333;
font-family: $monospace_font; font-family: $monospace_font;
font-weight: normal; font-weight: bold;
overflow: hidden; overflow: hidden;
.label-project {
@include border-radius-left(4px);
padding: 3px 4px;
background: #279;
position: relative;
left: -4px;
letter-spacing: -1px;
}
} }
.mr-list { .mr-list {
...@@ -121,64 +165,6 @@ ...@@ -121,64 +165,6 @@
display: none; display: none;
} }
.mr-state-widget {
font-size: 13px;
background: #FAFAFA;
margin-bottom: 20px;
color: #666;
border: 1px solid #e5e5e5;
@include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
@include border-radius(3px);
.ci_widget {
padding: 10px 15px;
font-size: 15px;
border-bottom: 1px solid #EEE;
&.ci-success {
color: $gl-success;
}
&.ci-skipped {
background-color: #eee;
color: #888;
}
&.ci-pending,
&.ci-running {
color: $gl-warning;
}
&.ci-failed,
&.ci-canceled,
&.ci-error {
color: $gl-danger;
}
}
.mr-widget-body {
padding: 10px 15px;
h4 {
font-weight: bold;
margin: 5px 0;
}
p:last-child {
margin-bottom: 0;
}
}
.mr-widget-footer {
padding: 10px 15px;
border-top: 1px solid #EEE;
}
.ci-coverage {
float: right;
}
}
.merge-request-show-labels { .merge-request-show-labels {
a { a {
margin-right: 5px; margin-right: 5px;
......
...@@ -61,4 +61,14 @@ module MergeRequestsHelper ...@@ -61,4 +61,14 @@ module MergeRequestsHelper
} }
) )
end end
def source_branch_with_namespace(merge_request)
if merge_request.for_fork?
namespace = link_to(merge_request.source_project_namespace,
project_path(merge_request.source_project))
namespace + ":#{merge_request.source_branch}"
else
merge_request.source_branch
end
end
end end
...@@ -432,7 +432,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -432,7 +432,7 @@ class MergeRequest < ActiveRecord::Base
target_project.repository.fetch_ref( target_project.repository.fetch_ref(
source_project.repository.path_to_repo, source_project.repository.path_to_repo,
"refs/heads/#{source_branch}", "refs/heads/#{source_branch}",
"refs/merge-requests/#{id}/head" "refs/merge-requests/#{iid}/head"
) )
end end
......
...@@ -161,8 +161,8 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -161,8 +161,8 @@ class MergeRequestDiff < ActiveRecord::Base
def compare_result def compare_result
@compare_result ||= @compare_result ||=
begin begin
# Update ref if merge request is from fork # Update ref for merge request
merge_request.fetch_ref if merge_request.for_fork? merge_request.fetch_ref
# Get latest sha of branch from source project # Get latest sha of branch from source project
source_sha = merge_request.source_project.commit(source_branch).sha source_sha = merge_request.source_project.commit(source_branch).sha
......
...@@ -6,40 +6,25 @@ ...@@ -6,40 +6,25 @@
= render "projects/merge_requests/show/mr_box" = render "projects/merge_requests/show/mr_box"
%hr %hr
.append-bottom-20 .append-bottom-20
.slead - if @merge_request.open?
%span From .btn-group.btn-group-sm.pull-right
- if @merge_request.for_fork? %a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} }
%strong.label-branch< = icon('download')
- if @merge_request.source_project Download as
= link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project) %span.caret
- else %ul.dropdown-menu
\ #{@merge_request.source_project_namespace} %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
\:#{@merge_request.source_branch} %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
.light
%div
%span From
%span.label-branch #{source_branch_with_namespace(@merge_request)}
%span into %span into
%strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} %span.label-branch #{@merge_request.target_branch}
- else - if @merge_request.open? && !@merge_request.branch_missing?
%strong.label-branch #{@merge_request.source_branch} %div
%span into If you want to try or merge this request manually, you can use the
%strong.label-branch #{@merge_request.target_branch} = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- if @merge_request.open?
.btn-group.btn-group-sm.pull-right
%a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} }
= icon('download')
Download as
%span.caret
%ul.dropdown-menu
%li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
%li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
- if @merge_request.open? and @merge_request.source_branch_exists?
.append-bottom-20
.slead
%span
Fetch the branch with
%strong.label-branch<
git fetch
\ #{@merge_request.source_project.http_url_to_repo}
\ #{@merge_request.source_branch}
= render "projects/merge_requests/show/how_to_merge" = render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/widget/show.html.haml" = render "projects/merge_requests/widget/show.html.haml"
......
= render "projects/commits/commits", project: @merge_request.source_project = render "projects/commits/commits", project: @merge_request.project
- if @merge_request_diff.collected? - if @merge_request_diff.collected?
= render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.project
- elsif @merge_request_diff.empty? - elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else - else
......
- if @merge_request.has_ci? - if @merge_request.has_ci?
.mr-widget-heading .mr-widget-heading
.ci_widget.ci-success{style: "display:none"} - [:success, :skipped, :canceled, :failed, :running, :pending].each do |status|
= icon("check")
%span CI build passed
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-skipped{style: "display:none"}
= icon("check")
%span CI build skipped
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-failed{style: "display:none"}
= icon("times")
%span CI build failed
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
- [:running, :pending].each do |status|
.ci_widget{class: "ci-#{status}", style: "display:none"} .ci_widget{class: "ci-#{status}", style: "display:none"}
= icon("clock-o") - if status == :success
= icon("check-circle")
- else
= icon("circle")
%span CI build #{status} %span CI build #{status}
for #{@merge_request.last_commit_short_sha}. for #{@merge_request.last_commit_short_sha}.
%span.ci-coverage
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget .ci_widget
...@@ -30,19 +16,12 @@ ...@@ -30,19 +16,12 @@
Checking for CI status for #{@merge_request.last_commit_short_sha} Checking for CI status for #{@merge_request.last_commit_short_sha}
.ci_widget.ci-not_found{style: "display:none"} .ci_widget.ci-not_found{style: "display:none"}
= icon("times") = icon("times-circle")
%span Can not find commit in the CI server %span Can not find commit in the CI server
for #{@merge_request.last_commit_short_sha}. for #{@merge_request.last_commit_short_sha}.
.ci_widget.ci-canceled{style: "display:none"}
= icon("times")
%span CI build canceled
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-error{style: "display:none"} .ci_widget.ci-error{style: "display:none"}
= icon("times") = icon("times-circle")
%span Cannot connect to the CI server. Please check your settings and try again. %span Cannot connect to the CI server. Please check your settings and try again.
:coffeescript :coffeescript
......
...@@ -18,12 +18,6 @@ ...@@ -18,12 +18,6 @@
text: @merge_request.merge_commit_message, text: @merge_request.merge_commit_message,
rows: 14, hint: true rows: 14, hint: true
%br
.light
If you want to merge this request manually, you can use the
%strong
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
:coffeescript :coffeescript
$('.accept-mr-form').on 'ajax:before', -> $('.accept-mr-form').on 'ajax:before', ->
btn = $('.accept_merge_request') btn = $('.accept_merge_request')
......
%h4
This merge request contains merge conflicts that must be resolved.
- if @merge_request.can_be_merged_by?(current_user) - if @merge_request.can_be_merged_by?(current_user)
%h4
This merge request contains merge conflicts that must be resolved.
%p %p
You can merge it manually using the You can merge it manually using the
%strong %strong
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- else - else
%strong This merge request contains merge conflicts that must be resolved. %p
Only those with write access to this repository can merge merge requests. Only those with write access to this repository can merge merge requests.
...@@ -13,4 +13,5 @@ ...@@ -13,4 +13,5 @@
- [Project users](add-user/add-user.md) - [Project users](add-user/add-user.md)
- [Protected branches](protected_branches.md) - [Protected branches](protected_branches.md)
- [Web Editor](web_editor.md) - [Web Editor](web_editor.md)
- [Merge Requests](merge_requests.md)
- ["Work In Progress" Merge Requests](wip_merge_requests.md) - ["Work In Progress" Merge Requests](wip_merge_requests.md)
# Merge Requests
Merge requests allow you to exchange changes you made to source code
## Checkout merge requests locally
Locate the section for your GitLab remote in the `.git/config` file. It looks like this:
```
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-ce.git
fetch = +refs/heads/*:refs/remotes/origin/*
```
Now add the line `fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*` to this section.
It should looks like this:
```
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-ce.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
```
Now you can fetch all the merge requests requests:
```
$ git fetch origin
From https://gitlab.com/gitlab-org/gitlab-ce.git
* [new ref] refs/merge-requests/1/head -> origin/merge-requests/1
* [new ref] refs/merge-requests/2/head -> origin/merge-requests/2
...
```
To check out a particular merge request:
```
$ git checkout origin/merge-requests/1
```
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment