Merge branch 'master' into doc_refactor_commits_api
This commit is contained in:
commit
831eb9468d
20
CHANGELOG
20
CHANGELOG
|
@ -1,15 +1,22 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 8.5.0 (unreleased)
|
||||
- Add "visibility" flag to GET /projects api endpoint
|
||||
- Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push
|
||||
- New UI for pagination
|
||||
|
||||
v 8.4.0 (unreleased)
|
||||
- Allow LDAP users to change their email if it was not set by the LDAP server
|
||||
- Ensure Gravatar host looks like an actual host
|
||||
- Consider re-assign as a mention from a notification point of view
|
||||
- Add pagination headers to already paginated API resources
|
||||
- Properly generate diff of orphan commits, like the first commit in a repository
|
||||
- Improve the consistency of commit titles, branch names, tag names, issue/MR titles, on their respective project pages
|
||||
- Autocomplete data is now always loaded, instead of when focusing a comment text area (Yorick Peterse)
|
||||
- Improved performance of finding issues for an entire group (Yorick Peterse)
|
||||
- Added custom application performance measuring system powered by InfluxDB (Yorick Peterse)
|
||||
- Autocomplete data is now always loaded, instead of when focusing a comment text area
|
||||
- Improved performance of finding issues for an entire group
|
||||
- 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)
|
||||
- Bump fog to 1.36.0 (Stan Hu)
|
||||
- Add user's last used IP addresses to admin page (Stan Hu)
|
||||
- Add housekeeping function to project settings page
|
||||
|
@ -60,11 +67,16 @@ v 8.4.0 (unreleased)
|
|||
- Autosize Markdown textareas
|
||||
- Import GitHub wiki into GitLab
|
||||
- Add reporters ability to download and browse build artifacts (Andrew Johnson)
|
||||
- Autofill referring url in message box when reporting user abuse. (Josh Frye)
|
||||
- Autofill referring url in message box when reporting user abuse.
|
||||
- Remove leading comma on award emoji when the user is the first to award the emoji (Zeger-Jan van de Weg)
|
||||
- Add build artifacts browser
|
||||
- Improve UX in builds artifacts browser
|
||||
- Increase default size of `data` column in `events` table when using MySQL
|
||||
- Expose button to CI Lint tool on project builds page
|
||||
- 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)
|
||||
- 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
|
||||
- Use gitlab-workhorse 0.5.4 (fixes API routing bug)
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.6.0
|
||||
0.6.1
|
||||
|
|
5
Gemfile
5
Gemfile
|
@ -49,7 +49,7 @@ gem "browser", '~> 1.0.0'
|
|||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
gem "gitlab_git", '~> 7.2.22'
|
||||
gem "gitlab_git", '~> 7.2.23'
|
||||
|
||||
# LDAP Auth
|
||||
# GitLab fork with several improvements to original library. For full list of changes
|
||||
|
@ -293,6 +293,9 @@ end
|
|||
|
||||
group :production do
|
||||
gem "gitlab_meta", '7.0'
|
||||
|
||||
# Sentry integration
|
||||
gem 'sentry-raven'
|
||||
end
|
||||
|
||||
gem "newrelic_rpm", '~> 3.9.4.245'
|
||||
|
|
|
@ -356,7 +356,7 @@ GEM
|
|||
posix-spawn (~> 0.3)
|
||||
gitlab_emoji (0.2.0)
|
||||
gemojione (~> 2.1)
|
||||
gitlab_git (7.2.22)
|
||||
gitlab_git (7.2.23)
|
||||
activesupport (~> 4.0)
|
||||
charlock_holmes (~> 0.7.3)
|
||||
github-linguist (~> 4.7.0)
|
||||
|
@ -725,6 +725,8 @@ GEM
|
|||
activesupport (>= 3.1, < 4.3)
|
||||
select2-rails (3.5.9.3)
|
||||
thor (~> 0.14)
|
||||
sentry-raven (0.15.3)
|
||||
faraday (>= 0.7.6)
|
||||
settingslogic (2.0.9)
|
||||
sexp_processor (4.6.0)
|
||||
sham_rack (1.3.6)
|
||||
|
@ -932,7 +934,7 @@ DEPENDENCIES
|
|||
github-markup (~> 1.3.1)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab_emoji (~> 0.2.0)
|
||||
gitlab_git (~> 7.2.22)
|
||||
gitlab_git (~> 7.2.23)
|
||||
gitlab_meta (= 7.0)
|
||||
gitlab_omniauth-ldap (~> 1.2.1)
|
||||
gollum-lib (~> 4.1.0)
|
||||
|
@ -1008,6 +1010,7 @@ DEPENDENCIES
|
|||
sdoc (~> 0.3.20)
|
||||
seed-fu (~> 2.3.5)
|
||||
select2-rails (~> 3.5.9)
|
||||
sentry-raven
|
||||
settingslogic (~> 2.0.9)
|
||||
sham_rack
|
||||
shoulda-matchers (~> 2.8.0)
|
||||
|
|
|
@ -44,7 +44,6 @@ class @AwardsHandler
|
|||
decrementCounter: (emoji) ->
|
||||
counter = @findEmojiIcon(emoji).siblings(".counter")
|
||||
emojiIcon = counter.parent()
|
||||
|
||||
if parseInt(counter.text()) > 1
|
||||
counter.text(parseInt(counter.text()) - 1)
|
||||
emojiIcon.removeClass("active")
|
||||
|
@ -60,20 +59,18 @@ class @AwardsHandler
|
|||
removeMeFromAuthorList: (emoji) ->
|
||||
award_block = @findEmojiIcon(emoji).parent()
|
||||
authors = award_block.attr("data-original-title").split(", ")
|
||||
authors = _.without(authors, "me").join(", ")
|
||||
award_block.attr("title", authors)
|
||||
authors.splice(authors.indexOf("me"),1)
|
||||
award_block.closest(".award").attr("data-original-title", authors.join(", "))
|
||||
@resetTooltip(award_block)
|
||||
|
||||
addMeToAuthorList: (emoji) ->
|
||||
award_block = @findEmojiIcon(emoji).parent()
|
||||
authors = _.compact(award_block.attr("data-original-title").split(", "))
|
||||
origTitle = award_block.attr("data-original-title").trim()
|
||||
authors = []
|
||||
if origTitle
|
||||
authors = origTitle.split(', ')
|
||||
authors.push("me")
|
||||
|
||||
if authors.length == 1
|
||||
award_block.attr("title", "me")
|
||||
else
|
||||
award_block.attr("title", authors.join(", "))
|
||||
|
||||
award_block.attr("title", authors.join(", "))
|
||||
@resetTooltip(award_block)
|
||||
|
||||
resetTooltip: (award) ->
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
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
|
|
@ -87,7 +87,6 @@ class Dispatcher
|
|||
new GroupAvatar()
|
||||
when 'projects:tree:show'
|
||||
new TreeView()
|
||||
shortcut_handler = new ShortcutsTree()
|
||||
when 'projects:find_file:show'
|
||||
shortcut_handler = true
|
||||
when 'projects:blob:show'
|
||||
|
@ -101,6 +100,8 @@ class Dispatcher
|
|||
shortcut_handler = true
|
||||
when 'projects:forks:new'
|
||||
new ProjectFork()
|
||||
when 'projects:artifacts:browse'
|
||||
new BuildArtifacts()
|
||||
when 'users:show'
|
||||
new User()
|
||||
new Activities()
|
||||
|
|
|
@ -4,6 +4,7 @@ class @Shortcuts
|
|||
Mousetrap.reset()
|
||||
Mousetrap.bind('?', @selectiveHelp)
|
||||
Mousetrap.bind('s', Shortcuts.focusSearch)
|
||||
Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL?
|
||||
|
||||
selectiveHelp: (e) =>
|
||||
Shortcuts.showHelp(e, @enabledHelp)
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
class @ShortcutsTree extends ShortcutsNavigation
|
||||
constructor: ->
|
||||
super()
|
||||
Mousetrap.bind('t', -> ShortcutsTree.findAndFollowLink('.shortcuts-find-file'))
|
|
@ -6,7 +6,7 @@ class @Star
|
|||
$starIcon = $this.find('i')
|
||||
|
||||
toggleStar = (isStarred) ->
|
||||
$this.parent().find('span.count').text data.star_count
|
||||
$this.parent().find('.star-count').text data.star_count
|
||||
if isStarred
|
||||
$starSpan.removeClass('starred').text 'Star'
|
||||
$starIcon.removeClass('fa-star').addClass 'fa-star-o'
|
||||
|
@ -19,4 +19,4 @@ class @Star
|
|||
return
|
||||
).on 'ajax:error', (e, xhr, status, error) ->
|
||||
new Flash('Star toggle failed. Try again later.', 'alert')
|
||||
return
|
||||
return
|
||||
|
|
|
@ -120,14 +120,6 @@ span.update-author {
|
|||
display: inline;
|
||||
}
|
||||
|
||||
.line_holder {
|
||||
&:hover {
|
||||
td {
|
||||
background: #FFFFCF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.time {
|
||||
color: #999;
|
||||
font-size: 90%;
|
||||
|
|
|
@ -92,15 +92,6 @@
|
|||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
background: #fff;
|
||||
}
|
||||
.lines {
|
||||
pre {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
img.avatar {
|
||||
border: 0 none;
|
||||
|
@ -116,18 +107,18 @@
|
|||
color: #888;
|
||||
}
|
||||
}
|
||||
td.blame-numbers {
|
||||
pre {
|
||||
color: #AAA;
|
||||
white-space: pre;
|
||||
}
|
||||
background: #f1f1f1;
|
||||
td.line-numbers {
|
||||
float: none;
|
||||
border-left: 1px solid #DDD;
|
||||
}
|
||||
td.lines {
|
||||
padding: 0;
|
||||
code {
|
||||
font-family: $monospace_font;
|
||||
}
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,3 +53,14 @@
|
|||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-sortable-handle {
|
||||
cursor: move;
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
|
||||
&:active {
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,11 @@
|
|||
.gl-pagination {
|
||||
text-align: center;
|
||||
border-top: 1px solid $border-color;
|
||||
background-color: $background-color;
|
||||
margin: -$gl-padding;
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
|
||||
.pagination {
|
||||
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;
|
|||
//##
|
||||
|
||||
$pagination-color: $gl-gray;
|
||||
$pagination-bg: $background-color;
|
||||
$pagination-border: transparent;
|
||||
$pagination-bg: #fff;
|
||||
$pagination-border: $border-color;
|
||||
|
||||
$pagination-hover-color: #fff;
|
||||
$pagination-hover-bg: $brand-info;
|
||||
$pagination-hover-border: transparent;
|
||||
$pagination-hover-color: $gl-gray;
|
||||
$pagination-hover-bg: $hover;
|
||||
$pagination-hover-border: $border-color;
|
||||
|
||||
$pagination-active-color: #fff;
|
||||
$pagination-active-bg: $brand-info;
|
||||
$pagination-active-border: transparent;
|
||||
$pagination-active-color: $blue-dark;
|
||||
$pagination-active-bg: #fff;
|
||||
$pagination-active-border: $border-color;
|
||||
|
||||
$pagination-disabled-color: #fff;
|
||||
$pagination-disabled-bg: lighten($brand-info, 15%);
|
||||
$pagination-disabled-border: transparent;
|
||||
$pagination-disabled-color: #cdcdcd;
|
||||
$pagination-disabled-bg: $background-color;
|
||||
$pagination-disabled-border: $border-color;
|
||||
|
||||
|
||||
//== Form states and alerts
|
||||
|
|
|
@ -26,6 +26,7 @@ $gl-vert-padding: 6px;
|
|||
$gl-padding-top:10px;
|
||||
$gl-avatar-size: 46px;
|
||||
$secondary-text: #7f8fa4;
|
||||
$error-exclamation-point: #E62958;
|
||||
|
||||
/*
|
||||
* Color schema
|
||||
|
|
|
@ -1,20 +1,40 @@
|
|||
/* https://github.com/MozMorris/tomorrow-pygments */
|
||||
.code.dark {
|
||||
|
||||
background-color: #1d1f21 !important;
|
||||
color: #c5c8c6 !important;
|
||||
|
||||
pre.highlight,
|
||||
.line-numbers,
|
||||
.line-numbers a {
|
||||
background-color: #1d1f21 !important;
|
||||
color: #c5c8c6 !important;
|
||||
// Line numbers
|
||||
.line-numbers, .diff-line-num {
|
||||
background-color: #1d1f21;
|
||||
}
|
||||
|
||||
.diff-line-num, .diff-line-num a {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
// Code itself
|
||||
pre.code {
|
||||
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
|
||||
pre .hll {
|
||||
background-color: #557 !important;
|
||||
|
|
|
@ -1,20 +1,40 @@
|
|||
/* https://github.com/richleland/pygments-css/blob/master/monokai.css */
|
||||
.code.monokai {
|
||||
|
||||
background-color: #272822 !important;
|
||||
color: #f8f8f2 !important;
|
||||
|
||||
pre.highlight,
|
||||
.line-numbers,
|
||||
.line-numbers a {
|
||||
background-color :#272822 !important;
|
||||
color: #f8f8f2 !important;
|
||||
// Line numbers
|
||||
.line-numbers, .diff-line-num {
|
||||
background-color: #272822;
|
||||
}
|
||||
|
||||
.diff-line-num, .diff-line-num a {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
// Code itself
|
||||
pre.code {
|
||||
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
|
||||
pre .hll {
|
||||
background-color: #49483e !important;
|
||||
|
|
|
@ -1,20 +1,40 @@
|
|||
/* https://gist.github.com/qguv/7936275 */
|
||||
.code.solarized-dark {
|
||||
|
||||
background-color: #002b36 !important;
|
||||
color: #93a1a1 !important;
|
||||
|
||||
pre.highlight,
|
||||
.line-numbers,
|
||||
.line-numbers a {
|
||||
background-color: #002b36 !important;
|
||||
color: #93a1a1 !important;
|
||||
// Line numbers
|
||||
.line-numbers, .diff-line-num {
|
||||
background-color: #002b36;
|
||||
}
|
||||
|
||||
.diff-line-num, .diff-line-num a {
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
// Code itself
|
||||
pre.code {
|
||||
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
|
||||
pre .hll {
|
||||
background-color: #174652 !important;
|
||||
|
|
|
@ -1,20 +1,40 @@
|
|||
/* https://gist.github.com/qguv/7936275 */
|
||||
.code.solarized-light {
|
||||
|
||||
background-color: #fdf6e3 !important;
|
||||
color: #586e75 !important;
|
||||
|
||||
pre.highlight,
|
||||
.line-numbers,
|
||||
.line-numbers a {
|
||||
background-color: #fdf6e3 !important;
|
||||
color: #586e75 !important;
|
||||
// Line numbers
|
||||
.line-numbers, .diff-line-num {
|
||||
background-color: #fdf6e3;
|
||||
}
|
||||
|
||||
.diff-line-num, .diff-line-num a {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
// Code itself
|
||||
pre.code {
|
||||
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
|
||||
pre .hll {
|
||||
background-color: #ddd8c5 !important;
|
||||
|
|
|
@ -1,20 +1,60 @@
|
|||
/* https://github.com/aahan/pygments-github-style */
|
||||
.code.white {
|
||||
|
||||
background-color: #f8fafc !important;
|
||||
color: #5b6169 !important;
|
||||
|
||||
pre.highlight,
|
||||
.line-numbers,
|
||||
.line-numbers a {
|
||||
background-color: $background-color !important;
|
||||
color: $gl-gray !important;
|
||||
// Line numbers
|
||||
.line-numbers, .diff-line-num {
|
||||
background-color: $background-color;
|
||||
}
|
||||
|
||||
.diff-line-num, .diff-line-num a {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
// Code itself
|
||||
pre.code {
|
||||
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
|
||||
|
|
|
@ -32,16 +32,6 @@
|
|||
background: #FFF;
|
||||
color: #333;
|
||||
|
||||
.old {
|
||||
span.idiff {
|
||||
background-color: #f8cbcb;
|
||||
}
|
||||
}
|
||||
.new {
|
||||
span.idiff {
|
||||
background-color: #a6f3a6;
|
||||
}
|
||||
}
|
||||
.unfold {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -76,7 +66,7 @@
|
|||
}
|
||||
|
||||
tr.line_holder.parallel {
|
||||
.old_line, .new_line, .diff_line {
|
||||
.old_line, .new_line {
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
|
@ -85,7 +75,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.old_line, .new_line, .diff_line {
|
||||
.old_line, .new_line {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
|
@ -107,43 +97,12 @@
|
|||
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 {
|
||||
display: block;
|
||||
margin: 0px;
|
||||
padding: 0px 0.5em;
|
||||
border: none;
|
||||
&.new {
|
||||
background: #eaffea;
|
||||
}
|
||||
&.old {
|
||||
background: #ffecec;
|
||||
}
|
||||
&.matched {
|
||||
color: $border-color;
|
||||
background: #fafafa;
|
||||
}
|
||||
&.parallel {
|
||||
display: table-cell;
|
||||
}
|
||||
|
@ -393,3 +352,15 @@
|
|||
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 @@
|
|||
.mr-source-target {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,18 +10,6 @@
|
|||
margin: 10px $gl-padding;
|
||||
}
|
||||
.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 {
|
||||
opacity: 1.0;
|
||||
filter: alpha(opacity=100);
|
||||
|
|
|
@ -242,11 +242,8 @@ ul.notes {
|
|||
|
||||
// "show" the icon also if we just hover somewhere over the line
|
||||
&:hover > td {
|
||||
background: $hover !important;
|
||||
|
||||
.add-diff-note {
|
||||
@include show-add-diff-note;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -558,3 +558,9 @@ pre.light-well {
|
|||
width: 101%;
|
||||
}
|
||||
}
|
||||
|
||||
.cannot-be-merged,
|
||||
.cannot-be-merged:hover {
|
||||
color: #E62958;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
border-bottom: 1px solid #DDD;
|
||||
padding-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.term {
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,9 +74,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
:metrics_timeout,
|
||||
:metrics_method_call_threshold,
|
||||
:metrics_sample_interval,
|
||||
:ip_blocking_enabled,
|
||||
:dnsbl_servers_list,
|
||||
:recaptcha_enabled,
|
||||
:recaptcha_site_key,
|
||||
:recaptcha_private_key,
|
||||
:sentry_enabled,
|
||||
:sentry_dsn,
|
||||
restricted_visibility_levels: [],
|
||||
import_sources: []
|
||||
)
|
||||
|
|
|
@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base
|
|||
before_action :check_password_expiration
|
||||
before_action :check_2fa_requirement
|
||||
before_action :ldap_security_check
|
||||
before_action :sentry_user_context
|
||||
before_action :default_headers
|
||||
before_action :add_gon_variables
|
||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||
|
@ -24,6 +25,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
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 :repository
|
||||
|
||||
rescue_from Encoding::CompatibilityError do |exception|
|
||||
log_exception(exception)
|
||||
|
@ -41,6 +43,16 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
protected
|
||||
|
||||
def sentry_user_context
|
||||
if Rails.env.production? && current_application_settings.sentry_enabled && current_user
|
||||
Raven.user_context(
|
||||
id: current_user.id,
|
||||
email: current_user.email,
|
||||
username: current_user.username,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
|
||||
# https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
|
||||
def authenticate_user_from_token!
|
||||
|
|
|
@ -97,7 +97,7 @@ module CreatesCommit
|
|||
# Merge request from fork to this project
|
||||
@mr_source_project = @tree_edit_project
|
||||
@mr_target_project = @project
|
||||
@mr_target_branch = @mr_target_project.repository.root_ref
|
||||
@mr_target_branch = @ref
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
def preview
|
||||
@content = params[:content]
|
||||
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
|
||||
end
|
||||
|
@ -65,8 +67,9 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def diff
|
||||
@form = UnfoldForm.new(params)
|
||||
@lines = @blob.data.lines[@form.since - 1..@form.to - 1]
|
||||
@form = UnfoldForm.new(params)
|
||||
@lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path)
|
||||
@lines = @lines[@form.since - 1..@form.to - 1]
|
||||
|
||||
if @form.bottom?
|
||||
@match_line = ''
|
||||
|
|
|
@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
|
|||
@diffs = commit.diffs
|
||||
end
|
||||
|
||||
@diff_refs = [commit.parent || commit, commit]
|
||||
@notes_count = commit.notes.count
|
||||
|
||||
@statuses = ci_commit.statuses if ci_commit
|
||||
|
|
|
@ -21,7 +21,8 @@ class Projects::CompareController < Projects::ApplicationController
|
|||
@commits = Commit.decorate(compare_result.commits, @project)
|
||||
@diffs = compare_result.diffs
|
||||
@commit = @project.commit(head_ref)
|
||||
@first_commit = @project.commit(base_ref)
|
||||
@base_commit = @project.commit(base_ref)
|
||||
@diff_refs = [@base_commit, @commit]
|
||||
@line_notes = []
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,7 +58,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
|
||||
def diffs
|
||||
@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_target = {
|
||||
|
@ -102,7 +106,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
@source_project = merge_request.source_project
|
||||
@commits = @merge_request.compare_commits.reverse
|
||||
@commit = @merge_request.last_commit
|
||||
@first_commit = @merge_request.first_commit
|
||||
@base_commit = @merge_request.diff_base_commit
|
||||
@diffs = @merge_request.compare_diffs
|
||||
|
||||
@ci_commit = @merge_request.ci_commit
|
||||
|
|
|
@ -8,6 +8,11 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
def create
|
||||
if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha
|
||||
if Gitlab::IpCheck.new(request.remote_ip).spam?
|
||||
flash[:alert] = 'Could not create an account. This IP is listed for spam.'
|
||||
return render action: 'new'
|
||||
end
|
||||
|
||||
super
|
||||
else
|
||||
flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code."
|
||||
|
|
|
@ -1,21 +1,10 @@
|
|||
module BlobHelper
|
||||
def highlight(blob_name, blob_content, nowrap: false, continue: false)
|
||||
@formatter ||= Rouge::Formatters::HTMLGitlab.new(
|
||||
nowrap: nowrap,
|
||||
cssclass: 'code highlight',
|
||||
lineanchors: true,
|
||||
lineanchorsid: 'LC'
|
||||
)
|
||||
def highlighter(blob_name, blob_content, nowrap: false)
|
||||
Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def no_highlight_files
|
||||
|
@ -37,10 +26,10 @@ module BlobHelper
|
|||
tree_join(ref, path),
|
||||
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' }
|
||||
elsif can_edit_blob?(blob)
|
||||
link_to "Edit", edit_path, class: 'btn btn-small'
|
||||
elsif can_edit_blob?(blob, project, ref)
|
||||
link_to "Edit", edit_path, class: 'btn'
|
||||
elsif can?(current_user, :fork_project, project)
|
||||
continue_params = {
|
||||
to: edit_path,
|
||||
|
@ -50,7 +39,7 @@ module BlobHelper
|
|||
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
|
||||
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
|
||||
|
||||
|
@ -61,11 +50,11 @@ module BlobHelper
|
|||
|
||||
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' }
|
||||
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' }
|
||||
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'
|
||||
elsif can?(current_user, :fork_project, project)
|
||||
continue_params = {
|
||||
|
|
|
@ -166,7 +166,7 @@ module CommitsHelper
|
|||
link_to(
|
||||
namespace_project_blob_path(project.namespace, project,
|
||||
tree_join(commit_sha, diff.new_path)),
|
||||
class: 'btn btn-small view-file js-view-file'
|
||||
class: 'btn view-file js-view-file'
|
||||
) do
|
||||
raw('View file @') + content_tag(:span, commit_sha[0..6],
|
||||
class: 'commit-short-id')
|
||||
|
|
|
@ -19,13 +19,13 @@ module DiffHelper
|
|||
end
|
||||
end
|
||||
|
||||
def safe_diff_files(diffs)
|
||||
def safe_diff_files(diffs, diff_refs)
|
||||
lines = 0
|
||||
safe_files = []
|
||||
diffs.first(allowed_diff_size).each do |diff|
|
||||
lines += diff.diff.lines.count
|
||||
break if lines > allowed_diff_lines
|
||||
safe_files << Gitlab::Diff::File.new(diff)
|
||||
safe_files << Gitlab::Diff::File.new(diff, diff_refs)
|
||||
end
|
||||
safe_files
|
||||
end
|
||||
|
@ -43,64 +43,6 @@ module DiffHelper
|
|||
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
|
||||
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, " ", 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, " ", line_code, type, line_new, full_line, line_code]
|
||||
lines.push(line)
|
||||
end
|
||||
end
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
def unfold_bottom_class(bottom)
|
||||
(bottom) ? 'js-unfold-bottom' : ''
|
||||
end
|
||||
|
@ -111,9 +53,9 @@ module DiffHelper
|
|||
|
||||
def diff_line_content(line)
|
||||
if line.blank?
|
||||
" "
|
||||
" ".html_safe
|
||||
else
|
||||
line
|
||||
line.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -160,8 +102,7 @@ module DiffHelper
|
|||
|
||||
def commit_for_diff(diff)
|
||||
if diff.deleted_file
|
||||
first_commit = @first_commit || @commit
|
||||
first_commit.parent || @first_commit
|
||||
@base_commit || @commit.parent || @commit
|
||||
else
|
||||
@commit
|
||||
end
|
||||
|
|
|
@ -3,13 +3,26 @@ module Emails
|
|||
def build_fail_email(build_id, to)
|
||||
@build = Ci::Build.find(build_id)
|
||||
@project = @build.project
|
||||
add_project_headers
|
||||
add_build_headers
|
||||
headers['X-GitLab-Build-Status'] = "failed"
|
||||
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
|
||||
end
|
||||
|
||||
def build_success_email(build_id, to)
|
||||
@build = Ci::Build.find(build_id)
|
||||
@project = @build.project
|
||||
add_project_headers
|
||||
add_build_headers
|
||||
headers['X-GitLab-Build-Status'] = "success"
|
||||
mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha))
|
||||
end
|
||||
|
||||
private
|
||||
def add_build_headers
|
||||
headers['X-GitLab-Build-Id'] = @build.id
|
||||
headers['X-GitLab-Build-Ref'] = @build.ref
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ module Emails
|
|||
@current_user = @created_by = User.find(created_by_id)
|
||||
@access_level = access_level
|
||||
@invite_email = invite_email
|
||||
|
||||
|
||||
@target_url = namespace_project_url(@project.namespace, @project)
|
||||
|
||||
mail(to: @created_by.notification_email,
|
||||
|
@ -65,6 +65,10 @@ module Emails
|
|||
|
||||
# used in notify layout
|
||||
@target_url = @message.target_url
|
||||
@project = Project.find project_id
|
||||
|
||||
add_project_headers
|
||||
headers['X-GitLab-Author'] = @message.author_username
|
||||
|
||||
mail(from: sender(@message.author_id, @message.send_from_committer_email?),
|
||||
reply_to: @message.reply_to,
|
||||
|
|
|
@ -100,12 +100,7 @@ class Notify < BaseMailer
|
|||
end
|
||||
|
||||
def mail_thread(model, headers = {})
|
||||
if @project
|
||||
headers['X-GitLab-Project'] = @project.name
|
||||
headers['X-GitLab-Project-Id'] = @project.id
|
||||
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
|
||||
end
|
||||
|
||||
add_project_headers
|
||||
headers["X-GitLab-#{model.class.name}-ID"] = model.id
|
||||
headers['X-GitLab-Reply-Key'] = reply_key
|
||||
|
||||
|
@ -152,4 +147,12 @@ class Notify < BaseMailer
|
|||
def reply_key
|
||||
@reply_key ||= SentNotification.reply_key
|
||||
end
|
||||
|
||||
def add_project_headers
|
||||
return unless @project
|
||||
|
||||
headers['X-GitLab-Project'] = @project.name
|
||||
headers['X-GitLab-Project-Id'] = @project.id
|
||||
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
# recaptcha_site_key :string
|
||||
# recaptcha_private_key :string
|
||||
# metrics_port :integer default(8089)
|
||||
# sentry_enabled :boolean default(FALSE)
|
||||
# sentry_dsn :string
|
||||
# ip_blocking_enabled :boolean default(FALSE)
|
||||
# dns_blacklist_threshold :float default(0.33)
|
||||
#
|
||||
|
||||
class ApplicationSetting < ActiveRecord::Base
|
||||
|
@ -82,6 +86,10 @@ class ApplicationSetting < ActiveRecord::Base
|
|||
presence: true,
|
||||
if: :recaptcha_enabled
|
||||
|
||||
validates :sentry_dsn,
|
||||
presence: true,
|
||||
if: :sentry_enabled
|
||||
|
||||
validates_each :restricted_visibility_levels do |record, attr, value|
|
||||
unless value.nil?
|
||||
value.each do |level|
|
||||
|
|
|
@ -346,17 +346,17 @@ module Ci
|
|||
end
|
||||
|
||||
def artifacts_browse_url
|
||||
if artifacts_browser_supported?
|
||||
if artifacts_metadata?
|
||||
browse_namespace_project_build_artifacts_path(project.namespace, project, self)
|
||||
end
|
||||
end
|
||||
|
||||
def artifacts_browser_supported?
|
||||
def artifacts_metadata?
|
||||
artifacts? && artifacts_metadata.exists?
|
||||
end
|
||||
|
||||
def artifacts_metadata_entry(path)
|
||||
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_entry
|
||||
def artifacts_metadata_entry(path, **options)
|
||||
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path, **options).to_entry
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -91,7 +91,7 @@ class Member < ActiveRecord::Base
|
|||
member.invite_email = user
|
||||
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.access_level = access_level
|
||||
|
||||
|
@ -107,6 +107,11 @@ class Member < ActiveRecord::Base
|
|||
current_user.can?(:update_group_member, member) ||
|
||||
current_user.can?(:update_project_member, member)
|
||||
end
|
||||
|
||||
def project_creator?(member, access_level)
|
||||
member.new_record? && member.owner? &&
|
||||
access_level.to_i == ProjectMember::MASTER
|
||||
end
|
||||
end
|
||||
|
||||
def invite?
|
||||
|
|
|
@ -84,7 +84,7 @@ class ProjectMember < Member
|
|||
def truncate_teams(project_ids)
|
||||
ProjectMember.transaction do
|
||||
members = ProjectMember.where(source_id: project_ids)
|
||||
|
||||
|
||||
members.each do |member|
|
||||
member.destroy
|
||||
end
|
||||
|
@ -133,13 +133,13 @@ class ProjectMember < Member
|
|||
event_service.join_project(self.project, self.user)
|
||||
notification_service.new_project_member(self)
|
||||
end
|
||||
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def post_update_hook
|
||||
if access_level_changed?
|
||||
notification_service.update_project_member(self)
|
||||
notification_service.update_project_member(self)
|
||||
end
|
||||
|
||||
super
|
||||
|
|
|
@ -180,6 +180,14 @@ class MergeRequest < ActiveRecord::Base
|
|||
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
|
||||
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
|
||||
last_commit.short_id
|
||||
end
|
||||
|
@ -254,7 +262,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def mergeable?
|
||||
return false unless open? && !work_in_progress?
|
||||
return false unless open? && !work_in_progress? && !broken?
|
||||
|
||||
check_if_can_be_merged
|
||||
|
||||
|
@ -477,8 +485,7 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def target_sha
|
||||
@target_sha ||= target_project.
|
||||
repository.commit(target_branch).sha
|
||||
@target_sha ||= target_project.repository.commit(target_branch).sha
|
||||
end
|
||||
|
||||
def source_sha
|
||||
|
@ -517,4 +524,10 @@ class MergeRequest < ActiveRecord::Base
|
|||
def ci_commit
|
||||
@ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project
|
||||
end
|
||||
|
||||
def diff_refs
|
||||
return nil unless diff_base_commit
|
||||
|
||||
[diff_base_commit, last_commit]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -73,6 +73,12 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
commits.last
|
||||
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
|
||||
@last_commit_short_sha ||= last_commit.short_id
|
||||
end
|
||||
|
@ -156,6 +162,9 @@ class MergeRequestDiff < ActiveRecord::Base
|
|||
end
|
||||
|
||||
self.st_diffs = new_diffs
|
||||
|
||||
self.base_commit_sha = merge_request.target_project.commit(target_branch).try(:sha)
|
||||
|
||||
self.save
|
||||
end
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class Note < ActiveRecord::Base
|
|||
participant :author
|
||||
|
||||
belongs_to :project
|
||||
belongs_to :noteable, polymorphic: true
|
||||
belongs_to :noteable, polymorphic: true, touch: true
|
||||
belongs_to :author, class_name: "User"
|
||||
belongs_to :updated_by, class_name: "User"
|
||||
|
||||
|
@ -244,7 +244,7 @@ class Note < ActiveRecord::Base
|
|||
prev_match_line = nil
|
||||
prev_lines = []
|
||||
|
||||
diff_lines.each do |line|
|
||||
highlighted_diff_lines.each do |line|
|
||||
if line.type == "match"
|
||||
prev_lines.clear
|
||||
prev_match_line = line
|
||||
|
@ -261,7 +261,11 @@ class Note < ActiveRecord::Base
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def discussion_id
|
||||
|
|
|
@ -272,6 +272,10 @@ class Project < ActiveRecord::Base
|
|||
query: "%#{query.try(:downcase)}%")
|
||||
end
|
||||
|
||||
def search_by_visibility(level)
|
||||
where(visibility_level: Gitlab::VisibilityLevel.const_get(level.upcase))
|
||||
end
|
||||
|
||||
def search_by_title(query)
|
||||
where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
|
||||
end
|
||||
|
@ -468,12 +472,9 @@ class Project < ActiveRecord::Base
|
|||
!external_issue_tracker
|
||||
end
|
||||
|
||||
def external_issues_trackers
|
||||
services.select(&:issue_tracker?).reject(&:default?)
|
||||
end
|
||||
|
||||
def external_issue_tracker
|
||||
@external_issues_tracker ||= external_issues_trackers.find(&:activated?)
|
||||
@external_issue_tracker ||=
|
||||
services.issue_trackers.active.without_defaults.first
|
||||
end
|
||||
|
||||
def can_have_issues_tracker_id?
|
||||
|
|
|
@ -23,14 +23,12 @@
|
|||
# List methods you need to implement to get your CI service
|
||||
# working with GitLab Merge Requests
|
||||
class CiService < Service
|
||||
def category
|
||||
:ci
|
||||
end
|
||||
|
||||
default_value_for :category, 'ci'
|
||||
|
||||
def valid_token?(token)
|
||||
self.respond_to?(:token) && self.token.present? && self.token == token
|
||||
end
|
||||
|
||||
|
||||
def supported_events
|
||||
%w(push)
|
||||
end
|
||||
|
|
|
@ -24,9 +24,7 @@ class GitlabIssueTrackerService < IssueTrackerService
|
|||
|
||||
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
||||
|
||||
def default?
|
||||
true
|
||||
end
|
||||
default_value_for :default, true
|
||||
|
||||
def to_param
|
||||
'gitlab'
|
||||
|
|
|
@ -23,12 +23,10 @@ class IssueTrackerService < Service
|
|||
|
||||
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
|
||||
|
||||
def category
|
||||
:issue_tracker
|
||||
end
|
||||
default_value_for :category, 'issue_tracker'
|
||||
|
||||
def default?
|
||||
false
|
||||
default
|
||||
end
|
||||
|
||||
def issue_url(iid)
|
||||
|
|
|
@ -43,6 +43,9 @@ class Service < ActiveRecord::Base
|
|||
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
|
||||
|
||||
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
|
||||
scope :issue_trackers, -> { where(category: 'issue_tracker') }
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :without_defaults, -> { where(default: false) }
|
||||
|
||||
scope :push_hooks, -> { where(push_events: true, active: true) }
|
||||
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
|
||||
|
@ -51,6 +54,8 @@ class Service < ActiveRecord::Base
|
|||
scope :note_hooks, -> { where(note_events: true, active: true) }
|
||||
scope :build_hooks, -> { where(build_events: true, active: true) }
|
||||
|
||||
default_value_for :category, 'common'
|
||||
|
||||
def activated?
|
||||
active
|
||||
end
|
||||
|
@ -60,7 +65,7 @@ class Service < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def category
|
||||
:common
|
||||
read_attribute(:category).to_sym
|
||||
end
|
||||
|
||||
def initialize_properties
|
||||
|
@ -153,7 +158,7 @@ class Service < ActiveRecord::Base
|
|||
|
||||
# Returns a hash of the properties that have been assigned a new value since last save,
|
||||
# indicating their original values (attr => original value).
|
||||
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
|
||||
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
|
||||
# so we need a specific implementation for service properties.
|
||||
# This allows to track changes to properties set with the accessor methods,
|
||||
# but not direct manipulation of properties hash.
|
||||
|
@ -164,7 +169,7 @@ class Service < ActiveRecord::Base
|
|||
def reset_updated_properties
|
||||
@updated_properties = nil
|
||||
end
|
||||
|
||||
|
||||
def async_execute(data)
|
||||
return unless supported_events.include?(data[:object_kind])
|
||||
|
||||
|
|
|
@ -664,7 +664,10 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def all_emails
|
||||
[self.email, *self.emails.map(&:email)]
|
||||
all_emails = []
|
||||
all_emails << self.email unless self.temp_oauth_email?
|
||||
all_emails.concat(self.emails.map(&:email))
|
||||
all_emails
|
||||
end
|
||||
|
||||
def hook_attrs
|
||||
|
|
|
@ -376,10 +376,10 @@ class NotificationService
|
|||
end
|
||||
|
||||
def reassign_resource_email(target, project, current_user, method)
|
||||
previous_assignee_id = previous_record(target, "assignee_id")
|
||||
previous_assignee_id = previous_record(target, 'assignee_id')
|
||||
previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
|
||||
|
||||
recipients = build_recipients(target, project, current_user, [previous_assignee])
|
||||
recipients = build_recipients(target, project, current_user, action: :reassign, previous_assignee: previous_assignee)
|
||||
|
||||
recipients.each do |recipient|
|
||||
mailer.send(
|
||||
|
@ -400,22 +400,27 @@ class NotificationService
|
|||
end
|
||||
end
|
||||
|
||||
def build_recipients(target, project, current_user, extra_recipients = nil)
|
||||
def build_recipients(target, project, current_user, action: nil, previous_assignee: nil)
|
||||
recipients = target.participants(current_user)
|
||||
|
||||
recipients = recipients.concat(extra_recipients).compact.uniq if extra_recipients
|
||||
|
||||
recipients = add_project_watchers(recipients, project)
|
||||
recipients = reject_mention_users(recipients, project)
|
||||
recipients = reject_muted_users(recipients, project)
|
||||
|
||||
# Re-assign is considered as a mention of the new assignee so we add the
|
||||
# new assignee to the list of recipients after we rejected users with
|
||||
# the "on mention" notification level
|
||||
if action == :reassign
|
||||
recipients << previous_assignee if previous_assignee
|
||||
recipients << target.assignee
|
||||
end
|
||||
|
||||
recipients = reject_muted_users(recipients, project)
|
||||
recipients = add_subscribed_users(recipients, target)
|
||||
recipients = reject_unsubscribed_users(recipients, target)
|
||||
|
||||
recipients.delete(current_user)
|
||||
recipients = recipients.uniq
|
||||
|
||||
recipients
|
||||
recipients.uniq
|
||||
end
|
||||
|
||||
def mailer
|
||||
|
|
|
@ -212,6 +212,22 @@
|
|||
|
||||
%fieldset
|
||||
%legend Spam and Anti-bot Protection
|
||||
.form-group
|
||||
.col-sm-offset-2.col-sm-10
|
||||
.checkbox
|
||||
= f.label :ip_blocking_enabled do
|
||||
= f.check_box :ip_blocking_enabled
|
||||
Enable IP check against blacklist at sign-up
|
||||
.help-block Helps preventing accounts creation from 'known spam sources'
|
||||
|
||||
.form-group
|
||||
= f.label :dnsbl_servers_list, class: 'control-label col-sm-2' do
|
||||
DNSBL servers list
|
||||
.col-sm-10
|
||||
= f.text_field :dnsbl_servers_list, class: 'form-control'
|
||||
.help-block
|
||||
Please enter DNSBL servers separated with comma
|
||||
|
||||
.form-group
|
||||
.col-sm-offset-2.col-sm-10
|
||||
.checkbox
|
||||
|
@ -226,11 +242,30 @@
|
|||
= f.text_field :recaptcha_site_key, class: 'form-control'
|
||||
.help-block
|
||||
Generate site and private keys here:
|
||||
%a{ href: 'http://www.google.com/recaptcha', target: 'blank'} http://www.google.com/recaptcha
|
||||
%a{ href: 'http://www.google.com/recaptcha', target: '_blank'} http://www.google.com/recaptcha
|
||||
.form-group
|
||||
= f.label :recaptcha_private_key, 'reCAPTCHA Private Key', class: 'control-label col-sm-2'
|
||||
.col-sm-10
|
||||
= f.text_field :recaptcha_private_key, class: 'form-control'
|
||||
|
||||
%fieldset
|
||||
%legend Error Reporting and Logging
|
||||
%p
|
||||
These settings require a restart to take effect.
|
||||
.form-group
|
||||
.col-sm-offset-2.col-sm-10
|
||||
.checkbox
|
||||
= f.label :sentry_enabled do
|
||||
= f.check_box :sentry_enabled
|
||||
Enable Sentry
|
||||
.help-block
|
||||
Sentry is an error reporting and logging tool which is currently not shipped with GitLab, get it here:
|
||||
%a{ href: 'https://getsentry.com', target: '_blank' } https://getsentry.com
|
||||
|
||||
.form-group
|
||||
= f.label :sentry_dsn, 'Sentry DSN', class: 'control-label col-sm-2'
|
||||
.col-sm-10
|
||||
= f.text_field :sentry_dsn, class: 'form-control'
|
||||
|
||||
.form-actions
|
||||
= f.submit 'Save', class: 'btn btn-primary'
|
||||
|
|
|
@ -5,5 +5,9 @@
|
|||
-# num_pages: total number of pages
|
||||
-# per_page: number of items to fetch per page
|
||||
-# remote: data-remote
|
||||
%li.next
|
||||
= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
|
||||
- if current_page.last?
|
||||
%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 @@
|
|||
%ul.pagination.clearfix
|
||||
- unless current_page.first?
|
||||
= 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|
|
||||
- if page.left_outer? || page.right_outer? || page.inside_window?
|
||||
= page_tag page
|
||||
- elsif !page.was_truncated?
|
||||
= gap_tag
|
||||
= next_page_tag
|
||||
- unless current_page.last?
|
||||
= next_page_tag
|
||||
= last_page_tag unless num_pages < 5
|
||||
|
||||
|
|
|
@ -5,5 +5,9 @@
|
|||
-# num_pages: total number of pages
|
||||
-# per_page: number of items to fetch per page
|
||||
-# remote: data-remote
|
||||
%li{class: "prev" }
|
||||
= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote
|
||||
- if current_page.first?
|
||||
%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
|
||||
|
|
|
@ -37,3 +37,6 @@
|
|||
%h1.title= title
|
||||
|
||||
= render 'shared/outdated_browser'
|
||||
- if @project && !@project.empty_repo?
|
||||
:javascript
|
||||
var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, @ref || @project.repository.root_ref)}";
|
|
@ -21,10 +21,10 @@
|
|||
.form-group
|
||||
= f.label :email, class: "control-label"
|
||||
.col-sm-10
|
||||
- if @user.ldap_user?
|
||||
- if @user.ldap_user? && @user.ldap_email?
|
||||
= f.text_field :email, class: "form-control", required: true, readonly: true
|
||||
%span.help-block.light
|
||||
Email is read-only for LDAP user
|
||||
Your email address was automatically set based on the LDAP server.
|
||||
- else
|
||||
- if @user.temp_oauth_email?
|
||||
= f.text_field :email, class: "form-control", required: true, value: nil
|
||||
|
|
|
@ -6,4 +6,3 @@
|
|||
%span.str-truncated
|
||||
= link_to directory.name, path_to_directory
|
||||
%td
|
||||
%td
|
||||
|
|
|
@ -7,5 +7,3 @@
|
|||
= link_to file.name, path_to_file
|
||||
%td
|
||||
= number_to_human_size(file.metadata[:size], precision: 2)
|
||||
%td
|
||||
= number_to_human_size(file.metadata[:zipped], precision: 2)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.top-block.gray-content-block.clearfix
|
||||
.pull-right
|
||||
= 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')
|
||||
Download artifacts archive
|
||||
|
||||
|
@ -15,14 +15,8 @@
|
|||
%tr
|
||||
%th Name
|
||||
%th Size
|
||||
%th Compressed to
|
||||
= render partial: 'tree_directory', collection: @entry.directories(parent: true), as: :directory
|
||||
= render partial: 'tree_file', collection: @entry.files, as: :file
|
||||
|
||||
- if @entry.empty?
|
||||
.center Empty
|
||||
|
||||
:javascript
|
||||
$(document).on('click', 'tr[data-link]', function(e) {
|
||||
window.location = this.dataset.link;
|
||||
});
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
%small= number_to_human_size @blob.size
|
||||
.file-actions
|
||||
= render "projects/blob/actions"
|
||||
.file-content.blame.highlight
|
||||
.file-content.blame.code.js-syntax-highlight
|
||||
%table
|
||||
- current_line = 1
|
||||
- blame_highlighter = highlighter(@blob.name, @blob.data, nowrap: true)
|
||||
- @blame.each do |blame_group|
|
||||
%tr
|
||||
%td.blame-commit
|
||||
|
@ -30,16 +31,15 @@
|
|||
= commit_author_link(commit, avatar: false)
|
||||
authored
|
||||
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)}
|
||||
%td.lines.blame-numbers
|
||||
%pre
|
||||
- line_count = blame_group[:lines].count
|
||||
- (current_line...(current_line + line_count)).each do |i|
|
||||
= i
|
||||
\
|
||||
- current_line += line_count
|
||||
%td.line-numbers
|
||||
- line_count = blame_group[:lines].count
|
||||
- (current_line...(current_line + line_count)).each do |i|
|
||||
%a.diff-line-num= i
|
||||
\
|
||||
- current_line += line_count
|
||||
%td.lines
|
||||
%pre{class: 'code highlight white'}
|
||||
%pre{class: 'code highlight'}
|
||||
%code
|
||||
- blame_group[:lines].each do |line|
|
||||
:erb
|
||||
<%= highlight(@blob.name, line, nowrap: true, continue: true).html_safe %>
|
||||
:preserve
|
||||
#{blame_highlighter.highlight(line)}
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
%tr.line_holder
|
||||
%td.old_line.diff-line-num{data: {linenumber: line_old}}
|
||||
= link_to raw(line_old), "#"
|
||||
%td.new_line= link_to raw(line_new) , "#"
|
||||
%td.line_content.noteable_line= ' ' * @form.indent + line
|
||||
%td.new_line.diff-line-num
|
||||
= link_to raw(line_new) , "#"
|
||||
%td.line_content.noteable_line==#{' ' * @form.indent}#{line}
|
||||
|
||||
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
|
||||
%tr.line_holder{ id: @form.to }
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
- @diff_lines.each do |line|
|
||||
%tr.line_holder{ class: "#{line.type}" }
|
||||
- if line.type == "match"
|
||||
%td.old_line= "..."
|
||||
%td.new_line= "..."
|
||||
%td.line_content.matched= line.text
|
||||
%td.old_line.diff-line-num= "..."
|
||||
%td.new_line.diff-line-num= "..."
|
||||
%td.line_content.match= line.text
|
||||
- else
|
||||
%td.old_line
|
||||
%td.new_line
|
||||
%td.line_content{class: "#{line.type}"}= raw diff_line_content(line.text)
|
||||
%td.old_line.diff-line-num
|
||||
%td.new_line.diff-line-num
|
||||
%td.line_content{class: "#{line.type}"}= diff_line_content(line.text)
|
||||
- else
|
||||
.nothing-here-block No changes.
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
- if can?(current_user, :manage_builds, @project)
|
||||
.pull-left.hidden-xs
|
||||
- if @all_builds.running_or_pending.any?
|
||||
= link_to 'Cancel running', cancel_all_namespace_project_builds_path(@project.namespace, @project), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
|
||||
= link_to 'Cancel running', cancel_all_namespace_project_builds_path(@project.namespace, @project),
|
||||
data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
|
||||
|
||||
= link_to ci_lint_path, class: 'btn btn-default' do
|
||||
= icon('wrench')
|
||||
%span CI Lint
|
||||
|
||||
%ul.nav-links
|
||||
%li{class: ('active' if @scope.nil?)}
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
.center
|
||||
.btn-group{ role: :group }
|
||||
= 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'
|
||||
|
||||
.build-widget
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
= render "ci_menu"
|
||||
- else
|
||||
%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"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
- if @commits.present?
|
||||
.prepend-top-default
|
||||
= 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
|
||||
.light-well.prepend-top-default
|
||||
.center
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- if diff_view == 'parallel'
|
||||
- fluid_layout true
|
||||
|
||||
- diff_files = safe_diff_files(diffs)
|
||||
- diff_files = safe_diff_files(diffs, diff_refs)
|
||||
|
||||
.content-block.oneline-block
|
||||
.inline-parallel-buttons
|
||||
|
|
|
@ -1,39 +1,37 @@
|
|||
.diff-file{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
|
||||
.diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"}
|
||||
.diff-file.file-holder{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
|
||||
.file-title{id: "file-path-#{hexdigest(diff_file.file_path)}"}
|
||||
- if diff_file.diff.submodule?
|
||||
%span
|
||||
= icon('archive fw')
|
||||
%strong
|
||||
= submodule_link(blob, @commit.id, project.repository)
|
||||
- else
|
||||
%span
|
||||
= blob_icon blob.mode, blob.name
|
||||
= link_to "#diff-#{i}" do
|
||||
%strong
|
||||
= diff_file.new_path
|
||||
= blob_icon blob.mode, blob.name
|
||||
= link_to "#diff-#{i}" do
|
||||
%strong
|
||||
= diff_file.new_path
|
||||
|
||||
- if diff_file.deleted_file
|
||||
deleted
|
||||
- elsif diff_file.renamed_file
|
||||
renamed from
|
||||
%strong
|
||||
= diff_file.old_path
|
||||
- if diff_file.deleted_file
|
||||
deleted
|
||||
- elsif diff_file.renamed_file
|
||||
renamed from
|
||||
%strong
|
||||
= diff_file.old_path
|
||||
|
||||
- if diff_file.mode_changed?
|
||||
%small
|
||||
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
|
||||
- if diff_file.mode_changed?
|
||||
%small
|
||||
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
|
||||
|
||||
.diff-controls
|
||||
.file-actions.hidden-xs
|
||||
- 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
|
||||
%i.fa.fa-comments
|
||||
|
||||
= link_to '#', class: 'js-toggle-diff-comments btn active has_tooltip', title: "Toggle comments for this file" do
|
||||
= icon('comments')
|
||||
\
|
||||
|
||||
- if editable_diff?(diff_file)
|
||||
= edit_blob_link(@merge_request.source_project,
|
||||
@merge_request.source_branch, diff_file.new_path,
|
||||
from_merge_request_id: @merge_request.id)
|
||||
|
||||
|
||||
= view_file_btn(diff_commit.id, diff_file, project)
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
%td.new_line.diff-line-num{data: {linenumber: line_new},
|
||||
class: [unfold_bottom_class(bottom), unfold_class(!new_file)]}
|
||||
\...
|
||||
%td.line_content.matched= line
|
||||
%td.line_content.match= line
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue