Commit 9ef46892 authored by Rubén Dávila's avatar Rubén Dávila

Merge branch 'master' into issue_5546

parents 7c520c78 3982219d
# This file is generated by GitLab CI image: "ruby:2.1"
services:
- mysql:latest
- postgres:latest
- redis:latest
variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
before_script: before_script:
- ./scripts/prepare_build.sh - ./scripts/prepare_build.sh
- ruby -v - ruby -v
......
...@@ -3,8 +3,10 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -3,8 +3,10 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.5.0 (unreleased) v 8.5.0 (unreleased)
- Add "visibility" flag to GET /projects api endpoint - Add "visibility" flag to GET /projects api endpoint
- Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push - Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push
- New UI for pagination
- Fix diff comments loaded by AJAX to load comment with diff in discussion tab
v 8.4.0 (unreleased) v 8.4.0
- Allow LDAP users to change their email if it was not set by the LDAP server - Allow LDAP users to change their email if it was not set by the LDAP server
- Ensure Gravatar host looks like an actual host - Ensure Gravatar host looks like an actual host
- Consider re-assign as a mention from a notification point of view - Consider re-assign as a mention from a notification point of view
...@@ -14,6 +16,7 @@ v 8.4.0 (unreleased) ...@@ -14,6 +16,7 @@ v 8.4.0 (unreleased)
- Autocomplete data is now always loaded, instead of when focusing a comment text area - Autocomplete data is now always loaded, instead of when focusing a comment text area
- Improved performance of finding issues for an entire group - Improved performance of finding issues for an entire group
- Added custom application performance measuring system powered by InfluxDB - Added custom application performance measuring system powered by InfluxDB
- Add syntax highlighting to diffs
- Gracefully handle invalid UTF-8 sequences in Markdown links (Stan Hu) - Gracefully handle invalid UTF-8 sequences in Markdown links (Stan Hu)
- Bump fog to 1.36.0 (Stan Hu) - Bump fog to 1.36.0 (Stan Hu)
- Add user's last used IP addresses to admin page (Stan Hu) - Add user's last used IP addresses to admin page (Stan Hu)
...@@ -74,6 +77,7 @@ v 8.4.0 (unreleased) ...@@ -74,6 +77,7 @@ v 8.4.0 (unreleased)
- Fix: Creator should be added as a master of the project on creation - Fix: Creator should be added as a master of the project on creation
- Added X-GitLab-... headers to emails from CI and Email On Push services (Anton Baklanov) - Added X-GitLab-... headers to emails from CI and Email On Push services (Anton Baklanov)
- Add IP check against DNSBLs at account sign-up - Add IP check against DNSBLs at account sign-up
- Added cache:key to .gitlab-ci.yml allowing to fine tune the caching
v 8.3.4 v 8.3.4
- Use gitlab-workhorse 0.5.4 (fixes API routing bug) - Use gitlab-workhorse 0.5.4 (fixes API routing bug)
......
File mode changed from 100644 to 100755
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
class @BuildArtifacts
constructor: () ->
@disablePropagation()
@setupEntryClick()
disablePropagation: ->
$('.top-block').on 'click', '.download', (e) ->
e.stopPropagation()
$('.tree-holder').on 'click', 'tr[data-link] a', (e) ->
e.stopImmediatePropagation()
setupEntryClick: ->
$('.tree-holder').on 'click', 'tr[data-link]', (e) ->
window.location = @dataset.link
...@@ -100,6 +100,8 @@ class Dispatcher ...@@ -100,6 +100,8 @@ class Dispatcher
shortcut_handler = true shortcut_handler = true
when 'projects:forks:new' when 'projects:forks:new'
new ProjectFork() new ProjectFork()
when 'projects:artifacts:browse'
new BuildArtifacts()
when 'users:show' when 'users:show'
new User() new User()
new Activities() new Activities()
......
...@@ -15,6 +15,8 @@ class @Notes ...@@ -15,6 +15,8 @@ class @Notes
@last_fetched_at = last_fetched_at @last_fetched_at = last_fetched_at
@view = view @view = view
@noteable_url = document.URL @noteable_url = document.URL
@notesCountBadge ||= $(".issuable-details").find(".notes-tab .badge")
@initRefresh() @initRefresh()
@setupMainTargetNoteForm() @setupMainTargetNoteForm()
@cleanBinding() @cleanBinding()
...@@ -89,7 +91,7 @@ class @Notes ...@@ -89,7 +91,7 @@ class @Notes
, 15000 , 15000
refresh: -> refresh: ->
unless document.hidden or (@noteable_url != document.URL) if not document.hidden and document.URL.indexOf(@noteable_url) is 0
@getContent() @getContent()
getContent: -> getContent: ->
...@@ -101,7 +103,10 @@ class @Notes ...@@ -101,7 +103,10 @@ class @Notes
notes = data.notes notes = data.notes
@last_fetched_at = data.last_fetched_at @last_fetched_at = data.last_fetched_at
$.each notes, (i, note) => $.each notes, (i, note) =>
@renderNote(note) if note.discussion_with_diff_html?
@renderDiscussionNote(note)
else
@renderNote(note)
### ###
...@@ -116,18 +121,21 @@ class @Notes ...@@ -116,18 +121,21 @@ class @Notes
flash.pinTo('.header-content') flash.pinTo('.header-content')
return return
if note.award
awards_handler.addAwardToEmojiBar(note.note)
awards_handler.scrollToAwards()
# render note if it not present in loaded list # render note if it not present in loaded list
# or skip if rendered # or skip if rendered
if @isNewNote(note) && !note.award else if @isNewNote(note)
@note_ids.push(note.id) @note_ids.push(note.id)
$('ul.main-notes-list').
append(note.html). $('ul.main-notes-list')
syntaxHighlight() .append(note.html)
.syntaxHighlight()
@initTaskList() @initTaskList()
@updateNotesCount(1)
if note.award
awards_handler.addAwardToEmojiBar(note.note)
awards_handler.scrollToAwards()
### ###
Check if note does not exists on page Check if note does not exists on page
...@@ -144,34 +152,39 @@ class @Notes ...@@ -144,34 +152,39 @@ class @Notes
Note: for rendering inline notes use renderDiscussionNote Note: for rendering inline notes use renderDiscussionNote
### ###
renderDiscussionNote: (note) -> renderDiscussionNote: (note) ->
return unless @isNewNote(note)
@note_ids.push(note.id) @note_ids.push(note.id)
form = $("form[rel='" + note.discussion_id + "']") form = $("#new-discussion-note-form-#{note.discussion_id}")
row = form.closest("tr") row = form.closest("tr")
note_html = $(note.html) note_html = $(note.html)
note_html.syntaxHighlight() note_html.syntaxHighlight()
# is this the first note of discussion? # is this the first note of discussion?
if row.is(".js-temp-notes-holder") discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']")
if discussionContainer.length is 0
# insert the note and the reply button after the temp row # insert the note and the reply button after the temp row
row.after note.discussion_html row.after note.discussion_html
# remove the note (will be added again below) # remove the note (will be added again below)
row.next().find(".note").remove() row.next().find(".note").remove()
# Before that, the container didn't exist
discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']")
# Add note to 'Changes' page discussions # Add note to 'Changes' page discussions
$(".notes[rel='" + note.discussion_id + "']").append note_html discussionContainer.append note_html
# Init discussion on 'Discussion' page if it is merge request page # Init discussion on 'Discussion' page if it is merge request page
if $('body').attr('data-page').indexOf('projects:merge_request') == 0 if $('body').attr('data-page').indexOf('projects:merge_request') is 0
discussion_html = $(note.discussion_with_diff_html) $('ul.main-notes-list')
discussion_html.syntaxHighlight() .append(note.discussion_with_diff_html)
$('ul.main-notes-list').append(discussion_html) .syntaxHighlight()
else else
# append new note to all matching discussions # append new note to all matching discussions
$(".notes[rel='" + note.discussion_id + "']").append note_html discussionContainer.append note_html
# cleanup after successfully creating a diff/discussion note @updateNotesCount(1)
@removeDiscussionNoteForm(form)
### ###
Called in response the main target form has been successfully submitted. Called in response the main target form has been successfully submitted.
...@@ -278,6 +291,9 @@ class @Notes ...@@ -278,6 +291,9 @@ class @Notes
addDiscussionNote: (xhr, note, status) => addDiscussionNote: (xhr, note, status) =>
@renderDiscussionNote(note) @renderDiscussionNote(note)
# cleanup after successfully creating a diff/discussion note
@removeDiscussionNoteForm($("#new-discussion-note-form-#{note.discussion_id}"))
### ###
Called in response to the edit note form being submitted Called in response to the edit note form being submitted
...@@ -349,30 +365,32 @@ class @Notes ...@@ -349,30 +365,32 @@ class @Notes
Removes the actual note from view. Removes the actual note from view.
Removes the whole discussion if the last note is being removed. Removes the whole discussion if the last note is being removed.
### ###
removeNote: -> removeNote: (e) =>
note = $(this).closest(".note") noteId = $(e.currentTarget)
note_id = note.attr('id') .closest(".note")
.attr("id")
$('.note[id="' + note_id + '"]').each -> # A same note appears in the "Discussion" and in the "Changes" tab, we have
note = $(this) # to remove all. Using $(".note[id='noteId']") ensure we get all the notes,
# where $("#noteId") would return only one.
$(".note[id='#{noteId}']").each (i, el) =>
note = $(el)
notes = note.closest(".notes") notes = note.closest(".notes")
count = notes.closest(".issuable-details").find(".notes-tab .badge")
# check if this is the last note for this line # check if this is the last note for this line
if notes.find(".note").length is 1 if notes.find(".note").length is 1
# for discussions # "Discussions" tab
notes.closest(".discussion").remove() notes.closest(".timeline-entry").remove()
# for diff lines # "Changes" tab / commit view
notes.closest("tr").remove() notes.closest("tr").remove()
# update notes count
oldNum = parseInt(count.text())
count.text(oldNum - 1)
note.remove() note.remove()
# Decrement the "Discussions" counter only once
@updateNotesCount(-1)
### ###
Called in response to clicking the delete attachment link Called in response to clicking the delete attachment link
...@@ -412,7 +430,7 @@ class @Notes ...@@ -412,7 +430,7 @@ class @Notes
### ###
setupDiscussionNoteForm: (dataHolder, form) => setupDiscussionNoteForm: (dataHolder, form) =>
# setup note target # setup note target
form.attr "rel", dataHolder.data("discussionId") form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}"
form.find("#line_type").val dataHolder.data("lineType") form.find("#line_type").val dataHolder.data("lineType")
form.find("#note_commit_id").val dataHolder.data("commitId") form.find("#note_commit_id").val dataHolder.data("commitId")
form.find("#note_line_code").val dataHolder.data("lineCode") form.find("#note_line_code").val dataHolder.data("lineCode")
...@@ -542,3 +560,6 @@ class @Notes ...@@ -542,3 +560,6 @@ class @Notes
updateTaskList: -> updateTaskList: ->
$('form', this).submit() $('form', this).submit()
updateNotesCount: (updateCount) ->
@notesCountBadge.text(parseInt(@notesCountBadge.text()) + updateCount)
...@@ -120,14 +120,6 @@ span.update-author { ...@@ -120,14 +120,6 @@ span.update-author {
display: inline; display: inline;
} }
.line_holder {
&:hover {
td {
background: #FFFFCF !important;
}
}
}
p.time { p.time {
color: #999; color: #999;
font-size: 90%; font-size: 90%;
......
...@@ -92,15 +92,6 @@ ...@@ -92,15 +92,6 @@
&:last-child { &:last-child {
border-right: none; border-right: none;
} }
background: #fff;
}
.lines {
pre {
padding: 0;
margin: 0;
background: none;
border: none;
}
} }
img.avatar { img.avatar {
border: 0 none; border: 0 none;
...@@ -116,18 +107,18 @@ ...@@ -116,18 +107,18 @@
color: #888; color: #888;
} }
} }
td.blame-numbers { td.line-numbers {
pre { float: none;
color: #AAA;
white-space: pre;
}
background: #f1f1f1;
border-left: 1px solid #DDD; border-left: 1px solid #DDD;
} }
td.lines { td.lines {
padding: 0;
code { code {
font-family: $monospace_font; font-family: $monospace_font;
} }
pre {
margin: 0;
}
} }
} }
......
...@@ -53,3 +53,14 @@ ...@@ -53,3 +53,14 @@
color: #333; color: #333;
} }
} }
.ui-sortable-handle {
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
&:active {
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
}
.gl-pagination { .gl-pagination {
text-align: center;
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
background-color: $background-color; margin: 0;
margin: -$gl-padding;
margin-top: 0; margin-top: 0;
.pagination { .pagination {
padding: 0; padding: 0;
margin: 0;
display: block;
li.first,
li.last,
li.next,
li.prev {
> a {
color: $link-color;
&:hover {
color: #fff;
}
}
}
li > a,
li > span {
border: none;
margin: 0;
@include border-radius(0 !important);
padding: 13px 19px;
border-right: 1px solid $border-color;
}
} }
} }
......
...@@ -66,20 +66,20 @@ $legend-color: $text-color; ...@@ -66,20 +66,20 @@ $legend-color: $text-color;
//## //##
$pagination-color: $gl-gray; $pagination-color: $gl-gray;
$pagination-bg: $background-color; $pagination-bg: #fff;
$pagination-border: transparent; $pagination-border: $border-color;
$pagination-hover-color: #fff; $pagination-hover-color: $gl-gray;
$pagination-hover-bg: $brand-info; $pagination-hover-bg: $hover;
$pagination-hover-border: transparent; $pagination-hover-border: $border-color;
$pagination-active-color: #fff; $pagination-active-color: $blue-dark;
$pagination-active-bg: $brand-info; $pagination-active-bg: #fff;
$pagination-active-border: transparent; $pagination-active-border: $border-color;
$pagination-disabled-color: #fff; $pagination-disabled-color: #cdcdcd;
$pagination-disabled-bg: lighten($brand-info, 15%); $pagination-disabled-bg: $background-color;
$pagination-disabled-border: transparent; $pagination-disabled-border: $border-color;
//== Form states and alerts //== Form states and alerts
......
/* https://github.com/MozMorris/tomorrow-pygments */ /* https://github.com/MozMorris/tomorrow-pygments */
.code.dark { .code.dark {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #1d1f21;
}
background-color: #1d1f21 !important; .diff-line-num, .diff-line-num a {
color: #c5c8c6 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #1d1f21 !important;
color: #c5c8c6 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #666; border-left: 1px solid #666;
} }
&, pre.code, .line_holder .line_content {
background-color: #1d1f21;
color: #c5c8c6;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(51, 255, 51, 0.1), rgba(51, 255, 51, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(255, 51, 51, 0.2), rgba(255, 51, 51, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #557 !important; background-color: #557 !important;
......
/* https://github.com/richleland/pygments-css/blob/master/monokai.css */ /* https://github.com/richleland/pygments-css/blob/master/monokai.css */
.code.monokai { .code.monokai {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #272822;
}
background-color: #272822 !important; .diff-line-num, .diff-line-num a {
color: #f8f8f2 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color :#272822 !important;
color: #f8f8f2 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #555; border-left: 1px solid #555;
} }
&, pre.code, .line_holder .line_content {
background-color: #272822;
color: #f8f8f2;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(166, 226, 46, 0.2), rgba(166, 226, 46, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(254, 147, 140, 0.2), rgba(254, 147, 140, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #49483e !important; background-color: #49483e !important;
......
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
.code.solarized-dark { .code.solarized-dark {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #002b36;
}
background-color: #002b36 !important; .diff-line-num, .diff-line-num a {
color: #93a1a1 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #002b36 !important;
color: #93a1a1 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #113b46; border-left: 1px solid #113b46;
} }
&, pre.code, .line_holder .line_content {
background-color: #002b36;
color: #93a1a1;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #174652 !important; background-color: #174652 !important;
......
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
.code.solarized-light { .code.solarized-light {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #fdf6e3;
}
background-color: #fdf6e3 !important; .diff-line-num, .diff-line-num a {
color: #586e75 !important; color: rgba(0, 0, 0, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #fdf6e3 !important;
color: #586e75 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #c5d0d4; border-left: 1px solid #c5d0d4;
} }
&, pre.code, .line_holder .line_content {
background-color: #fdf6e3;
color: #586e75;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #FAF3DD);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.3), #FAF3DD);
}
.line_content.match {
color: rgba(0, 0, 0, 0.3);
background: rgba(255, 255, 255, 0.4);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #ddd8c5 !important; background-color: #ddd8c5 !important;
......
/* https://github.com/aahan/pygments-github-style */ /* https://github.com/aahan/pygments-github-style */
.code.white { .code.white {
// Line numbers
.line-numbers, .diff-line-num {
background-color: $background-color;
}
background-color: #f8fafc !important; .diff-line-num, .diff-line-num a {
color: #5b6169 !important; color: rgba(0, 0, 0, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: $background-color !important;
color: $gl-gray !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
background-color: #fff !important; }
color: #333 !important;
&, pre.code, .line_holder .line_content {
background-color: #fff;
color: #333;
}
// Diff line
.line_holder {
.diff-line-num {
&.old {
background: #ffdddd;
border-color: #f1c0c0;
}
&.new {
background: #dbffdb;
border-color: #c1e9c1;
}
}
.line_content {
&.old {
background: #ffecec;
span.idiff {
background-color: #f8cbcb;
}
}
&.new {
background: #eaffea;
span.idiff {
background-color: #a6f3a6;
}
}
&.match {
color: rgba(0, 0, 0, 0.3);
background: #fafafa;
}
}
} }
// highlight line via anchor // highlight line via anchor
......
...@@ -32,16 +32,6 @@ ...@@ -32,16 +32,6 @@
background: #FFF; background: #FFF;
color: #333; color: #333;
.old {
span.idiff {
background-color: #f8cbcb;
}
}
.new {
span.idiff {
background-color: #a6f3a6;
}
}
.unfold { .unfold {
cursor: pointer; cursor: pointer;
} }
...@@ -76,7 +66,7 @@ ...@@ -76,7 +66,7 @@
} }
tr.line_holder.parallel { tr.line_holder.parallel {
.old_line, .new_line, .diff_line { .old_line, .new_line {
min-width: 50px; min-width: 50px;
} }
...@@ -85,7 +75,7 @@ ...@@ -85,7 +75,7 @@
} }
} }
.old_line, .new_line, .diff_line { .old_line, .new_line {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: none; border: none;
...@@ -107,43 +97,12 @@ ...@@ -107,43 +97,12 @@
text-decoration: underline; text-decoration: underline;
} }
} }
&.new {
background: #CFD;
}
&.old {
background: #FDD;
}
}
.diff_line {
padding: 0;
}
.line_holder {
&.old .old_line,
&.old .new_line {
background: #ffdddd;
border-color: #f1c0c0;
}
&.new .old_line,
&.new .new_line {
background: #dbffdb;
border-color: #c1e9c1;
}
} }
.line_content { .line_content {
display: block; display: block;
margin: 0px; margin: 0px;
padding: 0px 0.5em; padding: 0px 0.5em;
border: none; border: none;
&.new {
background: #eaffea;
}
&.old {
background: #ffecec;
}
&.matched {
color: $border-color;
background: #fafafa;
}
&.parallel { &.parallel {
display: table-cell; display: table-cell;
} }
...@@ -393,3 +352,15 @@ ...@@ -393,3 +352,15 @@
right: 15px; right: 15px;
} }
} }
@mixin diff_background($background, $idiff, $border) {
background: $background;
&.line_content span.idiff {
background: $idiff;
}
&.diff-line-num {
border-color: $border;
}
}
...@@ -201,3 +201,39 @@ ...@@ -201,3 +201,39 @@
.mr-source-target { .mr-source-target {
line-height: 31px; line-height: 31px;
} }
.disabled-comment-area {
padding: 16px 0;
.disabled-profile {
width: 40px;
height: 40px;
background: $border-gray-dark;
border-radius: 20px;
display: inline-block;
margin-right: 10px;
}
.disabled-comment {
background: $gray-light;
display: inline-block;
vertical-align: top;
height: 200px;
border-radius: 4px;
border: 1px solid $border-gray-normal;
padding-top: 90px;
text-align: center;
right: 20px;
position: absolute;
left: 70px;
margin-bottom: 20px;
span {
color: #B2B2B2;
a {
color: $md-link-color;
}
}
}
}
\ No newline at end of file
...@@ -10,18 +10,6 @@ ...@@ -10,18 +10,6 @@
margin: 10px $gl-padding; margin: 10px $gl-padding;
} }
.diff-file .diff-content { .diff-file .diff-content {
tr.line_holder:hover {
&> td.line_content {
background: $hover !important;
border-color: darken($hover, 10%) !important;
}
&> td.new_line,
&> td.old_line {
background: darken($hover, 4%) !important;
border-color: darken($hover, 10%) !important;
}
}
tr.line_holder:hover > td .line_note_link { tr.line_holder:hover > td .line_note_link {
opacity: 1.0; opacity: 1.0;
filter: alpha(opacity=100); filter: alpha(opacity=100);
......
...@@ -242,11 +242,8 @@ ul.notes { ...@@ -242,11 +242,8 @@ ul.notes {
// "show" the icon also if we just hover somewhere over the line // "show" the icon also if we just hover somewhere over the line
&:hover > td { &:hover > td {
background: $hover !important;
.add-diff-note { .add-diff-note {
@include show-add-diff-note; @include show-add-diff-note;
} }
} }
} }
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
padding-bottom: 15px; padding-bottom: 15px;
margin-bottom: 15px; margin-bottom: 15px;
.term {
height: 22px;
}
} }
} }
......
...@@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base ...@@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can?, :current_application_settings helper_method :abilities, :can?, :current_application_settings
helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled? helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
helper_method :repository
rescue_from Encoding::CompatibilityError do |exception| rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception) log_exception(exception)
......
...@@ -97,7 +97,7 @@ module CreatesCommit ...@@ -97,7 +97,7 @@ module CreatesCommit
# Merge request from fork to this project # Merge request from fork to this project
@mr_source_project = @tree_edit_project @mr_source_project = @tree_edit_project
@mr_target_project = @project @mr_target_project = @project
@mr_target_branch = @mr_target_project.repository.root_ref @mr_target_branch = @ref
end end
end end
end end
...@@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController
def preview def preview
@content = params[:content] @content = params[:content]
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true) diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/)) diff_lines = diffy.diff.scan(/.*\n/)[2..-1]
diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines)
@diff_lines = Gitlab::Diff::Highlight.new(diff_lines).highlight
render layout: false render layout: false
end end
...@@ -65,8 +67,9 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -65,8 +67,9 @@ class Projects::BlobController < Projects::ApplicationController
end end
def diff def diff
@form = UnfoldForm.new(params) @form = UnfoldForm.new(params)
@lines = @blob.data.lines[@form.since - 1..@form.to - 1] @lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path)
@lines = @lines[@form.since - 1..@form.to - 1]
if @form.bottom? if @form.bottom?
@match_line = '' @match_line = ''
......
...@@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
@diffs = commit.diffs @diffs = commit.diffs
end end
@diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count @notes_count = commit.notes.count
@statuses = ci_commit.statuses if ci_commit @statuses = ci_commit.statuses if ci_commit
......
...@@ -21,7 +21,8 @@ class Projects::CompareController < Projects::ApplicationController ...@@ -21,7 +21,8 @@ class Projects::CompareController < Projects::ApplicationController
@commits = Commit.decorate(compare_result.commits, @project) @commits = Commit.decorate(compare_result.commits, @project)
@diffs = compare_result.diffs @diffs = compare_result.diffs
@commit = @project.commit(head_ref) @commit = @project.commit(head_ref)
@first_commit = @project.commit(base_ref) @base_commit = @project.commit(base_ref)
@diff_refs = [@base_commit, @commit]
@line_notes = [] @line_notes = []
end end
end end
......
...@@ -58,7 +58,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -58,7 +58,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def diffs def diffs
@commit = @merge_request.last_commit @commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit @base_commit = @merge_request.diff_base_commit
# MRs created before 8.4 don't have a diff_base_commit,
# but we need it for the "View file @ ..." link by deleted files
@base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
@comments_allowed = @reply_allowed = true @comments_allowed = @reply_allowed = true
@comments_target = { @comments_target = {
...@@ -102,7 +106,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -102,7 +106,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@source_project = merge_request.source_project @source_project = merge_request.source_project
@commits = @merge_request.compare_commits.reverse @commits = @merge_request.compare_commits.reverse
@commit = @merge_request.last_commit @commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit @base_commit = @merge_request.diff_base_commit
@diffs = @merge_request.compare_diffs @diffs = @merge_request.compare_diffs
@ci_commit = @merge_request.ci_commit @ci_commit = @merge_request.ci_commit
......
...@@ -11,11 +11,9 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -11,11 +11,9 @@ class Projects::NotesController < Projects::ApplicationController
notes_json = { notes: [], last_fetched_at: current_fetched_at } notes_json = { notes: [], last_fetched_at: current_fetched_at }
@notes.each do |note| @notes.each do |note|
notes_json[:notes] << { next if note.cross_reference_not_visible_for?(current_user)
id: note.id,
html: note_to_html(note), notes_json[:notes] << note_json(note)
valid: note.valid?
}
end end
render json: notes_json render json: notes_json
...@@ -25,7 +23,7 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -25,7 +23,7 @@ class Projects::NotesController < Projects::ApplicationController
@note = Notes::CreateService.new(project, current_user, note_params).execute @note = Notes::CreateService.new(project, current_user, note_params).execute
respond_to do |format| respond_to do |format|
format.json { render_note_json(@note) } format.json { render json: note_json(@note) }
format.html { redirect_back_or_default } format.html { redirect_back_or_default }
end end
end end
...@@ -34,7 +32,7 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -34,7 +32,7 @@ class Projects::NotesController < Projects::ApplicationController
@note = Notes::UpdateService.new(project, current_user, note_params).execute(note) @note = Notes::UpdateService.new(project, current_user, note_params).execute(note)
respond_to do |format| respond_to do |format|
format.json { render_note_json(@note) } format.json { render json: note_json(@note) }
format.html { redirect_back_or_default } format.html { redirect_back_or_default }
end end
end end
...@@ -99,6 +97,8 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -99,6 +97,8 @@ class Projects::NotesController < Projects::ApplicationController
end end
def note_to_discussion_html(note) def note_to_discussion_html(note)
return unless note.for_diff_line?
if params[:view] == 'parallel' if params[:view] == 'parallel'
template = "projects/notes/_diff_notes_with_reply_parallel" template = "projects/notes/_diff_notes_with_reply_parallel"
locals = locals =
...@@ -131,9 +131,9 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -131,9 +131,9 @@ class Projects::NotesController < Projects::ApplicationController
) )
end end
def render_note_json(note) def note_json(note)
if note.valid? if note.valid?
render json: { {
valid: true, valid: true,
id: note.id, id: note.id,
discussion_id: note.discussion_id, discussion_id: note.discussion_id,
...@@ -144,7 +144,7 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -144,7 +144,7 @@ class Projects::NotesController < Projects::ApplicationController
discussion_with_diff_html: note_to_discussion_with_diff_html(note) discussion_with_diff_html: note_to_discussion_with_diff_html(note)
} }
else else
render json: { {
valid: false, valid: false,
award: note.is_award, award: note.is_award,
errors: note.errors errors: note.errors
...@@ -163,8 +163,6 @@ class Projects::NotesController < Projects::ApplicationController ...@@ -163,8 +163,6 @@ class Projects::NotesController < Projects::ApplicationController
) )
end end
private
def find_current_user_notes def find_current_user_notes
@notes = NotesFinder.new.execute(project, current_user, params) @notes = NotesFinder.new.execute(project, current_user, params)
end end
......
module BlobHelper module BlobHelper
def highlight(blob_name, blob_content, nowrap: false, continue: false) def highlighter(blob_name, blob_content, nowrap: false)
@formatter ||= Rouge::Formatters::HTMLGitlab.new( Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap)
nowrap: nowrap, end
cssclass: 'code highlight',
lineanchors: true,
lineanchorsid: 'LC'
)
begin
@lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content).new
result = @formatter.format(@lexer.lex(blob_content, continue: continue)).html_safe
rescue
@lexer = Rouge::Lexers::PlainText
result = @formatter.format(@lexer.lex(blob_content)).html_safe
end
result def highlight(blob_name, blob_content, nowrap: false)
Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap)
end end
def no_highlight_files def no_highlight_files
...@@ -37,10 +26,10 @@ module BlobHelper ...@@ -37,10 +26,10 @@ module BlobHelper
tree_join(ref, path), tree_join(ref, path),
link_opts) link_opts)
if !on_top_of_branch? if !on_top_of_branch?(project, ref)
button_tag "Edit", class: "btn btn-default disabled has_tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' } button_tag "Edit", class: "btn btn-default disabled has_tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' }
elsif can_edit_blob?(blob) elsif can_edit_blob?(blob, project, ref)
link_to "Edit", edit_path, class: 'btn btn-small' link_to "Edit", edit_path, class: 'btn'
elsif can?(current_user, :fork_project, project) elsif can?(current_user, :fork_project, project)
continue_params = { continue_params = {
to: edit_path, to: edit_path,
...@@ -50,7 +39,7 @@ module BlobHelper ...@@ -50,7 +39,7 @@ module BlobHelper
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
link_to "Edit", fork_path, class: 'btn btn-small', method: :post link_to "Edit", fork_path, class: 'btn', method: :post
end end
end end
...@@ -61,11 +50,11 @@ module BlobHelper ...@@ -61,11 +50,11 @@ module BlobHelper
return unless blob return unless blob
if !on_top_of_branch? if !on_top_of_branch?(project, ref)
button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "You can only #{action} files when you are on a branch", data: { container: 'body' } button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "You can only #{action} files when you are on a branch", data: { container: 'body' }
elsif blob.lfs_pointer? elsif blob.lfs_pointer?
button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "It is not possible to #{action} files that are stored in LFS using the web interface", data: { container: 'body' } button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "It is not possible to #{action} files that are stored in LFS using the web interface", data: { container: 'body' }
elsif can_edit_blob?(blob) elsif can_edit_blob?(blob, project, ref)
button_tag label, class: "btn btn-#{btn_class}", 'data-target' => "#modal-#{modal_type}-blob", 'data-toggle' => 'modal' button_tag label, class: "btn btn-#{btn_class}", 'data-target' => "#modal-#{modal_type}-blob", 'data-toggle' => 'modal'
elsif can?(current_user, :fork_project, project) elsif can?(current_user, :fork_project, project)
continue_params = { continue_params = {
......
...@@ -166,7 +166,7 @@ module CommitsHelper ...@@ -166,7 +166,7 @@ module CommitsHelper
link_to( link_to(
namespace_project_blob_path(project.namespace, project, namespace_project_blob_path(project.namespace, project,
tree_join(commit_sha, diff.new_path)), tree_join(commit_sha, diff.new_path)),
class: 'btn btn-small view-file js-view-file' class: 'btn view-file js-view-file'
) do ) do
raw('View file @') + content_tag(:span, commit_sha[0..6], raw('View file @') + content_tag(:span, commit_sha[0..6],
class: 'commit-short-id') class: 'commit-short-id')
......
...@@ -19,13 +19,13 @@ module DiffHelper ...@@ -19,13 +19,13 @@ module DiffHelper
end end
end end
def safe_diff_files(diffs) def safe_diff_files(diffs, diff_refs)
lines = 0 lines = 0
safe_files = [] safe_files = []
diffs.first(allowed_diff_size).each do |diff| diffs.first(allowed_diff_size).each do |diff|
lines += diff.diff.lines.count lines += diff.diff.lines.count
break if lines > allowed_diff_lines break if lines > allowed_diff_lines
safe_files << Gitlab::Diff::File.new(diff) safe_files << Gitlab::Diff::File.new(diff, diff_refs)
end end
safe_files safe_files
end end
...@@ -43,64 +43,6 @@ module DiffHelper ...@@ -43,64 +43,6 @@ module DiffHelper
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos) Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
end end
def parallel_diff(diff_file, index)
lines = []
skip_next = false
# Building array of lines
#
# [
# left_type, left_line_number, left_line_content, left_line_code,
# right_line_type, right_line_number, right_line_content, right_line_code
# ]
#
diff_file.diff_lines.each do |line|
full_line = line.text
type = line.type
line_code = generate_line_code(diff_file.file_path, line)
line_new = line.new_pos
line_old = line.old_pos
next_line = diff_file.next_line(line.index)
if next_line
next_line_code = generate_line_code(diff_file.file_path, next_line)
next_type = next_line.type
next_line = next_line.text
end
if type == 'match' || type.nil?
# line in the right panel is the same as in the left one
line = [type, line_old, full_line, line_code, type, line_new, full_line, line_code]
lines.push(line)
elsif type == 'old'
if next_type == 'new'
# Left side has text removed, right side has text added
line = [type, line_old, full_line, line_code, next_type, line_new, next_line, next_line_code]
lines.push(line)
skip_next = true
elsif next_type == 'old' || next_type.nil?
# Left side has text removed, right side doesn't have any change
# No next line code, no new line number, no new line text
line = [type, line_old, full_line, line_code, next_type, nil, "&nbsp;", nil]
lines.push(line)
end
elsif type == 'new'
if skip_next
# Change has been already included in previous line so no need to do it again
skip_next = false
next
else
# Change is only on the right side, left side has no change
line = [nil, nil, "&nbsp;", line_code, type, line_new, full_line, line_code]
lines.push(line)
end
end
end
lines
end
def unfold_bottom_class(bottom) def unfold_bottom_class(bottom)
(bottom) ? 'js-unfold-bottom' : '' (bottom) ? 'js-unfold-bottom' : ''
end end
...@@ -111,9 +53,9 @@ module DiffHelper ...@@ -111,9 +53,9 @@ module DiffHelper
def diff_line_content(line) def diff_line_content(line)
if line.blank? if line.blank?
" &nbsp;" " &nbsp;".html_safe
else else
line line.html_safe
end end
end end
...@@ -160,8 +102,7 @@ module DiffHelper ...@@ -160,8 +102,7 @@ module DiffHelper
def commit_for_diff(diff) def commit_for_diff(diff)
if diff.deleted_file if diff.deleted_file
first_commit = @first_commit || @commit @base_commit || @commit.parent || @commit
first_commit.parent || @first_commit
else else
@commit @commit
end end
......
...@@ -17,4 +17,79 @@ module SnippetsHelper ...@@ -17,4 +17,79 @@ module SnippetsHelper
snippet_path(snippet) snippet_path(snippet)
end end
end end
# Get an array of line numbers surrounding a matching
# line, bounded by min/max.
#
# @returns Array of line numbers
def bounded_line_numbers(line, min, max, surrounding_lines)
lower = line - surrounding_lines > min ? line - surrounding_lines : min
upper = line + surrounding_lines < max ? line + surrounding_lines : max
(lower..upper).to_a
end
# Returns a sorted set of lines to be included in a snippet preview.
# This ensures matching adjacent lines do not display duplicated
# surrounding code.
#
# @returns Array, unique and sorted.
def matching_lines(lined_content, surrounding_lines)
used_lines = []
lined_content.each_with_index do |line, line_number|
used_lines.concat bounded_line_numbers(
line_number,
0,
lined_content.size,
surrounding_lines
) if line.include?(query)
end
used_lines.uniq.sort
end
# 'Chunkify' entire snippet. Splits the snippet data into matching lines +
# surrounding_lines() worth of unmatching lines.
#
# @returns a hash with {snippet_object, snippet_chunks:{data,start_line}}
def chunk_snippet(snippet, surrounding_lines = 3)
lined_content = snippet.content.split("\n")
used_lines = matching_lines(lined_content, surrounding_lines)
snippet_chunk = []
snippet_chunks = []
snippet_start_line = 0
last_line = -1
# Go through each used line, and add consecutive lines as a single chunk
# to the snippet chunk array.
used_lines.each do |line_number|
if last_line < 0
# Start a new chunk.
snippet_start_line = line_number
snippet_chunk << lined_content[line_number]
elsif last_line == line_number - 1
# Consecutive line, continue chunk.
snippet_chunk << lined_content[line_number]
else
# Non-consecutive line, add chunk to chunk array.
snippet_chunks << {
data: snippet_chunk.join("\n"),
start_line: snippet_start_line + 1
}
# Start a new chunk.
snippet_chunk = [lined_content[line_number]]
snippet_start_line = line_number
end
last_line = line_number
end
# Add final chunk to chunk array
snippet_chunks << {
data: snippet_chunk.join("\n"),
start_line: snippet_start_line + 1
}
# Return snippet with chunk array
{ snippet_object: snippet, snippet_chunks: snippet_chunks }
end
end end
...@@ -346,17 +346,17 @@ module Ci ...@@ -346,17 +346,17 @@ module Ci
end end
def artifacts_browse_url def artifacts_browse_url
if artifacts_browser_supported? if artifacts_metadata?
browse_namespace_project_build_artifacts_path(project.namespace, project, self) browse_namespace_project_build_artifacts_path(project.namespace, project, self)
end end
end end
def artifacts_browser_supported? def artifacts_metadata?
artifacts? && artifacts_metadata.exists? artifacts? && artifacts_metadata.exists?
end end
def artifacts_metadata_entry(path) def artifacts_metadata_entry(path, **options)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_entry Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path, **options).to_entry
end end
private private
......
...@@ -38,6 +38,7 @@ class Issue < ActiveRecord::Base ...@@ -38,6 +38,7 @@ class Issue < ActiveRecord::Base
scope :cared, ->(user) { where(assignee_id: user) } scope :cared, ->(user) { where(assignee_id: user) }
scope :open_for, ->(user) { opened.assigned_to(user) } scope :open_for, ->(user) { opened.assigned_to(user) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
state_machine :state, initial: :opened do state_machine :state, initial: :opened do
event :close do event :close do
......
...@@ -91,7 +91,7 @@ class Member < ActiveRecord::Base ...@@ -91,7 +91,7 @@ class Member < ActiveRecord::Base
member.invite_email = user member.invite_email = user
end end
if can_update_member?(current_user, member) if can_update_member?(current_user, member) || project_creator?(member, access_level)
member.created_by ||= current_user member.created_by ||= current_user
member.access_level = access_level member.access_level = access_level
...@@ -107,6 +107,11 @@ class Member < ActiveRecord::Base ...@@ -107,6 +107,11 @@ class Member < ActiveRecord::Base
current_user.can?(:update_group_member, member) || current_user.can?(:update_group_member, member) ||
current_user.can?(:update_project_member, member) current_user.can?(:update_project_member, member)
end end
def project_creator?(member, access_level)
member.new_record? && member.owner? &&
access_level.to_i == ProjectMember::MASTER
end
end end
def invite? def invite?
......
...@@ -84,7 +84,7 @@ class ProjectMember < Member ...@@ -84,7 +84,7 @@ class ProjectMember < Member
def truncate_teams(project_ids) def truncate_teams(project_ids)
ProjectMember.transaction do ProjectMember.transaction do
members = ProjectMember.where(source_id: project_ids) members = ProjectMember.where(source_id: project_ids)
members.each do |member| members.each do |member|
member.destroy member.destroy
end end
...@@ -133,13 +133,13 @@ class ProjectMember < Member ...@@ -133,13 +133,13 @@ class ProjectMember < Member
event_service.join_project(self.project, self.user) event_service.join_project(self.project, self.user)
notification_service.new_project_member(self) notification_service.new_project_member(self)
end end
super super
end end
def post_update_hook def post_update_hook
if access_level_changed? if access_level_changed?
notification_service.update_project_member(self) notification_service.update_project_member(self)
end end
super super
......
...@@ -180,6 +180,14 @@ class MergeRequest < ActiveRecord::Base ...@@ -180,6 +180,14 @@ class MergeRequest < ActiveRecord::Base
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
end end
def diff_base_commit
if merge_request_diff
merge_request_diff.base_commit
else
self.target_project.commit(self.target_branch)
end
end
def last_commit_short_sha def last_commit_short_sha
last_commit.short_id last_commit.short_id
end end
...@@ -254,7 +262,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -254,7 +262,7 @@ class MergeRequest < ActiveRecord::Base
end end
def mergeable? def mergeable?
return false unless open? && !work_in_progress? return false unless open? && !work_in_progress? && !broken?
check_if_can_be_merged check_if_can_be_merged
...@@ -477,8 +485,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -477,8 +485,7 @@ class MergeRequest < ActiveRecord::Base
end end
def target_sha def target_sha
@target_sha ||= target_project. @target_sha ||= target_project.repository.commit(target_branch).sha
repository.commit(target_branch).sha
end end
def source_sha def source_sha
...@@ -517,4 +524,10 @@ class MergeRequest < ActiveRecord::Base ...@@ -517,4 +524,10 @@ class MergeRequest < ActiveRecord::Base
def ci_commit def ci_commit
@ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project @ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project
end end
def diff_refs
return nil unless diff_base_commit
[diff_base_commit, last_commit]
end
end end
...@@ -73,6 +73,12 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -73,6 +73,12 @@ class MergeRequestDiff < ActiveRecord::Base
commits.last commits.last
end end
def base_commit
return nil unless self.base_commit_sha
merge_request.target_project.commit(self.base_commit_sha)
end
def last_commit_short_sha def last_commit_short_sha
@last_commit_short_sha ||= last_commit.short_id @last_commit_short_sha ||= last_commit.short_id
end end
...@@ -156,6 +162,9 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -156,6 +162,9 @@ class MergeRequestDiff < ActiveRecord::Base
end end
self.st_diffs = new_diffs self.st_diffs = new_diffs
self.base_commit_sha = merge_request.target_project.commit(target_branch).try(:sha)
self.save self.save
end end
......
...@@ -244,7 +244,7 @@ class Note < ActiveRecord::Base ...@@ -244,7 +244,7 @@ class Note < ActiveRecord::Base
prev_match_line = nil prev_match_line = nil
prev_lines = [] prev_lines = []
diff_lines.each do |line| highlighted_diff_lines.each do |line|
if line.type == "match" if line.type == "match"
prev_lines.clear prev_lines.clear
prev_match_line = line prev_match_line = line
...@@ -261,7 +261,11 @@ class Note < ActiveRecord::Base ...@@ -261,7 +261,11 @@ class Note < ActiveRecord::Base
end end
def diff_lines def diff_lines
@diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a) @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines)
end
def highlighted_diff_lines
Gitlab::Diff::Highlight.new(diff_lines).highlight
end end
def discussion_id def discussion_id
......
...@@ -904,4 +904,8 @@ class Project < ActiveRecord::Base ...@@ -904,4 +904,8 @@ class Project < ActiveRecord::Base
def runners_token def runners_token
ensure_runners_token! ensure_runners_token!
end end
def wiki
@wiki ||= ProjectWiki.new(self, self.owner)
end
end end
...@@ -12,6 +12,7 @@ class ProjectWiki ...@@ -12,6 +12,7 @@ class ProjectWiki
# Returns a string describing what went wrong after # Returns a string describing what went wrong after
# an operation fails. # an operation fails.
attr_reader :error_message attr_reader :error_message
attr_reader :project
def initialize(project, user = nil) def initialize(project, user = nil)
@project = project @project = project
......
...@@ -95,7 +95,7 @@ module Projects ...@@ -95,7 +95,7 @@ module Projects
system_hook_service.execute_hooks_for(@project, :create) system_hook_service.execute_hooks_for(@project, :create)
unless @project.group unless @project.group
@project.team << [current_user, :master] @project.team << [current_user, :master, current_user]
end end
@project.import_start if @project.import? @project.import_start if @project.import?
......
...@@ -5,5 +5,9 @@ ...@@ -5,5 +5,9 @@
-# num_pages: total number of pages -# num_pages: total number of pages
-# per_page: number of items to fetch per page -# per_page: number of items to fetch per page
-# remote: data-remote -# remote: data-remote
%li.next - if current_page.last?
= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote %li{ class: "next disabled" }
%span= raw(t 'views.pagination.next')
- else
%li{ class: "next" }
= link_to raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
%ul.pagination.clearfix %ul.pagination.clearfix
- unless current_page.first? - unless current_page.first?
= first_page_tag unless num_pages < 5 # As kaminari will always show the first 5 pages = first_page_tag unless num_pages < 5 # As kaminari will always show the first 5 pages
= prev_page_tag = prev_page_tag
- each_page do |page| - each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window? - if page.left_outer? || page.right_outer? || page.inside_window?
= page_tag page = page_tag page
- elsif !page.was_truncated? - elsif !page.was_truncated?
= gap_tag = gap_tag
= next_page_tag
- unless current_page.last? - unless current_page.last?
= next_page_tag
= last_page_tag unless num_pages < 5 = last_page_tag unless num_pages < 5
...@@ -5,5 +5,9 @@ ...@@ -5,5 +5,9 @@
-# num_pages: total number of pages -# num_pages: total number of pages
-# per_page: number of items to fetch per page -# per_page: number of items to fetch per page
-# remote: data-remote -# remote: data-remote
%li{class: "prev" } - if current_page.first?
= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote %li{ class: "prev disabled" }
%span= raw(t 'views.pagination.previous')
- else
%li{ class: "prev" }
= link_to raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.top-block.gray-content-block.clearfix .top-block.gray-content-block.clearfix
.pull-right .pull-right
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
class: 'btn btn-default' do class: 'btn btn-default download' do
= icon('download') = icon('download')
Download artifacts archive Download artifacts archive
...@@ -20,12 +20,3 @@ ...@@ -20,12 +20,3 @@
- if @entry.empty? - if @entry.empty?
.center Empty .center Empty
:javascript
$('.tree-holder').on('click', 'tr[data-link] a', function(e) {
e.stopImmediatePropagation();
});
$('.tree-holder').on('click', 'tr[data-link]', function(e) {
window.location = this.dataset.link;
});
...@@ -12,9 +12,10 @@ ...@@ -12,9 +12,10 @@
%small= number_to_human_size @blob.size %small= number_to_human_size @blob.size
.file-actions .file-actions
= render "projects/blob/actions" = render "projects/blob/actions"
.file-content.blame.highlight .file-content.blame.code.js-syntax-highlight
%table %table
- current_line = 1 - current_line = 1
- blame_highlighter = highlighter(@blob.name, @blob.data, nowrap: true)
- @blame.each do |blame_group| - @blame.each do |blame_group|
%tr %tr
%td.blame-commit %td.blame-commit
...@@ -30,16 +31,15 @@ ...@@ -30,16 +31,15 @@
= commit_author_link(commit, avatar: false) = commit_author_link(commit, avatar: false)
authored authored
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)} #{time_ago_with_tooltip(commit.committed_date, skip_js: true)}
%td.lines.blame-numbers %td.line-numbers
%pre - line_count = blame_group[:lines].count
- line_count = blame_group[:lines].count - (current_line...(current_line + line_count)).each do |i|
- (current_line...(current_line + line_count)).each do |i| %a.diff-line-num= i
= i \
\ - current_line += line_count
- current_line += line_count
%td.lines %td.lines
%pre{class: 'code highlight white'} %pre{class: 'code highlight'}
%code %code
- blame_group[:lines].each do |line| - blame_group[:lines].each do |line|
:erb :preserve
<%= highlight(@blob.name, line, nowrap: true, continue: true).html_safe %> #{blame_highlighter.highlight(line)}
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
%tr.line_holder %tr.line_holder
%td.old_line.diff-line-num{data: {linenumber: line_old}} %td.old_line.diff-line-num{data: {linenumber: line_old}}
= link_to raw(line_old), "#" = link_to raw(line_old), "#"
%td.new_line= link_to raw(line_new) , "#" %td.new_line.diff-line-num
%td.line_content.noteable_line= ' ' * @form.indent + line = link_to raw(line_new) , "#"
%td.line_content.noteable_line==#{' ' * @form.indent}#{line}
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc - if @form.unfold? && @form.bottom? && @form.to < @blob.loc
%tr.line_holder{ id: @form.to } %tr.line_holder{ id: @form.to }
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
- @diff_lines.each do |line| - @diff_lines.each do |line|
%tr.line_holder{ class: "#{line.type}" } %tr.line_holder{ class: "#{line.type}" }
- if line.type == "match" - if line.type == "match"
%td.old_line= "..." %td.old_line.diff-line-num= "..."
%td.new_line= "..." %td.new_line.diff-line-num= "..."
%td.line_content.matched= line.text %td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num
%td.new_line %td.new_line.diff-line-num
%td.line_content{class: "#{line.type}"}= raw diff_line_content(line.text) %td.line_content{class: "#{line.type}"}= diff_line_content(line.text)
- else - else
.nothing-here-block No changes. .nothing-here-block No changes.
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
.center .center
.btn-group{ role: :group } .btn-group{ role: :group }
= link_to "Download", @build.artifacts_download_url, class: 'btn btn-sm btn-primary' = link_to "Download", @build.artifacts_download_url, class: 'btn btn-sm btn-primary'
- if @build.artifacts_browser_supported? - if @build.artifacts_metadata?
= link_to "Browse", @build.artifacts_browse_url, class: 'btn btn-sm btn-primary' = link_to "Browse", @build.artifacts_browse_url, class: 'btn btn-sm btn-primary'
.build-widget .build-widget
......
...@@ -9,5 +9,6 @@ ...@@ -9,5 +9,6 @@
= render "ci_menu" = render "ci_menu"
- else - else
%div.block-connector %div.block-connector
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project,
diff_refs: @diff_refs
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
- if @commits.present? - if @commits.present?
.prepend-top-default .prepend-top-default
= render "projects/commits/commit_list" = render "projects/commits/commit_list"
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
- else - else
.light-well.prepend-top-default .light-well.prepend-top-default
.center .center
......
- if diff_view == 'parallel' - if diff_view == 'parallel'
- fluid_layout true - fluid_layout true
- diff_files = safe_diff_files(diffs) - diff_files = safe_diff_files(diffs, diff_refs)
.content-block.oneline-block .content-block.oneline-block
.inline-parallel-buttons .inline-parallel-buttons
......
.diff-file{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)} .diff-file.file-holder{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
.diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"} .file-title{id: "file-path-#{hexdigest(diff_file.file_path)}"}
- if diff_file.diff.submodule? - if diff_file.diff.submodule?
%span %span
= icon('archive fw') = icon('archive fw')
%strong %strong
= submodule_link(blob, @commit.id, project.repository) = submodule_link(blob, @commit.id, project.repository)
- else - else
%span = blob_icon blob.mode, blob.name
= blob_icon blob.mode, blob.name = link_to "#diff-#{i}" do
= link_to "#diff-#{i}" do %strong
%strong = diff_file.new_path
= diff_file.new_path
- if diff_file.deleted_file - if diff_file.deleted_file
deleted deleted
- elsif diff_file.renamed_file - elsif diff_file.renamed_file
renamed from renamed from
%strong %strong
= diff_file.old_path = diff_file.old_path
- if diff_file.mode_changed? - if diff_file.mode_changed?
%small %small
= "#{diff_file.diff.a_mode}#{diff_file.diff.b_mode}" = "#{diff_file.diff.a_mode}#{diff_file.diff.b_mode}"
.diff-controls .file-actions.hidden-xs
- if blob_text_viewable?(blob) - if blob_text_viewable?(blob)
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do = link_to '#', class: 'js-toggle-diff-comments btn active has_tooltip', title: "Toggle comments for this file" do
%i.fa.fa-comments = icon('comments')
&nbsp; \
- if editable_diff?(diff_file) - if editable_diff?(diff_file)
= edit_blob_link(@merge_request.source_project, = edit_blob_link(@merge_request.source_project,
@merge_request.source_branch, diff_file.new_path, @merge_request.source_branch, diff_file.new_path,
from_merge_request_id: @merge_request.id) from_merge_request_id: @merge_request.id)
&nbsp;
= view_file_btn(diff_commit.id, diff_file, project) = view_file_btn(diff_commit.id, diff_file, project)
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
%td.new_line.diff-line-num{data: {linenumber: line_new}, %td.new_line.diff-line-num{data: {linenumber: line_new},
class: [unfold_bottom_class(bottom), unfold_class(!new_file)]} class: [unfold_bottom_class(bottom), unfold_class(!new_file)]}
\... \...
%td.line_content.matched= line %td.line_content.match= line
%td.old_line %td.old_line.diff-line-num
%td.line_content.parallel.matched= line %td.line_content.parallel.match= line
%td.new_line %td.new_line.diff-line-num
%td.line_content.parallel.matched= line %td.line_content.parallel.match= line
/ Side-by-side diff view / Side-by-side diff view
%div.text-file.diff-wrap-lines %div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight
%table %table
- parallel_diff(diff_file, index).each do |line| - diff_file.parallel_diff_lines.each do |line|
- type_left = line[0] - left = line[:left]
- line_number_left = line[1] - right = line[:right]
- line_content_left = line[2]
- line_code_left = line[3]
- type_right = line[4]
- line_number_right = line[5]
- line_content_right = line[6]
- line_code_right = line[7]
%tr.line_holder.parallel %tr.line_holder.parallel
- if type_left == 'match' - if left[:type] == 'match'
= render "projects/diffs/match_line_parallel", { line: line_content_left, = render "projects/diffs/match_line_parallel", { line: left[:text],
line_old: line_number_left, line_new: line_number_right } line_old: left[:number], line_new: right[:number] }
- elsif type_left == 'old' || type_left.nil? - elsif left[:type] == 'nonewline'
%td.old_line{id: line_code_left, class: "#{type_left}"} %td.old_line.diff-line-num
= link_to raw(line_number_left), "##{line_code_left}", id: line_code_left %td.line_content.parallel.match= left[:text]
%td.new_line.diff-line-num
%td.line_content.parallel.match= left[:text]
- else
%td.old_line.diff-line-num{id: left[:line_code], class: "#{left[:type]}"}
= link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code_left, 'old') = link_to_new_diff_note(left[:line_code], 'old')
%td.line_content{class: "parallel noteable_line #{type_left} #{line_code_left}", "line_code" => line_code_left }= raw line_content_left %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
- if type_right == 'new' - if right[:type] == 'new'
- new_line_class = 'new' - new_line_class = 'new'
- new_line_code = line_code_right - new_line_code = right[:line_code]
- else - else
- new_line_class = nil - new_line_class = nil
- new_line_code = line_code_left - new_line_code = left[:line_code]
%td.new_line{id: new_line_code, class: "#{new_line_class}", data: { linenumber: line_number_right }} %td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class}", data: { linenumber: right[:number] }}
= link_to raw(line_number_right), "##{new_line_code}", id: new_line_code = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code_right, 'new') = link_to_new_diff_note(right[:line_code], 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", "line_code" => new_line_code}= raw line_content_right %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
- if @reply_allowed - if @reply_allowed
- comments_left, comments_right = organize_comments(type_left, type_right, line_code_left, line_code_right) - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
- if comments_left.present? || comments_right.present? - if comments_left.present? || comments_right.present?
= render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right = render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right
......
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
.suppressed-container .suppressed-container
%a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show. %a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show.
%table.text-file{class: "#{'hide' if too_big}"} %table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
- last_line = 0 - last_line = 0
- diff_file.diff_lines.each_with_index do |line, index| - raw_diff_lines = diff_file.diff_lines
- diff_file.highlighted_diff_lines.each_with_index do |line, index|
- type = line.type - type = line.type
- last_line = line.new_pos - last_line = line.new_pos
- line_code = generate_line_code(diff_file.file_path, line) - line_code = generate_line_code(diff_file.file_path, line)
...@@ -14,19 +16,23 @@ ...@@ -14,19 +16,23 @@
- if type == "match" - if type == "match"
= render "projects/diffs/match_line", {line: line.text, = render "projects/diffs/match_line", {line: line.text,
line_old: line_old, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file} line_old: line_old, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file}
- elsif type == 'nonewline'
%td.old_line.diff-line-num
%td.new_line.diff-line-num
%td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num{class: type}
= link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code) = link_to_new_diff_note(line_code)
%td.new_line{data: {linenumber: line.new_pos}} %td.new_line.diff-line-num{class: type, data: {linenumber: line.new_pos}}
= link_to raw(type == "old" ? "&nbsp;" : line.new_pos) , "##{line_code}", id: line_code = link_to raw(type == "old" ? "&nbsp;" : line.new_pos), "##{line_code}", id: line_code
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text) %td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text)
- if @reply_allowed - if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at) - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
- unless comments.empty? - unless comments.empty?
= render "projects/notes/diff_notes_with_reply", notes: comments, line: line.text = render "projects/notes/diff_notes_with_reply", notes: comments, line: raw_diff_lines[index].text
- if last_line > 0 - if last_line > 0
= render "projects/diffs/match_line", {line: "", = render "projects/diffs/match_line", {line: "",
......
...@@ -5,9 +5,4 @@ ...@@ -5,9 +5,4 @@
.nothing-here-block No issues to show .nothing-here-block No issues to show
- if @issues.present? - if @issues.present?
.issuable-filter-count
%span.pull-right
= number_with_delimiter(@issues.total_count)
issues for this filter
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
...@@ -5,10 +5,5 @@ ...@@ -5,10 +5,5 @@
.nothing-here-block No merge requests to show .nothing-here-block No merge requests to show
- if @merge_requests.present? - if @merge_requests.present?
.issuable-filter-count
%span.pull-right
= number_with_delimiter(@merge_requests.total_count)
merge requests for this filter
= paginate @merge_requests, theme: "gitlab" = paginate @merge_requests, theme: "gitlab"
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
= render "projects/merge_requests/show/commits" = render "projects/merge_requests/show/commits"
#diffs.diffs.tab-pane.active #diffs.diffs.tab-pane.active
- if @diffs.present? - if @diffs.present?
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @merge_request.diff_refs
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
.alert.alert-danger .alert.alert-danger
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
......
- if @merge_request_diff.collected? - if @merge_request_diff.collected?
= render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs, project: @merge_request.project = render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs,
project: @merge_request.project, diff_refs: @merge_request.diff_refs
- 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
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
%i.fa.fa-comment %i.fa.fa-comment
= notes.count = notes.count
%td.notes_content %td.notes_content
%ul.notes{ rel: note.discussion_id } %ul.notes{ data: { discussion_id: note.discussion_id } }
= render notes = render notes
.discussion-reply-holder .discussion-reply-holder
= link_to_reply_diff(note) = link_to_reply_diff(note)
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
%i.fa.fa-comment %i.fa.fa-comment
= notes_left.count = notes_left.count
%td.notes_content.parallel.old %td.notes_content.parallel.old
%ul.notes{ rel: note1.discussion_id } %ul.notes{ data: { discussion_id: note1.discussion_id } }
= render notes_left = render notes_left
.discussion-reply-holder .discussion-reply-holder
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
%i.fa.fa-comment %i.fa.fa-comment
= notes_right.count = notes_right.count
%td.notes_content.parallel.new %td.notes_content.parallel.new
%ul.notes{ rel: note2.discussion_id } %ul.notes{ data: { discussion_id: note2.discussion_id } }
= render notes_right = render notes_right
.discussion-reply-holder .discussion-reply-holder
...@@ -31,4 +31,3 @@ ...@@ -31,4 +31,3 @@
- else - else
%td.notes_line.new= "" %td.notes_line.new= ""
%td.notes_content.parallel.new= "" %td.notes_content.parallel.new= ""
%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: { discussion: note.discussion_id } } %li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)] }
.timeline-entry-inner .timeline-entry-inner
.timeline-icon .timeline-icon
%a{href: user_path(note.author)} %a{href: user_path(note.author)}
......
...@@ -5,6 +5,16 @@ ...@@ -5,6 +5,16 @@
.js-main-target-form .js-main-target-form
- if can? current_user, :create_note, @project - if can? current_user, :create_note, @project
= render "projects/notes/form", view: diff_view = render "projects/notes/form", view: diff_view
- else
.disabled-comment-area
.disabled-profile
.disabled-comment
%span
Please
= link_to "register",new_user_session_path
or
= link_to "login",new_user_session_path
to post a comment
:javascript :javascript
var notes = new Notes("#{namespace_project_notes_path(namespace_id: @project.namespace, target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}") var notes = new Notes("#{namespace_project_notes_path(namespace_id: @project.namespace, target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}")
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
= render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
- else - else
.panel.panel-default .panel.panel-default
.notes{ rel: discussion_notes.first.discussion_id } .notes{ data: { discussion_id: discussion_notes.first.discussion_id } }
= render discussion_notes = render discussion_notes
.discussion-reply-holder .discussion-reply-holder
= link_to_reply_diff(discussion_notes.first) = link_to_reply_diff(discussion_notes.first)
...@@ -16,15 +16,15 @@ ...@@ -16,15 +16,15 @@
- line_code = generate_line_code(note.file_path, line) - line_code = generate_line_code(note.file_path, line)
%tr.line_holder{ id: line_code, class: "#{type}" } %tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match" - if type == "match"
%td.old_line= "..." %td.old_line.diff-line-num= "..."
%td.new_line= "..." %td.new_line.diff-line-num= "..."
%td.line_content.matched= line.text %td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num
= raw(type == "new" ? "&nbsp;" : line.old_pos) = raw(type == "new" ? "&nbsp;" : line.old_pos)
%td.new_line %td.new_line.diff-line-num
= raw(type == "old" ? "&nbsp;" : line.new_pos) = raw(type == "old" ? "&nbsp;" : line.new_pos)
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text) %td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text)
- if line_code == note.line_code - if line_code == note.line_code
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
- if merge_request.description.present? - if merge_request.description.present?
.description.term .description.term
= preserve do = preserve do
= search_md_sanitize(markdown(merge_request.description)) = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project }))
%span.light %span.light
#{merge_request.project.name_with_namespace} #{merge_request.project.name_with_namespace}
.pull-right .pull-right
......
...@@ -22,29 +22,27 @@ ...@@ -22,29 +22,27 @@
.file-content.code .file-content.code
.nothing-here-block Empty file .nothing-here-block Empty file
- else - else
.file-content.code .file-content.code.js-syntax-highlight
%div.highlighted-data{ class: user_color_scheme } .line-numbers
.line-numbers - snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty?
- snippet[:data].lines.to_a.size.times do |index|
- offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
- i = index + offset
= link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}", class: "diff-line-num" do
%i.fa.fa-link
= i
- unless snippet == snippet_blob[:snippet_chunks].last
%a.diff-line-num
= "."
%pre.code
%code
- snippet_blob[:snippet_chunks].each do |snippet| - snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty? - unless snippet[:data].empty?
- snippet[:data].lines.to_a.size.times do |index| = snippet[:data]
- offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
- i = index + offset
= link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do
%i.fa.fa-link
= i
- unless snippet == snippet_blob[:snippet_chunks].last - unless snippet == snippet_blob[:snippet_chunks].last
%a %a
= "." = "..."
.highlight.term - else
%pre .file-content.code
%code .nothing-here-block Empty file
- snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty?
= snippet[:data]
- unless snippet == snippet_blob[:snippet_chunks].last
%a
= "..."
- else
.file-content.code
.nothing-here-block Empty file
.file-content.code.js-syntax-highlight{ class: user_color_scheme } .file-content.code.js-syntax-highlight
.line-numbers .line-numbers
- if blob.data.present? - if blob.data.present?
- blob.data.lines.each_index do |index| - blob.data.lines.each_index do |index|
- offset = defined?(first_line_number) ? first_line_number : 1 - offset = defined?(first_line_number) ? first_line_number : 1
- i = index + offset - i = index + offset
-# We're not using `link_to` because it is too slow once we get to thousands of lines. -# We're not using `link_to` because it is too slow once we get to thousands of lines.
%a{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i} %a.diff-line-num{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i}
%i.fa.fa-link %i.fa.fa-link
= i = i
.blob-content{data: {blob_id: blob.id}} .blob-content{data: {blob_id: blob.id}}
:preserve = highlight(blob.name, blob.data)
#{highlight(blob.name, blob.data)}
...@@ -49,6 +49,7 @@ if Gitlab::Metrics.enabled? ...@@ -49,6 +49,7 @@ if Gitlab::Metrics.enabled?
config.instrument_instance_methods(Gitlab::Shell) config.instrument_instance_methods(Gitlab::Shell)
config.instrument_methods(Gitlab::Git) config.instrument_methods(Gitlab::Git)
config.instrument_instance_methods(Gitlab::Git::Repository)
Gitlab::Git.constants.each do |name| Gitlab::Git.constants.each do |name|
const = Gitlab::Git.const_get(name) const = Gitlab::Git.const_get(name)
......
...@@ -8,3 +8,7 @@ en: ...@@ -8,3 +8,7 @@ en:
wrong_size: "is the wrong size (should be %{file_size})" wrong_size: "is the wrong size (should be %{file_size})"
size_too_small: "is too small (should be at least %{file_size})" size_too_small: "is too small (should be at least %{file_size})"
size_too_big: "is too big (should be at most %{file_size})" size_too_big: "is too big (should be at most %{file_size})"
views:
pagination:
previous: "Prev"
next: "Next"
class AddBaseCommitShaToMergeRequestDiffs < ActiveRecord::Migration
def change
add_column :merge_request_diffs, :base_commit_sha, :string
end
end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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