Commit 3b73db5a authored by Valery Sizov's avatar Valery Sizov

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into ce-upstream

parents ac70bdcd a8b7ac91
image: "ruby:2.1" image: "ruby:2.2"
services: services:
- mysql:latest - mysql:latest
...@@ -134,3 +134,26 @@ bundler:audit: ...@@ -134,3 +134,26 @@ bundler:audit:
- ruby - ruby
- mysql - mysql
allow_failure: true allow_failure: true
# Ruby 2.1 jobs
spec:ruby21:
image: ruby:2.1
script:
- RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec
tags:
- ruby
- mysql
only:
- master
spinach:ruby21:
image: ruby:2.1
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach
tags:
- ruby
- mysql
only:
- master
Please view this file on the master branch, on stable branches it's out of date. 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)
- Ensure rake tasks that don't need a DB connection can be run without one
- Add "visibility" flag to GET /projects api endpoint - Add "visibility" flag to GET /projects api endpoint
- Ignore binary files in code search to prevent Error 500 (Stan Hu) - Ignore binary files in code search to prevent Error 500 (Stan Hu)
- 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 - New UI for pagination
- Don't prevent sign out when 2FA enforcement is enabled and user hasn't yet
set it up
- Fix diff comments loaded by AJAX to load comment with diff in discussion tab - Fix diff comments loaded by AJAX to load comment with diff in discussion tab
- Whitelist raw "abbr" elements when parsing Markdown (Benedict Etzel) - Whitelist raw "abbr" elements when parsing Markdown (Benedict Etzel)
- Don't vendor minified JS - Don't vendor minified JS
- Display 404 error on group not found
- Track project import failure
- Fix visibility level text in admin area (Zeger-Jan van de Weg)
- Update the ExternalIssue regex pattern (Blake Hitchcock)
- Revert "Add IP check against DNSBLs at account sign-up"
- Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead
- Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead
v 8.4.3
- Increase lfs_objects size column to 8-byte integer to allow files larger than 2.1GB
v 8.4.2
- Bump required gitlab-workhorse version to bring in a fix for missing
artifacts in the build artifacts browser
- Get rid of those ugly borders on the file tree view
- Fix updating the runner information when asking for builds
- Bump gitlab_git version to 7.2.24 in order to bring in a performance
improvement when checking if a repository was empty
- Add instrumentation for Gitlab::Git::Repository instance methods so we can
track them in Performance Monitoring.
- Correctly highlight MR diff when MR has merge conflicts
- Increase contrast between highlighted code comments and inline diff marker
- Fix method undefined when using external commit status in builds
- Fix highlighting in blame view.
v 8.4.1
- Apply security updates for Rails (4.2.5.1), rails-html-sanitizer (1.0.3),
and Nokogiri (1.6.7.2)
- Fix redirect loop during import
- Fix diff highlighting for all syntax themes
v 8.4.0 (unreleased) v 8.4.0 (unreleased)
- Hide issues settings when issues are disabled (Hannes Rosenögger) - Hide issues settings when issues are disabled (Hannes Rosenögger)
......
source "https://rubygems.org" source "https://rubygems.org"
gem 'rails', '4.2.5' gem 'rails', '4.2.5.1'
gem 'rails-deprecated_sanitizer', '~> 1.0.3' gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Responders respond_to and respond_with # Responders respond_to and respond_with
...@@ -110,7 +110,8 @@ gem 'asciidoctor', '~> 1.5.2' ...@@ -110,7 +110,8 @@ gem 'asciidoctor', '~> 1.5.2'
gem 'rouge', '~> 1.10.1' gem 'rouge', '~> 1.10.1'
# See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s # See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
gem 'nokogiri', '1.6.7.1' # and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
gem 'nokogiri', '1.6.7.2'
# Diffs # Diffs
gem 'diffy', '~> 3.0.3' gem 'diffy', '~> 3.0.3'
...@@ -308,7 +309,7 @@ end ...@@ -308,7 +309,7 @@ end
gem "newrelic_rpm", '~> 3.9.4.245' gem "newrelic_rpm", '~> 3.9.4.245'
gem 'newrelic-grape' gem 'newrelic-grape'
gem 'octokit', '~> 3.7.0' gem 'octokit', '~> 3.8.0'
gem "mail_room", "~> 0.6.1" gem "mail_room", "~> 0.6.1"
......
...@@ -4,41 +4,41 @@ GEM ...@@ -4,41 +4,41 @@ GEM
CFPropertyList (2.3.2) CFPropertyList (2.3.2)
RedCloth (4.2.9) RedCloth (4.2.9)
ace-rails-ap (2.0.1) ace-rails-ap (2.0.1)
actionmailer (4.2.5) actionmailer (4.2.5.1)
actionpack (= 4.2.5) actionpack (= 4.2.5.1)
actionview (= 4.2.5) actionview (= 4.2.5.1)
activejob (= 4.2.5) activejob (= 4.2.5.1)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.5) actionpack (4.2.5.1)
actionview (= 4.2.5) actionview (= 4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
rack (~> 1.6) rack (~> 1.6)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.5) actionview (4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (4.2.5) activejob (4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
globalid (>= 0.3.0) globalid (>= 0.3.0)
activemodel (4.2.5) activemodel (4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
builder (~> 3.1) builder (~> 3.1)
activerecord (4.2.5) activerecord (4.2.5.1)
activemodel (= 4.2.5) activemodel (= 4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
arel (~> 6.0) arel (~> 6.0)
activerecord-deprecated_finders (1.0.4) activerecord-deprecated_finders (1.0.4)
activerecord-session_store (0.1.2) activerecord-session_store (0.1.2)
actionpack (>= 4.0.0, < 5) actionpack (>= 4.0.0, < 5)
activerecord (>= 4.0.0, < 5) activerecord (>= 4.0.0, < 5)
railties (>= 4.0.0, < 5) railties (>= 4.0.0, < 5)
activesupport (4.2.5) activesupport (4.2.5.1)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
...@@ -506,7 +506,7 @@ GEM ...@@ -506,7 +506,7 @@ GEM
grape grape
newrelic_rpm newrelic_rpm
newrelic_rpm (3.9.4.245) newrelic_rpm (3.9.4.245)
nokogiri (1.6.7.1) nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2) mini_portile2 (~> 2.0.0.rc2)
nprogress-rails (0.1.6.7) nprogress-rails (0.1.6.7)
oauth (0.4.7) oauth (0.4.7)
...@@ -516,7 +516,7 @@ GEM ...@@ -516,7 +516,7 @@ GEM
multi_json (~> 1.3) multi_json (~> 1.3)
multi_xml (~> 0.5) multi_xml (~> 0.5)
rack (~> 1.2) rack (~> 1.2)
octokit (3.7.1) octokit (3.8.0)
sawyer (~> 0.6.0, >= 0.5.3) sawyer (~> 0.6.0, >= 0.5.3)
omniauth (1.2.2) omniauth (1.2.2)
hashie (>= 1.2, < 4) hashie (>= 1.2, < 4)
...@@ -612,16 +612,16 @@ GEM ...@@ -612,16 +612,16 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.5) rails (4.2.5.1)
actionmailer (= 4.2.5) actionmailer (= 4.2.5.1)
actionpack (= 4.2.5) actionpack (= 4.2.5.1)
actionview (= 4.2.5) actionview (= 4.2.5.1)
activejob (= 4.2.5) activejob (= 4.2.5.1)
activemodel (= 4.2.5) activemodel (= 4.2.5.1)
activerecord (= 4.2.5) activerecord (= 4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.5) railties (= 4.2.5.1)
sprockets-rails sprockets-rails
rails-deprecated_sanitizer (1.0.3) rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha) activesupport (>= 4.2.0.alpha)
...@@ -629,11 +629,11 @@ GEM ...@@ -629,11 +629,11 @@ GEM
activesupport (>= 4.2.0.beta, < 5.0) activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0) nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1) rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.2) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (4.2.5) railties (4.2.5.1)
actionpack (= 4.2.5) actionpack (= 4.2.5.1)
activesupport (= 4.2.5) activesupport (= 4.2.5.1)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.0.0) rainbow (2.0.0)
...@@ -749,7 +749,7 @@ GEM ...@@ -749,7 +749,7 @@ GEM
activesupport (>= 3.1, < 4.3) activesupport (>= 3.1, < 4.3)
select2-rails (3.5.9.3) select2-rails (3.5.9.3)
thor (~> 0.14) thor (~> 0.14)
sentry-raven (0.15.3) sentry-raven (0.15.4)
faraday (>= 0.7.6) faraday (>= 0.7.6)
settingslogic (2.0.9) settingslogic (2.0.9)
sexp_processor (4.6.0) sexp_processor (4.6.0)
...@@ -992,10 +992,10 @@ DEPENDENCIES ...@@ -992,10 +992,10 @@ DEPENDENCIES
net-ssh (~> 3.0.1) net-ssh (~> 3.0.1)
newrelic-grape newrelic-grape
newrelic_rpm (~> 3.9.4.245) newrelic_rpm (~> 3.9.4.245)
nokogiri (= 1.6.7.1) nokogiri (= 1.6.7.2)
nprogress-rails (~> 0.1.6.7) nprogress-rails (~> 0.1.6.7)
oauth2 (~> 1.0.0) oauth2 (~> 1.0.0)
octokit (~> 3.7.0) octokit (~> 3.8.0)
omniauth (~> 1.2.2) omniauth (~> 1.2.2)
omniauth-azure-oauth2 (~> 0.0.6) omniauth-azure-oauth2 (~> 0.0.6)
omniauth-bitbucket (~> 0.0.2) omniauth-bitbucket (~> 0.0.2)
...@@ -1018,7 +1018,7 @@ DEPENDENCIES ...@@ -1018,7 +1018,7 @@ DEPENDENCIES
rack-attack (~> 4.3.1) rack-attack (~> 4.3.1)
rack-cors (~> 0.4.0) rack-cors (~> 0.4.0)
rack-oauth2 (~> 1.2.1) rack-oauth2 (~> 1.2.1)
rails (= 4.2.5) rails (= 4.2.5.1)
rails-deprecated_sanitizer (~> 1.0.3) rails-deprecated_sanitizer (~> 1.0.3)
raphael-rails (~> 2.1.2) raphael-rails (~> 2.1.2)
rblineprof rblineprof
......
...@@ -93,7 +93,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the ...@@ -93,7 +93,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
GitLab is a Ruby on Rails application that runs on the following software: GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL - Ubuntu/Debian/CentOS/RHEL
- Ruby (MRI) 2.1 - Ruby (MRI) 2.1 or 2.2
- Git 1.7.10+ - Git 1.7.10+
- Redis 2.8+ - Redis 2.8+
- MySQL or PostgreSQL - MySQL or PostgreSQL
......
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
# the compiled file. # the compiled file.
# #
#= require jquery #= require jquery
#= require jquery-ui #= require jquery-ui/autocomplete
#= require jquery-ui/datepicker
#= require jquery-ui/effect-highlight
#= require jquery-ui/sortable
#= require jquery_ujs #= require jquery_ujs
#= require jquery.cookie #= require jquery.cookie
#= require jquery.endless-scroll #= require jquery.endless-scroll
...@@ -207,4 +210,13 @@ $ -> ...@@ -207,4 +210,13 @@ $ ->
form = btn.closest("form") form = btn.closest("form")
new ConfirmDangerModal(form, text, warningMessage: warningMessage) new ConfirmDangerModal(form, text, warningMessage: warningMessage)
$('input[type="search"]').each ->
$this = $(this)
$this.attr 'value', $this.val()
return
$(document).on 'keyup', 'input[type="search"]' , (e) ->
$this = $(this)
$this.attr 'value', $this.val()
new Aside() new Aside()
...@@ -4,6 +4,7 @@ class @AwardsHandler ...@@ -4,6 +4,7 @@ class @AwardsHandler
event.stopPropagation() event.stopPropagation()
event.preventDefault() event.preventDefault()
$(".emoji-menu").show() $(".emoji-menu").show()
$("#emoji_search").focus()
$("html").on 'click', (event) -> $("html").on 'click', (event) ->
if !$(event.target).closest(".emoji-menu").length if !$(event.target).closest(".emoji-menu").length
......
...@@ -32,6 +32,7 @@ class @EditBlob ...@@ -32,6 +32,7 @@ class @EditBlob
content: editor.getValue() content: editor.getValue()
, (response) -> , (response) ->
currentPane.empty().append response currentPane.empty().append response
currentPane.syntaxHighlight()
return return
else else
......
...@@ -50,6 +50,7 @@ class @Issue ...@@ -50,6 +50,7 @@ class @Issue
new Flash(issueFailMessage, 'alert') new Flash(issueFailMessage, 'alert')
success: (data, textStatus, jqXHR) -> success: (data, textStatus, jqXHR) ->
if data.saved if data.saved
$(document).trigger('issuable:change');
if isClose if isClose
$('a.btn-close').addClass('hidden') $('a.btn-close').addClass('hidden')
$('a.btn-reopen').removeClass('hidden') $('a.btn-reopen').removeClass('hidden')
......
...@@ -64,6 +64,9 @@ class @Notes ...@@ -64,6 +64,9 @@ class @Notes
# fetch notes when tab becomes visible # fetch notes when tab becomes visible
$(document).on "visibilitychange", @visibilityChange $(document).on "visibilitychange", @visibilityChange
# when issue status changes, we need to refresh data
$(document).on "issuable:change", @refresh
cleanBinding: -> cleanBinding: ->
$(document).off "ajax:success", ".js-main-target-form" $(document).off "ajax:success", ".js-main-target-form"
$(document).off "ajax:success", ".js-discussion-note-form" $(document).off "ajax:success", ".js-discussion-note-form"
......
...@@ -9,11 +9,13 @@ class @ProjectsList ...@@ -9,11 +9,13 @@ class @ProjectsList
$(".projects-list-filter").keyup -> $(".projects-list-filter").keyup ->
terms = $(this).val() terms = $(this).val()
uiBox = $('div.projects-list-holder') uiBox = $('div.projects-list-holder')
filterSelector = $(this).data('filter-selector') || 'span.filter-title'
if terms == "" || terms == undefined if terms == "" || terms == undefined
uiBox.find("ul.projects-list li").show() uiBox.find("ul.projects-list li").show()
else else
uiBox.find("ul.projects-list li").each (index) -> uiBox.find("ul.projects-list li").each (index) ->
name = $(this).find("span.filter-title").text() name = $(this).find(filterSelector).text()
if name.toLowerCase().search(terms.toLowerCase()) == -1 if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide() $(this).hide()
......
...@@ -5,11 +5,11 @@ class @ShortcutsIssuable extends ShortcutsNavigation ...@@ -5,11 +5,11 @@ class @ShortcutsIssuable extends ShortcutsNavigation
constructor: (isMergeRequest) -> constructor: (isMergeRequest) ->
super() super()
Mousetrap.bind('a', -> Mousetrap.bind('a', ->
$('.js-assignee').select2('open') $('.block.assignee .edit-link').trigger('click')
return false return false
) )
Mousetrap.bind('m', -> Mousetrap.bind('m', ->
$('.js-milestone').select2('open') $('.block.milestone .edit-link').trigger('click')
return false return false
) )
Mousetrap.bind('r', => Mousetrap.bind('r', =>
......
...@@ -320,14 +320,6 @@ table { ...@@ -320,14 +320,6 @@ table {
} }
} }
.wiki .highlight, .note-body .highlight {
margin: 12px 0 12px 0;
}
.wiki .code {
overflow-x: auto;
}
.footer-links { .footer-links {
margin-bottom: 20px; margin-bottom: 20px;
a { a {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
border: 1px solid $border-color; border: 1px solid $border-color;
&.readme-holder { &.readme-holder {
margin-top: 10px;
border-bottom: 0; border-bottom: 0;
} }
......
...@@ -2,11 +2,42 @@ textarea { ...@@ -2,11 +2,42 @@ textarea {
resize: vertical; resize: vertical;
} }
input[type='search'].search-text-input { input {
background-image: image-url("icon-search.png"); border-radius: $border-radius-base;
}
input[type='search'] {
background-color: white;
padding-left: 10px;
}
input[type='search'].search-input {
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 10px; background-position: 10px;
padding-left: 25px; background-size: 16px;
background-position-x: 30%;
padding-left: 10px;
background-color: $gray-light;
&.search-input[value=""] {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAFu0lEQVRIia1WTahkVxH+quqce7vf6zdvJpHoIlkYJ2SiJiIokmQjgoGgIAaEIYuYXWICgojiwkmC4taFwhjcyIDusogEIwwiSSCKPwsdwzAg0SjJ9Izzk5n3+nXfe8+pqizOvd395scfsJqi6dPnnDr11Vc/NJ1OwUTosqJLCmYCHCAC2mSHs+ojZv6AO46Y+20AhIneJsafhPhXVZSXDk7qi+aOLhtQNuBmQtcarAKjTXpn2+l3u2yPunvZSABRucjcAV/eMZuM48/Go/g1d19kc4wq+e8MZjWkbI/P5t2P3RFFbv7SQdyBlBUx8N8OTuqjMcof+N94yMPrY2DMm/ytnb32J0QrY+6AqsHM4Q64O9SKDmerKDD3Oy/tNL9vk342CC8RuU6n0ymCMHb22scu7zQngtASOjUHE1BX4UUAv4b7Ow6qiXCXuz/UdvogAAweDY943/b4cAz0ZlYHXeMsnT07RVb7wMUr8ykI4H5HVkMd5Rcb4/jNURVOL5qErAaAUUdCCIJ5kx5q2nw8m39ImEAAsjpE6PStB0YfMcd1wqqG3Xn7A3PfZyyKnNjaqD4fmE/fCNKshirIyY1xvI+Av6g5QIAIIWX7cJPssboSiBBEeKmsZne0Sb8kzAUWNYyq8NvbDo0fZ6beqxuLmqOOMr/lwOh+YXpXtbjERGja9JyZ9+HxpXKb9Gj5oywRESbj+Cj1ENG1QViTGBl1FbC1We1tbVRfHWIoQkhqH9xbpE92XUbb6VJZ1R4crjRz1JWcDMJvLdoMcyAEhjuwHo8Bfndg3mbszhOY+adVlMtD3po51OwzIQiEaams7oeJhxRw1FFOVpFRRUYIhMBAFRnjOsC8IFHHUA4TQQhgAqpAiIFfGbxkIqj54ayGbL7UoOqHCniAEKHLNr26l+D9wQJzeUwMAnfHvEnLECzZRwRV++d60ptjW9VLZeolEJG6GwCCE0CFVNB+Ay0NEqoQYG4YYFu7B8IEVRt3uRzy/osIoLV9QZimWXGHUMFdmI6M64DUF2Je88R9VZqCSP+QlcF5k+4tCzSsXaqjINuK6UyE0+s/mk6/qFq8oAIL9pqMLhkGsNrOyoOIlszust3aJv0U9+kFdwjTGwWl1YdF+KWlQSZ0Se/psj8yGVdg5tJyfH96EBWmLtoEMwMzMFt031NzGWLLzKhC+KV7H5ZeeaMOPxemma2x68puc0LN3+/u6LJiePS6MKHvn4wu6cPzJj0hsioeMfDrEvjv5r6W9gBvjKJujuKzQ0URIZj75NylvT+mbHfXQa4rwAMaVRTMm/SFyzvNy0yF6+4AM+1ubcSnqkAIUjQKl1RKSbE5jt+vovx1MBqF0WW7/d1Z80ab9BtmuJ3Xk5cJKds9TZt/uLPXvtiTrQ+dIwqfAejUvM1os6FNikXKUHfQ+ekUsXT5u85enJ0CaBSkkGEo1syUQ+DfMdE/4GA1uzupf9zdbzhOmLsF4efHVXjaHHAzmDtGdQRd/Nc5wAEJjNki3XfhyvwVNz80xANrht3LsENY9cBBdN1L9GUyyvFRFZ42t75sBvCQRykbRlU4tT2pPxoCvzx09d4GmPs200M6wKdWSDGK8mppYSWdhAlt0qeaLv+IadXU9/Evq4FAZ8ej+LmtcTxaRX4NWI0Uag5Vg1p5MYg8BnlhXIdPHDow+vTWZvVMVttXDLqkTzZdPj6Qii6cP1cSvIdl3iQkNYyi9HH0I22y+93tY3DcQkTZgQtM+POoCr8x97eylkmtrgKuztrvXJ21x/aNKuqIkZ/fntRfCdcTfhUTAIhRzoDojJD0aSNLLwMzmpT7+JaLtyf1MwDo6qz9djFaUq3t9MlFmy/c1OCSceY9fMsVaL9mvH9ocXdkdWxv1scAePG0THAhMOaLdOw/Gvxfxb1w4eCapyIENUcV5M3/u8FitAxZ25P6GAHT3UX39Srw+QOb1ZffA98Dl2Wy1BYkAAAAAElFTkSuQmCC');
}
&.search-input::-webkit-input-placeholder {
text-align: center;
}
&.search-input:-moz-placeholder { /* Firefox 18- */
text-align: center;
}
&.search-input::-moz-placeholder { /* Firefox 19+ */
text-align: center;
}
&.search-input:-ms-input-placeholder {
text-align: center;
}
} }
input[type='text'].danger { input[type='text'].danger {
...@@ -74,6 +105,7 @@ label { ...@@ -74,6 +105,7 @@ label {
.form-control { .form-control {
@include box-shadow(none); @include box-shadow(none);
border-radius: 3px;
} }
.form-control-inline { .form-control-inline {
......
...@@ -108,16 +108,10 @@ header { ...@@ -108,16 +108,10 @@ header {
.search-input { .search-input {
width: 220px; width: 220px;
background-image: image-url("icon-search.png");
background-repeat: no-repeat;
background-position: 195px;
@include input-big;
&:focus { &:focus {
@include box-shadow(none); @include box-shadow(none);
outline: none; outline: none;
border-color: #DDD;
background-color: #FFF;
} }
} }
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
overflow-y: hidden; overflow-y: hidden;
white-space: pre; white-space: pre;
word-wrap: normal; word-wrap: normal;
border-left: 1px solid;
code { code {
font-family: $monospace_font; font-family: $monospace_font;
...@@ -25,7 +26,7 @@ ...@@ -25,7 +26,7 @@
padding: 0; padding: 0;
.line { .line {
display: inline; display: inline-block;
} }
} }
} }
...@@ -53,18 +54,3 @@ ...@@ -53,18 +54,3 @@
} }
} }
} }
.note-text .code {
border: none;
box-shadow: none;
background: $background-color;
padding: 1em;
overflow-x: auto;
code {
font-family: $monospace_font;
white-space: pre;
word-wrap: normal;
padding: 0;
}
}
...@@ -33,7 +33,7 @@ table { ...@@ -33,7 +33,7 @@ table {
background-color: $background-color; background-color: $background-color;
font-weight: normal; font-weight: normal;
font-size: 15px; font-size: 15px;
border-bottom: 1px solid $border-color !important; border-bottom: 1px solid $border-color;
&.sortable { &.sortable {
cursor: pointer; cursor: pointer;
...@@ -41,8 +41,8 @@ table { ...@@ -41,8 +41,8 @@ table {
} }
td { td {
border-color: $table-border-color !important; border-color: $table-border-color;
border-bottom: 1px solid; border-bottom: 1px solid $border-color;
} }
} }
} }
......
...@@ -22,9 +22,9 @@ $brand-info: $gl-info; ...@@ -22,9 +22,9 @@ $brand-info: $gl-info;
$brand-warning: $gl-warning; $brand-warning: $gl-warning;
$brand-danger: $gl-danger; $brand-danger: $gl-danger;
$border-radius-base: 2px !default; $border-radius-base: 3px !default;
$border-radius-large: 2px !default; $border-radius-large: 3px !default;
$border-radius-small: 2px !default; $border-radius-small: 3px !default;
//== Scaffolding //== Scaffolding
......
...@@ -87,8 +87,8 @@ ...@@ -87,8 +87,8 @@
} }
p { p {
color:#5c5d5e; color: #5c5d5e;
margin:6px 0 0 0; margin: 6px 0 0 0;
} }
table { table {
...@@ -102,11 +102,10 @@ ...@@ -102,11 +102,10 @@
} }
pre { pre {
margin: 12px 0 12px 0 !important; margin: 12px 0 12px 0;
background-color: #f8fafc; font-size: 13px;
font-size: 13px !important; line-height: 1.6em;
color: #5b6169; overflow-x: auto;
line-height: 1.6em !important;
@include border-radius(2px); @include border-radius(2px);
} }
...@@ -116,7 +115,7 @@ ...@@ -116,7 +115,7 @@
ul, ol { ul, ol {
padding: 0; padding: 0;
margin: 6px 0 6px 18px !important; margin: 6px 0 6px 28px !important;
} }
li { li {
...@@ -204,11 +203,6 @@ h1, h2, h3, h4, h5, h6 { ...@@ -204,11 +203,6 @@ h1, h2, h3, h4, h5, h6 {
pre { pre {
font-family: $monospace_font; font-family: $monospace_font;
&.dark {
background: #333;
color: $background-color;
}
&.plain-readme { &.plain-readme {
background: none; background: none;
border: none; border: none;
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
} }
// Code itself // Code itself
pre.code { pre.code, .diff-line-num {
border-left: 1px solid #666; border-color: #666;
} }
&, pre.code, .line_holder .line_content { &, pre.code, .line_holder .line_content {
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
// Diff line // Diff line
.line_holder { .line_holder {
.diff-line-num.new, .line_content.new { .diff-line-num.new, .line_content.new {
@include diff_background(rgba(51, 255, 51, 0.1), rgba(51, 255, 51, 0.3), #808080); @include diff_background(rgba(51, 255, 51, 0.1), rgba(51, 255, 51, 0.2), #808080);
} }
.diff-line-num.old, .line_content.old { .diff-line-num.old, .line_content.old {
@include diff_background(rgba(255, 51, 51, 0.2), rgba(255, 51, 51, 0.3), #808080); @include diff_background(rgba(255, 51, 51, 0.2), rgba(255, 51, 51, 0.25), #808080);
} }
.line_content.match { .line_content.match {
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
} }
// Code itself // Code itself
pre.code { pre.code, .diff-line-num {
border-left: 1px solid #555; border-color: #555;
} }
&, pre.code, .line_holder .line_content { &, pre.code, .line_holder .line_content {
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
// Diff line // Diff line
.line_holder { .line_holder {
.diff-line-num.new, .line_content.new { .diff-line-num.new, .line_content.new {
@include diff_background(rgba(166, 226, 46, 0.2), rgba(166, 226, 46, 0.3), #808080); @include diff_background(rgba(166, 226, 46, 0.1), rgba(166, 226, 46, 0.15), #808080);
} }
.diff-line-num.old, .line_content.old { .diff-line-num.old, .line_content.old {
@include diff_background(rgba(254, 147, 140, 0.2), rgba(254, 147, 140, 0.3), #808080); @include diff_background(rgba(254, 147, 140, 0.15), rgba(254, 147, 140, 0.2), #808080);
} }
.line_content.match { .line_content.match {
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
} }
// Code itself // Code itself
pre.code { pre.code, .diff-line-num {
border-left: 1px solid #113b46; border-color: #113b46;
} }
&, pre.code, .line_holder .line_content { &, pre.code, .line_holder .line_content {
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
// Diff line // Diff line
.line_holder { .line_holder {
.diff-line-num.new, .line_content.new { .diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #808080); @include diff_background(rgba(133, 153, 0, 0.15), rgba(133, 153, 0, 0.25), #113b46);
} }
.diff-line-num.old, .line_content.old { .diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.3), rgba(220, 50, 47, 0.3), #808080); @include diff_background(rgba(220, 50, 47, 0.3), rgba(220, 50, 47, 0.25), #113b46);
} }
.line_content.match { .line_content.match {
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
} }
// Code itself // Code itself
pre.code { pre.code, .diff-line-num {
border-left: 1px solid #c5d0d4; border-color: #c5d0d4;
} }
&, pre.code, .line_holder .line_content { &, pre.code, .line_holder .line_content {
...@@ -22,11 +22,11 @@ ...@@ -22,11 +22,11 @@
// Diff line // Diff line
.line_holder { .line_holder {
.diff-line-num.new, .line_content.new { .diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #FAF3DD); @include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.25), #c5d0d4);
} }
.diff-line-num.old, .line_content.old { .diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.3), #FAF3DD); @include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.25), #c5d0d4);
} }
.line_content.match { .line_content.match {
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
} }
// Code itself // Code itself
pre.code { pre.code, .diff-line-num {
border-left: 1px solid $border-color; border-color: $border-color;
} }
&, pre.code, .line_holder .line_content { &, pre.code, .line_holder .line_content {
......
...@@ -79,10 +79,8 @@ ...@@ -79,10 +79,8 @@
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: none; border: none;
background: $background-color;
color: rgba(0, 0, 0, 0.3);
padding: 0px 5px; padding: 0px 5px;
border-right: 1px solid $border-color; border-right: 1px solid;
text-align: right; text-align: right;
min-width: 35px; min-width: 35px;
max-width: 50px; max-width: 50px;
...@@ -92,7 +90,6 @@ ...@@ -92,7 +90,6 @@
float: left; float: left;
width: 35px; width: 35px;
font-weight: normal; font-weight: normal;
color: rgba(0, 0, 0, 0.3);
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
......
.member-search-form { .member-search-form {
float: left; float: left;
input[type='search'] {
width: 225px;
vertical-align: bottom;
@media (max-width: $screen-xs-max) {
width: 100px;
vertical-align: bottom;
}
}
} }
.milestone-row { .milestone-row {
......
...@@ -49,11 +49,6 @@ ...@@ -49,11 +49,6 @@
.issue-search-form { .issue-search-form {
margin: 0; margin: 0;
height: 24px; height: 24px;
.issue_search {
border: 1px solid #DDD !important;
background-color: #f4f4f4;
}
} }
form.edit-issue { form.edit-issue {
......
...@@ -154,6 +154,7 @@ ul.notes { ...@@ -154,6 +154,7 @@ ul.notes {
text-align: center; text-align: center;
padding: 10px 0; padding: 10px 0;
background: #FFF; background: #FFF;
color: $text-color;
} }
&.notes_line2 { &.notes_line2 {
text-align: center; text-align: center;
......
...@@ -564,3 +564,53 @@ pre.light-well { ...@@ -564,3 +564,53 @@ pre.light-well {
color: #E62958; color: #E62958;
margin-top: 2px; margin-top: 2px;
} }
/*
* Forks list rendered on Project's forks page
*/
.forks-top-block {
padding: 16px 0;
}
.projects-search-form {
.dropdown-toggle.btn {
margin-top: -3px;
}
&.fork-search-form {
margin: 0;
margin-top: -$gl-padding;
padding-bottom: 0;
input {
/* Small devices (tablets, 768px and up) */
@media (min-width: $screen-sm-min) { width: 180px; }
/* Medium devices (desktops, 992px and up) */
@media (min-width: $screen-md-min) { width: 350px; }
/* Large devices (large desktops, 1200px and up) */
@media (min-width: $screen-lg-min) { width: 400px; }
}
.sort-forks {
width: 160px;
}
.fork-link {
float: right;
margin-left: $gl-padding;
}
}
}
.private-forks-notice .private-fork-icon {
i:nth-child(1) {
color: #2AA056;
}
i:nth-child(2) {
color: #FFFFFF;
}
}
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
&:hover { &:hover {
td { td {
background: $hover; background: $hover;
border-top: 1px solid #ADF;
border-bottom: 1px solid #ADF;
} }
cursor: pointer; cursor: pointer;
} }
......
...@@ -76,8 +76,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -76,8 +76,6 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_timeout, :metrics_timeout,
:metrics_method_call_threshold, :metrics_method_call_threshold,
:metrics_sample_interval, :metrics_sample_interval,
:ip_blocking_enabled,
:dnsbl_servers_list,
:recaptcha_enabled, :recaptcha_enabled,
:recaptcha_site_key, :recaptcha_site_key,
:recaptcha_private_key, :recaptcha_private_key,
......
...@@ -308,7 +308,8 @@ class ApplicationController < ActionController::Base ...@@ -308,7 +308,8 @@ class ApplicationController < ActionController::Base
end end
def set_filters_params def set_filters_params
params[:sort] ||= 'id_desc' set_default_sort
params[:scope] = 'all' if params[:scope].blank? params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank? params[:state] = 'opened' if params[:state].blank?
...@@ -415,4 +416,24 @@ class ApplicationController < ActionController::Base ...@@ -415,4 +416,24 @@ class ApplicationController < ActionController::Base
current_user.nil? && root_path == request.path current_user.nil? && root_path == request.path
end end
private
def set_default_sort
key = if is_a_listing_page_for?('issues') || is_a_listing_page_for?('merge_requests')
'issuable_sort'
end
cookies[key] = params[:sort] if key && params[:sort].present?
params[:sort] = cookies[key] if key
params[:sort] ||= 'id_desc'
end
def is_a_listing_page_for?(page_type)
controller_name, action_name = params.values_at(:controller, :action)
(controller_name == "projects/#{page_type}" && action_name == 'index') ||
(controller_name == 'groups' && action_name == page_type) ||
(controller_name == 'dashboard' && action_name == page_type)
end
end end
...@@ -36,7 +36,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ...@@ -36,7 +36,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
private private
def load_events def load_events
@events = Event.in_projects(@projects.pluck(:id)) @events = Event.in_projects(@projects)
@events = @event_filter.apply_filter(@events).with_associations @events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
end end
......
...@@ -23,14 +23,14 @@ class DashboardController < Dashboard::ApplicationController ...@@ -23,14 +23,14 @@ class DashboardController < Dashboard::ApplicationController
protected protected
def load_events def load_events
project_ids = projects =
if params[:filter] == "starred" if params[:filter] == "starred"
current_user.starred_projects current_user.starred_projects
else else
current_user.authorized_projects current_user.authorized_projects
end.pluck(:id) end
@events = Event.in_projects(project_ids) @events = Event.in_projects(projects)
@events = @event_filter.apply_filter(@events).with_associations @events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
end end
......
...@@ -2,17 +2,18 @@ class GroupsController < Groups::ApplicationController ...@@ -2,17 +2,18 @@ class GroupsController < Groups::ApplicationController
include IssuesAction include IssuesAction
include MergeRequestsAction include MergeRequestsAction
skip_before_action :authenticate_user!, only: [:show, :issues, :merge_requests]
respond_to :html respond_to :html
before_action :group, except: [:new, :create]
skip_before_action :authenticate_user!, only: [:index, :show, :issues, :merge_requests]
before_action :group, except: [:index, :new, :create]
# Authorize # Authorize
before_action :authorize_read_group!, except: [:show, :new, :create, :autocomplete] before_action :authorize_read_group!, except: [:index, :show, :new, :create, :autocomplete]
before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects] before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects]
before_action :authorize_create_group!, only: [:new, :create] before_action :authorize_create_group!, only: [:new, :create]
# Load group projects # Load group projects
before_action :load_projects, except: [:new, :create, :projects, :edit, :update, :autocomplete] before_action :load_projects, except: [:index, :new, :create, :projects, :edit, :update, :autocomplete]
before_action :event_filter, only: :show before_action :event_filter, only: :show
layout :determine_layout layout :determine_layout
...@@ -89,16 +90,13 @@ class GroupsController < Groups::ApplicationController ...@@ -89,16 +90,13 @@ class GroupsController < Groups::ApplicationController
def group def group
@group ||= Group.find_by(path: params[:id]) @group ||= Group.find_by(path: params[:id])
@group || render_404
end end
def load_projects def load_projects
@projects ||= ProjectsFinder.new.execute(current_user, group: group).sorted_by_activity.non_archived @projects ||= ProjectsFinder.new.execute(current_user, group: group).sorted_by_activity.non_archived
end end
def project_ids
@projects.pluck(:id)
end
# Dont allow unauthorized access to group # Dont allow unauthorized access to group
def authorize_read_group! def authorize_read_group!
unless @group and (@projects.present? or can?(current_user, :read_group, @group)) unless @group and (@projects.present? or can?(current_user, :read_group, @group))
...@@ -131,7 +129,7 @@ class GroupsController < Groups::ApplicationController ...@@ -131,7 +129,7 @@ class GroupsController < Groups::ApplicationController
end end
def load_events def load_events
@events = Event.in_projects(project_ids) @events = Event.in_projects(@projects)
@events = event_filter.apply_filter(@events).with_associations @events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0) @events = @events.limit(20).offset(params[:offset] || 0)
end end
......
...@@ -13,10 +13,10 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController ...@@ -13,10 +13,10 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
current_user.save! if current_user.changed? current_user.save! if current_user.changed?
if two_factor_grace_period_expired? if two_factor_grace_period_expired?
flash.now[:alert] = 'You must configure Two-Factor Authentication in your account.' flash.now[:alert] = 'You must enable Two-factor Authentication for your account.'
else else
grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours
flash.now[:alert] = "You must configure Two-Factor Authentication in your account until #{l(grace_period_deadline)}." flash.now[:alert] = "You must enable Two-factor Authentication for your account before #{l(grace_period_deadline)}."
end end
@qr_code = build_qr_code @qr_code = build_qr_code
......
...@@ -8,28 +8,6 @@ class Projects::BlameController < Projects::ApplicationController ...@@ -8,28 +8,6 @@ class Projects::BlameController < Projects::ApplicationController
def show def show
@blob = @repository.blob_at(@commit.id, @path) @blob = @repository.blob_at(@commit.id, @path)
@blame = group_blame_lines @blame_groups = Gitlab::Blame.new(@blob, @commit).groups
end
def group_blame_lines
blame = Gitlab::Git::Blame.new(@repository, @commit.id, @path)
prev_sha = nil
groups = []
current_group = nil
blame.each do |commit, line|
if prev_sha && prev_sha == commit.sha
current_group[:lines] << line
else
groups << current_group if current_group.present?
current_group = { commit: commit, lines: [line] }
end
prev_sha = commit.sha
end
groups << current_group if current_group.present?
groups
end end
end end
...@@ -21,7 +21,7 @@ class Projects::CompareController < Projects::ApplicationController ...@@ -21,7 +21,7 @@ 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)
@base_commit = @project.commit(base_ref) @base_commit = @project.merge_base_commit(base_ref, head_ref)
@diff_refs = [@base_commit, @commit] @diff_refs = [@base_commit, @commit]
@line_notes = [] @line_notes = []
end end
......
...@@ -3,6 +3,15 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -3,6 +3,15 @@ class Projects::ForksController < Projects::ApplicationController
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :authorize_download_code! before_action :authorize_download_code!
def index
@sort = params[:sort] || 'id_desc'
@all_forks = project.forks.includes(:creator).order_by(@sort)
@public_forks, @protected_forks = @all_forks.partition do |project|
can?(current_user, :read_project, project)
end
end
def new def new
@namespaces = current_user.manageable_namespaces @namespaces = current_user.manageable_namespaces
@namespaces.delete(@project.namespace) @namespaces.delete(@project.namespace)
......
class Projects::ImportsController < Projects::ApplicationController class Projects::ImportsController < Projects::ApplicationController
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :require_no_repo, except: :show before_action :require_no_repo, only: [:new, :create]
before_action :redirect_if_progress, except: :show before_action :redirect_if_progress, only: [:new, :create]
def new def new
end end
...@@ -22,11 +22,11 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -22,11 +22,11 @@ class Projects::ImportsController < Projects::ApplicationController
end end
def show def show
if @project.repository_exists? || @project.import_finished? if @project.import_finished?
if continue_params if continue_params
redirect_to continue_params[:to], notice: continue_params[:notice] redirect_to continue_params[:to], notice: continue_params[:notice]
else else
redirect_to project_path(@project), notice: "The project was successfully forked." redirect_to namespace_project_path(@project.namespace, @project), notice: finished_notice
end end
elsif @project.import_failed? elsif @project.import_failed?
redirect_to new_namespace_project_import_path(@project.namespace, @project) redirect_to new_namespace_project_import_path(@project.namespace, @project)
...@@ -34,6 +34,7 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -34,6 +34,7 @@ class Projects::ImportsController < Projects::ApplicationController
if continue_params && continue_params[:notice_now] if continue_params && continue_params[:notice_now]
flash.now[:notice] = continue_params[:notice_now] flash.now[:notice] = continue_params[:notice_now]
end end
# Render # Render
end end
end end
...@@ -42,6 +43,7 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -42,6 +43,7 @@ class Projects::ImportsController < Projects::ApplicationController
def continue_params def continue_params
continue_params = params[:continue] continue_params = params[:continue]
if continue_params if continue_params
continue_params.permit(:to, :notice, :notice_now) continue_params.permit(:to, :notice, :notice_now)
else else
...@@ -49,8 +51,16 @@ class Projects::ImportsController < Projects::ApplicationController ...@@ -49,8 +51,16 @@ class Projects::ImportsController < Projects::ApplicationController
end end
end end
def finished_notice
if @project.forked?
'The project was successfully forked.'
else
'The project was successfully imported.'
end
end
def require_no_repo def require_no_repo
if @project.repository_exists? && !@project.import_in_progress? if @project.repository_exists?
redirect_to(namespace_project_path(@project.namespace, @project)) redirect_to(namespace_project_path(@project.namespace, @project))
end end
end end
......
...@@ -8,11 +8,6 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -8,11 +8,6 @@ class RegistrationsController < Devise::RegistrationsController
def create def create
if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha 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 super
else else
flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code." flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code."
......
...@@ -2,6 +2,8 @@ class SessionsController < Devise::SessionsController ...@@ -2,6 +2,8 @@ class SessionsController < Devise::SessionsController
include AuthenticatesWithTwoFactor include AuthenticatesWithTwoFactor
include Recaptcha::ClientHelper include Recaptcha::ClientHelper
skip_before_action :check_2fa_requirement, only: [:destroy]
prepend_before_action :authenticate_with_two_factor, only: [:create] prepend_before_action :authenticate_with_two_factor, only: [:create]
prepend_before_action :store_redirect_path, only: [:new] prepend_before_action :store_redirect_path, only: [:new]
before_action :gitlab_geo_login, only: [:new] before_action :gitlab_geo_login, only: [:new]
......
...@@ -174,7 +174,7 @@ module ApplicationHelper ...@@ -174,7 +174,7 @@ module ApplicationHelper
def search_placeholder def search_placeholder
if @project && @project.persisted? if @project && @project.persisted?
'Search in this project' 'Search'
elsif @snippet || @snippets || @show_snippets elsif @snippet || @snippets || @show_snippets
'Search snippets' 'Search snippets'
elsif @group && @group.persisted? elsif @group && @group.persisted?
......
...@@ -36,8 +36,7 @@ module BlobHelper ...@@ -36,8 +36,7 @@ module BlobHelper
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now notice_now: edit_in_new_fork_notice_now
} }
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params)
continue: continue_params)
link_to "Edit", fork_path, class: 'btn', method: :post link_to "Edit", fork_path, class: 'btn', method: :post
end end
...@@ -62,8 +61,7 @@ module BlobHelper ...@@ -62,8 +61,7 @@ module BlobHelper
notice: edit_in_new_fork_notice + " Try to #{action} this file again.", notice: edit_in_new_fork_notice + " Try to #{action} this file again.",
notice_now: edit_in_new_fork_notice_now notice_now: edit_in_new_fork_notice_now
} }
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params)
continue: continue_params)
link_to label, fork_path, class: "btn btn-#{btn_class}", method: :post link_to label, fork_path, class: "btn btn-#{btn_class}", method: :post
end end
......
...@@ -152,7 +152,7 @@ module CommitsHelper ...@@ -152,7 +152,7 @@ module CommitsHelper
options = { options = {
class: "commit-#{options[:source]}-link has_tooltip", class: "commit-#{options[:source]}-link has_tooltip",
data: { :'original-title' => sanitize(source_email) } data: { 'original-title'.to_sym => sanitize(source_email) }
} }
if user.nil? if user.nil?
......
...@@ -7,7 +7,7 @@ module IconsHelper ...@@ -7,7 +7,7 @@ module IconsHelper
# font-awesome-rails gem, but should we ever use a different icon pack in the # font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls. # future we won't have to change hundreds of method calls.
def icon(names, options = {}) def icon(names, options = {})
fa_icon(names, options) options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
end end
def spinner(text = nil, visible = false) def spinner(text = nil, visible = false)
......
...@@ -83,7 +83,11 @@ module LabelsHelper ...@@ -83,7 +83,11 @@ module LabelsHelper
end end
def text_color_for_bg(bg_color) def text_color_for_bg(bg_color)
r, g, b = bg_color.slice(1,7).scan(/.{2}/).map(&:hex) if bg_color.length == 4
r, g, b = bg_color[1, 4].scan(/./).map { |v| (v * 2).hex }
else
r, g, b = bg_color[1, 7].scan(/.{2}/).map(&:hex)
end
if (r + g + b) > 500 if (r + g + b) > 500
'#333333' '#333333'
......
...@@ -40,7 +40,7 @@ module ProjectsHelper ...@@ -40,7 +40,7 @@ module ProjectsHelper
link_to(author_html, user_path(author), class: "author_link").html_safe link_to(author_html, user_path(author), class: "author_link").html_safe
else else
title = opts[:title].sub(":name", sanitize(author.name)) title = opts[:title].sub(":name", sanitize(author.name))
link_to(author_html, user_path(author), class: "author_link has_tooltip", data: { :'original-title' => title, container: 'body' } ).html_safe link_to(author_html, user_path(author), class: "author_link has_tooltip", data: { 'original-title'.to_sym => title, container: 'body' } ).html_safe
end end
end end
...@@ -116,7 +116,7 @@ module ProjectsHelper ...@@ -116,7 +116,7 @@ module ProjectsHelper
private private
def get_project_nav_tabs(project, current_user) def get_project_nav_tabs(project, current_user)
nav_tabs = [:home] nav_tabs = [:home, :forks]
if !project.empty_repo? && can?(current_user, :download_code, project) if !project.empty_repo? && can?(current_user, :download_code, project)
nav_tabs << [:files, :commits, :network, :graphs] nav_tabs << [:files, :commits, :network, :graphs]
......
...@@ -44,8 +44,6 @@ ...@@ -44,8 +44,6 @@
# metrics_port :integer default(8089) # metrics_port :integer default(8089)
# sentry_enabled :boolean default(FALSE) # sentry_enabled :boolean default(FALSE)
# sentry_dsn :string # sentry_dsn :string
# ip_blocking_enabled :boolean default(FALSE)
# dns_blacklist_threshold :float default(0.33)
# #
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
......
...@@ -47,7 +47,11 @@ class Event < ActiveRecord::Base ...@@ -47,7 +47,11 @@ class Event < ActiveRecord::Base
# Scopes # Scopes
scope :recent, -> { reorder(id: :desc) } scope :recent, -> { reorder(id: :desc) }
scope :code_push, -> { where(action: PUSHED) } scope :code_push, -> { where(action: PUSHED) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
scope :in_projects, ->(projects) do
where(project_id: projects.select(:id).reorder(nil)).recent
end
scope :with_associations, -> { includes(project: :namespace) } scope :with_associations, -> { includes(project: :namespace) }
scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) } scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) }
scope :issues, -> { where(target_type: 'Issue') } scope :issues, -> { where(target_type: 'Issue') }
...@@ -70,12 +74,6 @@ class Event < ActiveRecord::Base ...@@ -70,12 +74,6 @@ class Event < ActiveRecord::Base
[Event::CREATED, Event::CLOSED, Event::MERGED]) [Event::CREATED, Event::CLOSED, Event::MERGED])
end end
def latest_update_time
row = select(:updated_at, :project_id).reorder(id: :desc).take
row ? row.updated_at : nil
end
def limit_recent(limit = 20, offset = nil) def limit_recent(limit = 20, offset = nil)
recent.limit(limit).offset(offset) recent.limit(limit).offset(offset)
end end
......
...@@ -31,7 +31,7 @@ class ExternalIssue ...@@ -31,7 +31,7 @@ class ExternalIssue
# Pattern used to extract `JIRA-123` issue references from text # Pattern used to extract `JIRA-123` issue references from text
def self.reference_pattern def self.reference_pattern
%r{(?<issue>([A-Z\-]+-)\d+)} %r{(?<issue>\b([A-Z][A-Z0-9_]+-)\d+)}
end end
def to_reference(_from_project = nil) def to_reference(_from_project = nil)
......
...@@ -187,8 +187,8 @@ class MergeRequest < ActiveRecord::Base ...@@ -187,8 +187,8 @@ class MergeRequest < ActiveRecord::Base
def diff_base_commit def diff_base_commit
if merge_request_diff if merge_request_diff
merge_request_diff.base_commit merge_request_diff.base_commit
else elsif source_sha
self.target_project.commit(self.target_branch) self.target_project.merge_base_commit(self.source_sha, self.target_branch)
end end
end end
...@@ -545,7 +545,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -545,7 +545,7 @@ class MergeRequest < ActiveRecord::Base
end end
def source_sha def source_sha
commits.first.sha last_commit.try(:sha)
end end
def fetch_ref def fetch_ref
......
...@@ -48,14 +48,11 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -48,14 +48,11 @@ class MergeRequestDiff < ActiveRecord::Base
end end
def diffs_no_whitespace def diffs_no_whitespace
# Get latest sha of branch from source project
source_sha = merge_request.source_project.commit(source_branch).sha
compare_result = Gitlab::CompareResult.new( compare_result = Gitlab::CompareResult.new(
Gitlab::Git::Compare.new( Gitlab::Git::Compare.new(
merge_request.target_project.repository.raw_repository, self.repository.raw_repository,
merge_request.target_branch, self.target_branch,
source_sha, self.source_sha,
), { ignore_whitespace_change: true } ), { ignore_whitespace_change: true }
) )
@diffs_no_whitespace ||= load_diffs(dump_commits(compare_result.diffs)) @diffs_no_whitespace ||= load_diffs(dump_commits(compare_result.diffs))
...@@ -83,8 +80,6 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -83,8 +80,6 @@ class MergeRequestDiff < ActiveRecord::Base
@last_commit_short_sha ||= last_commit.short_id @last_commit_short_sha ||= last_commit.short_id
end end
private
def dump_commits(commits) def dump_commits(commits)
commits.map(&:to_hash) commits.map(&:to_hash)
end end
...@@ -163,7 +158,7 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -163,7 +158,7 @@ class MergeRequestDiff < ActiveRecord::Base
self.st_diffs = new_diffs self.st_diffs = new_diffs
self.base_commit_sha = merge_request.target_project.commit(target_branch).try(:sha) self.base_commit_sha = self.repository.merge_base(self.source_sha, self.target_branch)
self.save self.save
end end
...@@ -181,7 +176,10 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -181,7 +176,10 @@ class MergeRequestDiff < ActiveRecord::Base
merge_request.target_project.repository merge_request.target_project.repository
end end
private def source_sha
source_commit = merge_request.source_project.commit(source_branch)
source_commit.try(:sha)
end
def compare_result def compare_result
@compare_result ||= @compare_result ||=
...@@ -189,15 +187,11 @@ class MergeRequestDiff < ActiveRecord::Base ...@@ -189,15 +187,11 @@ class MergeRequestDiff < ActiveRecord::Base
# Update ref for merge request # Update ref for merge request
merge_request.fetch_ref merge_request.fetch_ref
# Get latest sha of branch from source project
source_commit = merge_request.source_project.commit(source_branch)
source_sha = source_commit.try(:sha)
Gitlab::CompareResult.new( Gitlab::CompareResult.new(
Gitlab::Git::Compare.new( Gitlab::Git::Compare.new(
merge_request.target_project.repository.raw_repository, self.repository.raw_repository,
merge_request.target_branch, self.target_branch,
source_sha, self.source_sha
) )
) )
end end
......
...@@ -383,6 +383,11 @@ class Project < ActiveRecord::Base ...@@ -383,6 +383,11 @@ class Project < ActiveRecord::Base
repository.commit(id) repository.commit(id)
end end
def merge_base_commit(first_commit_id, second_commit_id)
sha = repository.merge_base(first_commit_id, second_commit_id)
repository.commit(sha) if sha
end
def saved? def saved?
id && persisted? id && persisted?
end end
......
...@@ -664,6 +664,8 @@ class Repository ...@@ -664,6 +664,8 @@ class Repository
def merge_base(first_commit_id, second_commit_id) def merge_base(first_commit_id, second_commit_id)
rugged.merge_base(first_commit_id, second_commit_id) rugged.merge_base(first_commit_id, second_commit_id)
rescue Rugged::ReferenceError
nil
end end
def is_ancestor?(ancestor_id, descendant_id) def is_ancestor?(ancestor_id, descendant_id)
......
...@@ -17,12 +17,20 @@ class Tree ...@@ -17,12 +17,20 @@ class Tree
def readme def readme
return @readme if defined?(@readme) return @readme if defined?(@readme)
# Take the first previewable readme, or return nil if none is available or available_readmes = blobs.select(&:readme?)
# we can't preview any of them
readme_tree = blobs.find do |blob| previewable_readmes = available_readmes.select do |blob|
blob.readme? && (previewable?(blob.name) || plain?(blob.name)) previewable?(blob.name)
end
plain_readmes = available_readmes.select do |blob|
plain?(blob.name)
end end
# Prioritize previewable over plain readmes
readme_tree = previewable_readmes.first || plain_readmes.first
# Return if we can't preview any of them
if readme_tree.nil? if readme_tree.nil?
return @readme = nil return @readme = nil
end end
......
...@@ -110,7 +110,7 @@ class WikiPage ...@@ -110,7 +110,7 @@ class WikiPage
# Returns boolean True or False if this instance # Returns boolean True or False if this instance
# is an old version of the page. # is an old version of the page.
def historical? def historical?
@page.historical? @page.historical? && versions.first.sha != version.sha
end end
# Returns boolean True or False if this instance # Returns boolean True or False if this instance
......
...@@ -6,27 +6,12 @@ module Notes ...@@ -6,27 +6,12 @@ module Notes
note.system = false note.system = false
if note.save if note.save
notification_service.new_note(note) # Finish the harder work in the background
NewNoteWorker.perform_in(2.seconds, note.id, params)
# Skip system notes, like status changes and cross-references and awards
unless note.system || note.is_award
event_service.leave_note(note, note.author)
note.create_cross_references!
execute_hooks(note)
end
end end
note note
end end
def hook_data(note)
Gitlab::NoteDataBuilder.build(note, current_user)
end
def execute_hooks(note)
note_data = hook_data(note)
note.project.execute_hooks(note_data, :note_hooks)
note.project.execute_services(note_data, :note_hooks)
end
end end
end end
module Notes
class PostProcessService
attr_accessor :note
def initialize(note)
@note = note
end
def execute
# Skip system notes, like status changes and cross-references and awards
unless @note.system || @note.is_award
EventCreateService.new.leave_note(@note, @note.author)
@note.create_cross_references!
execute_note_hooks
end
end
def hook_data
Gitlab::NoteDataBuilder.build(@note, @note.author)
end
def execute_note_hooks
note_data = hook_data
@note.project.execute_hooks(note_data, :note_hooks)
@note.project.execute_services(note_data, :note_hooks)
end
end
end
module Projects
class ImportService < BaseService
include Gitlab::ShellAdapter
class Error < StandardError; end
ALLOWED_TYPES = [
'bitbucket',
'fogbugz',
'gitlab',
'github',
'google_code'
]
def execute
if unknown_url?
# In this case, we only want to import issues, not a repository.
create_repository
else
import_repository
end
import_data
success
rescue Error => e
error(e.message)
end
private
def create_repository
unless project.create_repository
raise Error, 'The repository could not be created.'
end
end
def import_repository
begin
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
rescue Gitlab::Shell::Error => e
raise Error, e.message
end
end
def import_data
return unless has_importer?
unless importer.execute
raise Error, 'The remote data could not be imported.'
end
end
def has_importer?
ALLOWED_TYPES.include?(project.import_type)
end
def importer
class_name = "Gitlab::#{project.import_type.camelize}Import::Importer"
class_name.constantize.new(project)
end
def unknown_url?
project.import_url == Project::UNKNOWN_IMPORT_URL
end
end
end
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
.form-group.project-visibility-level-holder .form-group.project-visibility-level-holder
= f.label :default_project_visibility, class: 'control-label col-sm-2' = f.label :default_project_visibility, class: 'control-label col-sm-2'
.col-sm-10 .col-sm-10
= render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project) = render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project.new)
.form-group.project-visibility-level-holder .form-group.project-visibility-level-holder
= f.label :default_snippet_visibility, class: 'control-label col-sm-2' = f.label :default_snippet_visibility, class: 'control-label col-sm-2'
.col-sm-10 .col-sm-10
= render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: PersonalSnippet) = render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: ProjectSnippet.new)
.form-group .form-group
= f.label :restricted_visibility_levels, class: 'control-label col-sm-2' = f.label :restricted_visibility_levels, class: 'control-label col-sm-2'
.col-sm-10 .col-sm-10
...@@ -225,22 +225,6 @@ ...@@ -225,22 +225,6 @@
%fieldset %fieldset
%legend Spam and Anti-bot Protection %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 .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
...@@ -281,4 +265,4 @@ ...@@ -281,4 +265,4 @@
= f.text_field :sentry_dsn, class: 'form-control' = f.text_field :sentry_dsn, class: 'form-control'
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-primary' = f.submit 'Save', class: 'btn btn-save'
...@@ -22,5 +22,5 @@ ...@@ -22,5 +22,5 @@
%code= Doorkeeper.configuration.native_redirect_uri %code= Doorkeeper.configuration.native_redirect_uri
for local tests for local tests
.form-actions .form-actions
= f.submit 'Submit', class: "btn btn-primary wide" = f.submit 'Submit', class: "btn btn-save wide"
= link_to "Cancel", admin_applications_path, class: "btn btn-default" = link_to "Cancel", admin_applications_path, class: "btn btn-default"
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
- else - else
.form-actions .form-actions
= f.submit 'Save changes', class: "btn btn-primary" = f.submit 'Save changes', class: "btn btn-save"
= link_to 'Cancel', admin_group_path(@group), class: "btn btn-cancel" = link_to 'Cancel', admin_group_path(@group), class: "btn btn-cancel"
- if @group.persisted? - if @group.persisted?
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
- @hooks.each do |hook| - @hooks.each do |hook|
%li %li
.list-item-name .list-item-name
= link_to admin_hook_path(hook) do
%strong= hook.url %strong= hook.url
%p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"} %p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
.controls .controls
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html" xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html"
xml.id dashboard_projects_url xml.id dashboard_projects_url
xml.updated @events.latest_update_time.xmlschema if @events.any? xml.updated @events[0].updated_at.xmlschema if @events[0]
@events.each do |event| @events.each do |event|
event_to_atom(xml, event) event_to_atom(xml, event)
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.pull-right .pull-right
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path) - elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path)
...@@ -24,4 +24,3 @@ ...@@ -24,4 +24,3 @@
= sort_title_recently_updated = sort_title_recently_updated
= link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do
= sort_title_oldest_updated = sort_title_oldest_updated
...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link href: group_url(@group, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: group_url(@group, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: group_url(@group), rel: "alternate", type: "text/html" xml.link href: group_url(@group), rel: "alternate", type: "text/html"
xml.id group_url(@group) xml.id group_url(@group)
xml.updated @events.latest_update_time.xmlschema if @events.any? xml.updated @events[0].updated_at.xmlschema if @events[0]
@events.each do |event| @events.each do |event|
event_to_atom(xml, event) event_to_atom(xml, event)
......
...@@ -98,6 +98,13 @@ ...@@ -98,6 +98,13 @@
%span %span
Wiki Wiki
- if project_nav_tab? :forks
= nav_link(controller: :forks, action: :index) do
= link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks' do
= icon('code-fork fw')
%span
Forks
- if project_nav_tab? :snippets - if project_nav_tab? :snippets
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do
......
...@@ -15,12 +15,11 @@ ...@@ -15,12 +15,11 @@
.file-content.blame.code.js-syntax-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_groups.each do |blame_group|
- @blame.each do |blame_group|
%tr %tr
%td.blame-commit %td.blame-commit
.commit .commit
- commit = Commit.new(blame_group[:commit], @project) - commit = blame_group[:commit]
.commit-row-title .commit-row-title
%strong %strong
= link_to_gfm truncate(commit.title, length: 35), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "cdark" = link_to_gfm truncate(commit.title, length: 35), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "cdark"
...@@ -38,8 +37,7 @@ ...@@ -38,8 +37,7 @@
\ \
- current_line += line_count - current_line += line_count
%td.lines %td.lines
%pre{class: 'code highlight'} %pre.code.highlight
%code %code
- blame_group[:lines].each do |line| - blame_group[:lines].each do |line|
:preserve #{line}
#{blame_highlighter.highlight(line)}
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
.file-content.wiki .file-content.wiki
= render_markup(blob.name, blob.data) = render_markup(blob.name, blob.data)
- else - else
.file-content.code
- unless blob.empty? - unless blob.empty?
= render 'shared/file_highlight', blob: blob = render 'shared/file_highlight', blob: blob
- else - else
.file-content.code
.nothing-here-block Empty file .nothing-here-block Empty file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
.file-content.wiki .file-content.wiki
= raw render_markup(@blob.name, @content) = raw render_markup(@blob.name, @content)
- else - else
.file-content.code .file-content.code.js-syntax-highlight
- unless @diff_lines.empty? - unless @diff_lines.empty?
%table.text-file %table.text-file
- @diff_lines.each do |line| - @diff_lines.each do |line|
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
&nbsp; &nbsp;
.dropdown.inline .dropdown.inline
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= @sort.humanize = @sort.humanize
- else - else
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'),
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
%td %td
.pull-right .pull-right
- if current_user && can?(current_user, :read_build_artifacts, commit_status.project) && commit_status.artifacts? - if current_user && can?(current_user, :read_build_artifacts, commit_status.project) && commit_status.artifacts_download_url
= link_to commit_status.artifacts_download_url, title: 'Download artifacts' do = link_to commit_status.artifacts_download_url, title: 'Download artifacts' do
%i.fa.fa-download %i.fa.fa-download
- if current_user && can?(current_user, :manage_builds, commit_status.project) - if current_user && can?(current_user, :manage_builds, commit_status.project)
......
.gray-content-block.top-block.clearfix.white.forks-top-block
.pull-left
- public_count = @public_forks.size
- protected_count = @protected_forks.size
- full_count_title = "#{public_count} public and #{protected_count} private"
== #{pluralize(@all_forks.size, 'fork')}: #{full_count_title}
.pull-right
.projects-search-form.fork-search-form
= search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter form-control',
spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' }
.dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn.sort-forks{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort:
- if @sort.present?
= sort_options_hash[@sort]
- else
= sort_title_recently_created
%b.caret
%ul.dropdown-menu.dropdown-menu-align-right
%li
- excluded_filters = [:state, :scope, :label_name, :milestone_id, :assignee_id, :author_id]
= link_to page_filter_path(sort: sort_value_recently_created, without: excluded_filters) do
= sort_title_recently_created
= link_to page_filter_path(sort: sort_value_oldest_created, without: excluded_filters) do
= sort_title_oldest_created
= link_to page_filter_path(sort: sort_value_recently_updated, without: excluded_filters) do
= sort_title_recently_updated
= link_to page_filter_path(sort: sort_value_oldest_updated, without: excluded_filters) do
= sort_title_oldest_updated
.fork-link.inline
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'pull-right btn btn-new' do
= icon('code-fork fw')
Fork
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'pull-right btn btn-new' do
= icon('code-fork fw')
Fork
.projects-list-holder
- if @public_forks.blank?
%ul.content-list
%li
.nothing-here-block No forks to show
- else
= render 'shared/projects/list', projects: @public_forks, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true
- if protected_count > 0
%ul.projects-list.private-forks-notice
%li.project-row
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(protected_count, 'private fork')
%span you have no access to.
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
- else - else
.fork-thumbnail .fork-thumbnail
= link_to namespace_project_fork_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do = link_to namespace_project_forks_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do
= image_tag namespace_icon(namespace, 100) = image_tag namespace_icon(namespace, 100)
.caption .caption
%strong %strong
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= diff.new_path = diff.new_path
- if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
%span.file-mode= "#{diff.a_mode}#{diff.b_mode}" %span.file-mode= "#{diff.a_mode}#{diff.b_mode}"
.diff-content .diff-content.code.js-syntax-highlight
%table %table
- note.truncated_diff_lines.each do |line| - note.truncated_diff_lines.each do |line|
- type = line.type - type = line.type
......
...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" xml.link href: namespace_project_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html" xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html"
xml.id namespace_project_url(@project.namespace, @project) xml.id namespace_project_url(@project.namespace, @project)
xml.updated @events.latest_update_time.xmlschema if @events.any? xml.updated @events[0].updated_at.xmlschema if @events[0?
@events.each do |event| @events.each do |event|
event_to_atom(xml, event) event_to_atom(xml, event)
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
- continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id), - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id),
notice: edit_in_new_fork_notice, notice: edit_in_new_fork_notice,
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('pencil fw') = icon('pencil fw')
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to upload a file again.", notice: edit_in_new_fork_notice + " Try to upload a file again.",
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('file fw') = icon('file fw')
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
- continue_params = { to: request.fullpath, - continue_params = { to: request.fullpath,
notice: edit_in_new_fork_notice + " Try to create a new directory again.", notice: edit_in_new_fork_notice + " Try to create a new directory again.",
notice_now: edit_in_new_fork_notice_now } notice_now: edit_in_new_fork_notice_now }
- fork_path = namespace_project_fork_path(@project.namespace, @project, namespace_key: current_user.namespace.id, - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
= link_to fork_path, method: :post do = link_to fork_path, method: :post do
= icon('folder fw') = icon('folder fw')
......
.gitlab-promo .gitlab-promo
= link_to 'Homepage', promo_url = link_to 'Homepage', promo_url
= link_to "Blog", promo_url + '/blog/' = link_to 'Blog', promo_url + '/blog/'
= link_to "@gitlab", "https://twitter.com/gitlab" = link_to '@gitlab', 'https://twitter.com/gitlab'
= link_to "Requests", "http://feedback.gitlab.com/" = link_to 'Requests', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#feature-proposals'
.dropdown.inline.prepend-left-10 .dropdown.inline.prepend-left-10
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
%span.light sort: %span.light
- if @sort.present? - if @sort.present?
= sort_options_hash[@sort] = sort_options_hash[@sort]
- else - else
......
= form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do = form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do
.append-right-10.hidden-xs.hidden-sm .append-right-10.hidden-xs.hidden-sm
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input', spellcheck: false } = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by name ...', class: 'form-control issue_search search-text-input', spellcheck: false }
= hidden_field_tag :state, params['state'] = hidden_field_tag :state, params['state']
= hidden_field_tag :scope, params['scope'] = hidden_field_tag :scope, params['scope']
= hidden_field_tag :assignee_id, params['assignee_id'] = hidden_field_tag :assignee_id, params['assignee_id']
......
- projects_limit = 20 unless local_assigns[:projects_limit] - projects_limit = 20 unless local_assigns[:projects_limit]
- avatar = true unless local_assigns[:avatar] == false - avatar = true unless local_assigns[:avatar] == false
- use_creator_avatar = false unless local_assigns[:use_creator_avatar] == true
- stars = true unless local_assigns[:stars] == false - stars = true unless local_assigns[:stars] == false
- forks = false unless local_assigns[:forks] == true
- ci = false unless local_assigns[:ci] == true - ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true - skip_namespace = false unless local_assigns[:skip_namespace] == true
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
%ul.projects-list %ul.projects-list
- projects.each_with_index do |project, i| - projects.each_with_index do |project, i|
- css_class = (i >= projects_limit) ? 'hide' : nil - css_class = (i >= projects_limit) ? 'hide' : nil
= render "shared/projects/project", project: project, skip_namespace: skip_namespace, = render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, ci: ci avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar,
forks: forks, show_last_commit_as_description: show_last_commit_as_description
- if projects.size > projects_limit - if projects.size > projects_limit
%li.bottom.center %li.bottom.center
......
- avatar = true unless local_assigns[:avatar] == false - avatar = true unless local_assigns[:avatar] == false
- stars = true unless local_assigns[:stars] == false - stars = true unless local_assigns[:stars] == false
- forks = false unless local_assigns[:forks] == true
- ci = false unless local_assigns[:ci] == true - ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true - skip_namespace = false unless local_assigns[:skip_namespace] == true
- css_class = '' unless local_assigns[:css_class] - css_class = '' unless local_assigns[:css_class]
- css_class += " no-description" unless project.description.present? - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
- css_class += " no-description" if project.description.blank? && !show_last_commit_as_description
- ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit - ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit
- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] - cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2']
- cache_key.push(ci_commit.status) if ci_commit - cache_key.push(ci_commit.status) if ci_commit
...@@ -13,6 +15,9 @@ ...@@ -13,6 +15,9 @@
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
- if avatar - if avatar
.dash-project-avatar .dash-project-avatar
- if use_creator_avatar
= image_tag avatar_icon(project.creator.email, 46), class: "avatar s46", alt:''
- else
= project_icon(project, alt: '', class: 'avatar project-avatar s46') = project_icon(project, alt: '', class: 'avatar project-avatar s46')
%span.project-full-name %span.project-full-name
%span.namespace-name %span.namespace-name
...@@ -26,10 +31,18 @@ ...@@ -26,10 +31,18 @@
- if ci_commit - if ci_commit
= render_ci_status(ci_commit) = render_ci_status(ci_commit)
&nbsp; &nbsp;
- if forks
%span
= icon('code-fork')
= project.forks_count
- if stars - if stars
%span %span
%i.fa.fa-star = icon('star')
= project.star_count = project.star_count
- if project.description.present? - if show_last_commit_as_description
.project-description
= link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit),
class: "commit-row-message"
- elsif project.description.present?
.project-description .project-description
= markdown(project.description, pipeline: :description) = markdown(project.description, pipeline: :description)
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
.file-content.wiki .file-content.wiki
= render_markup(@snippet.file_name, @snippet.data) = render_markup(@snippet.file_name, @snippet.data)
- else - else
.file-content.code
= render 'shared/file_highlight', blob: @snippet = render 'shared/file_highlight', blob: @snippet
- else - else
.file-content.code .file-content.code
......
...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear ...@@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml" xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml"
xml.link href: user_url(@user), rel: "alternate", type: "text/html" xml.link href: user_url(@user), rel: "alternate", type: "text/html"
xml.id user_url(@user) xml.id user_url(@user)
xml.updated @events.latest_update_time.xmlschema if @events.any? xml.updated @events[0].updated_at.xmlschema if @events[0]
@events.each do |event| @events.each do |event|
event_to_atom(xml, event) event_to_atom(xml, event)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
- if current_user - if current_user
.awards-controls .awards-controls
%a.add-award{"data-toggle" => "dropdown", "data-target" => "#", "href" => "#"} %a.add-award{"href" => "#"}
= icon('smile-o') = icon('smile-o')
.emoji-menu .emoji-menu
.emoji-menu-content .emoji-menu-content
......
class NewNoteWorker
include Sidekiq::Worker
sidekiq_options queue: :default
def perform(note_id, note_params)
note = Note.find(note_id)
NotificationService.new.new_note(note)
Notes::PostProcessService.new(note).execute
end
end
...@@ -4,52 +4,20 @@ class RepositoryImportWorker ...@@ -4,52 +4,20 @@ class RepositoryImportWorker
sidekiq_options queue: :gitlab_shell sidekiq_options queue: :gitlab_shell
def perform(project_id) attr_accessor :project, :current_user
project = Project.find(project_id)
if project.import_url == Project::UNKNOWN_IMPORT_URL def perform(project_id)
# In this case, we only want to import issues, not a repository. @project = Project.find(project_id)
unless project.create_repository @current_user = @project.creator
project.update(import_error: "The repository could not be created.")
project.import_fail
return
end
else
begin
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
rescue Gitlab::Shell::Error => e
project.update(import_error: e.message)
project.import_fail
return
end
end
data_import_result = result = Projects::ImportService.new(project, current_user).execute
case project.import_type
when 'github'
Gitlab::GithubImport::Importer.new(project).execute
when 'gitlab'
Gitlab::GitlabImport::Importer.new(project).execute
when 'bitbucket'
Gitlab::BitbucketImport::Importer.new(project).execute
when 'google_code'
Gitlab::GoogleCodeImport::Importer.new(project).execute
when 'fogbugz'
Gitlab::FogbugzImport::Importer.new(project).execute
else
true
end
unless data_import_result if result[:status] == :error
project.update(import_error: "The remote issue data could not be imported.") project.update(import_error: result[:message])
project.import_fail project.import_fail
return return
end end
if project.import_type == 'bitbucket'
Gitlab::BitbucketImport::KeyDeleter.new(project).execute
end
project.import_finish project.import_finish
# Explicitly update mirror so that upstream remote is created and fetched # Explicitly update mirror so that upstream remote is created and fetched
......
...@@ -236,7 +236,7 @@ Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled']. ...@@ -236,7 +236,7 @@ Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].
Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil? Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil?
Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?)|([A-Z]*-\d*))+)' if Settings.gitlab['issue_closing_pattern'].nil? Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?)|([A-Z][A-Z0-9_]+-\d+))+)' if Settings.gitlab['issue_closing_pattern'].nil?
Settings.gitlab['default_projects_features'] ||= {} Settings.gitlab['default_projects_features'] ||= {}
Settings.gitlab['webhook_timeout'] ||= 10 Settings.gitlab['webhook_timeout'] ||= 10
Settings.gitlab['max_attachment_size'] ||= 10 Settings.gitlab['max_attachment_size'] ||= 10
......
Haml::Template.options[:ugly] = true Haml::Template.options[:ugly] = true
# Remove the `:coffee` and `:coffeescript` filters
#
# See https://git.io/vztMu and http://stackoverflow.com/a/17571242/223897
Haml::Filters.remove_filter('coffee')
Haml::Filters.remove_filter('coffeescript')
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.
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