Merge remote-tracking branch 'origin/master' into feature-oauth-refactoring
This commit is contained in:
commit
bf0de1a500
|
@ -5,6 +5,8 @@ targets:
|
|||
debian-7: &wheezy
|
||||
build_dependencies:
|
||||
- libicu-dev
|
||||
- cmake
|
||||
- pkg-config
|
||||
dependencies:
|
||||
- libicu48
|
||||
- libpcre3
|
||||
|
@ -13,6 +15,8 @@ targets:
|
|||
ubuntu-14.04:
|
||||
build_dependencies:
|
||||
- libicu-dev
|
||||
- cmake
|
||||
- pkg-config
|
||||
dependencies:
|
||||
- libicu52
|
||||
- libpcre3
|
||||
|
@ -20,6 +24,8 @@ targets:
|
|||
centos-6:
|
||||
build_dependencies:
|
||||
- libicu-devel
|
||||
- cmake
|
||||
- pkgconfig
|
||||
dependencies:
|
||||
- libicu
|
||||
- pcre
|
||||
|
|
42
.travis.yml
42
.travis.yml
|
@ -1,42 +0,0 @@
|
|||
language: ruby
|
||||
cache:
|
||||
directories:
|
||||
- vendor/bundle
|
||||
env:
|
||||
global:
|
||||
- TRAVIS=true
|
||||
matrix:
|
||||
- TASK=spinach_project DB=mysql
|
||||
- TASK=spinach_other DB=mysql
|
||||
- TASK=spec:api DB=mysql
|
||||
- TASK=spec:feature DB=mysql
|
||||
- TASK=spec:other DB=mysql
|
||||
- TASK=jasmine:ci DB=mysql
|
||||
- TASK=spinach_project DB=postgresql
|
||||
- TASK=spinach_other DB=postgresql
|
||||
- TASK=spec:api DB=postgresql
|
||||
- TASK=spec:feature DB=postgresql
|
||||
- TASK=spec:other DB=postgresql
|
||||
- TASK=jasmine:ci DB=postgresql
|
||||
before_install:
|
||||
- sudo apt-get install libicu-dev -y
|
||||
install:
|
||||
- "travis_retry bundle config build.nokogiri --use-system-libraries"
|
||||
- "travis_retry bundle install --deployment --without production --retry 5"
|
||||
branches:
|
||||
only:
|
||||
- 'master'
|
||||
rvm:
|
||||
- 2.0.0
|
||||
services:
|
||||
- redis-server
|
||||
before_script:
|
||||
- "cp config/database.yml.$DB config/database.yml"
|
||||
- "cp config/gitlab.yml.example config/gitlab.yml"
|
||||
- "bundle exec rake db:setup"
|
||||
- "bundle exec rake db:seed_fu"
|
||||
script: "bundle exec rake $TASK --trace"
|
||||
notifications:
|
||||
email: false
|
||||
git:
|
||||
depth: 10
|
17
CHANGELOG
17
CHANGELOG
|
@ -10,9 +10,26 @@ v 7.3.0
|
|||
- Support Unix domain sockets for Redis
|
||||
- Store session Redis keys in 'session:gitlab:' namespace
|
||||
- Deprecate LDAP account takeover based on partial LDAP email / GitLab username match
|
||||
- Use /bin/sh instead of Bash in bin/web, bin/background_jobs (Pavel Novitskiy)
|
||||
- Keyboard shortcuts for productivity (Robert Schilling)
|
||||
- API: filter issues by state (Julien Bianchi)
|
||||
- API: filter issues by labels (Julien Bianchi)
|
||||
- Add system hook for ssh key changes
|
||||
- Add blob permalink link (Ciro Santilli)
|
||||
- Create annotated tags through UI and API (Sean Edge)
|
||||
- Snippets search (Charles Bushong)
|
||||
- Comment new push to existing MR
|
||||
- Add 'ci' to the blacklist of forbidden names
|
||||
- Improve text filtering on issues page
|
||||
- Comment & Close button
|
||||
- Process git push --all much faster
|
||||
- Don't allow edit of system notes
|
||||
- Project wiki search (Ralf Seidler)
|
||||
- Enabled Shibboleth authentication support (Matus Banas)
|
||||
|
||||
v 7.2.1
|
||||
- Delete orphaned labels during label migration (James Brooks)
|
||||
- Security: prevent XSS with stricter MIME types for raw repo files
|
||||
|
||||
v 7.2.0
|
||||
- Explore page
|
||||
|
|
3
Gemfile
3
Gemfile
|
@ -27,6 +27,7 @@ gem 'omniauth', "~> 1.1.3"
|
|||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-twitter'
|
||||
gem 'omniauth-github'
|
||||
gem 'omniauth-shibboleth'
|
||||
|
||||
# Extracting information from a git repository
|
||||
# Provide access to Gitlab::Git library
|
||||
|
@ -36,7 +37,7 @@ gem "gitlab_git", '~> 6.0'
|
|||
gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack'
|
||||
|
||||
# LDAP Auth
|
||||
gem 'gitlab_omniauth-ldap', '1.0.4', require: "omniauth-ldap"
|
||||
gem 'gitlab_omniauth-ldap', '1.1.0', require: "omniauth-ldap"
|
||||
|
||||
# Git Wiki
|
||||
gem 'gollum-lib', '~> 3.0.0'
|
||||
|
|
13
Gemfile.lock
13
Gemfile.lock
|
@ -168,7 +168,7 @@ GEM
|
|||
multi_json
|
||||
gitlab-grack (2.0.0.pre)
|
||||
rack (~> 1.5.1)
|
||||
gitlab-grit (2.6.10)
|
||||
gitlab-grit (2.6.11)
|
||||
charlock_holmes (~> 0.6)
|
||||
diff-lcs (~> 1.1)
|
||||
mime-types (~> 1.15)
|
||||
|
@ -186,8 +186,8 @@ GEM
|
|||
gitlab-linguist (~> 3.0)
|
||||
rugged (~> 0.21.0)
|
||||
gitlab_meta (7.0)
|
||||
gitlab_omniauth-ldap (1.0.4)
|
||||
net-ldap (~> 0.3.1)
|
||||
gitlab_omniauth-ldap (1.1.0)
|
||||
net-ldap (~> 0.7.0)
|
||||
omniauth (~> 1.0)
|
||||
pyu-ruby-sasl (~> 0.0.3.1)
|
||||
rubyntlm (~> 0.1.1)
|
||||
|
@ -292,7 +292,7 @@ GEM
|
|||
multi_xml (0.5.5)
|
||||
multipart-post (1.2.0)
|
||||
mysql2 (0.3.16)
|
||||
net-ldap (0.3.1)
|
||||
net-ldap (0.7.0)
|
||||
net-scp (1.1.2)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (2.8.0)
|
||||
|
@ -321,6 +321,8 @@ GEM
|
|||
omniauth-oauth2 (1.1.1)
|
||||
oauth2 (~> 0.8.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-shibboleth (1.1.1)
|
||||
omniauth (>= 1.0.0)
|
||||
omniauth-twitter (1.0.1)
|
||||
multi_json (~> 1.3)
|
||||
omniauth-oauth (~> 1.0)
|
||||
|
@ -616,7 +618,7 @@ DEPENDENCIES
|
|||
gitlab_emoji (~> 0.0.1.1)
|
||||
gitlab_git (~> 6.0)
|
||||
gitlab_meta (= 7.0)
|
||||
gitlab_omniauth-ldap (= 1.0.4)
|
||||
gitlab_omniauth-ldap (= 1.1.0)
|
||||
gollum-lib (~> 3.0.0)
|
||||
gon (~> 5.0.0)
|
||||
grape (~> 0.6.1)
|
||||
|
@ -644,6 +646,7 @@ DEPENDENCIES
|
|||
omniauth-github
|
||||
omniauth-google-oauth2
|
||||
omniauth-twitter
|
||||
omniauth-shibboleth
|
||||
org-ruby
|
||||
pg
|
||||
poltergeist (~> 1.5.1)
|
||||
|
|
|
@ -87,7 +87,7 @@ Please use ``` to format console output, logs, and code as it's very hard to rea
|
|||
|
||||
### Issue fixed in newer version
|
||||
|
||||
Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(https://github.com/gitlabhq/gitlabhq/tree/master/doc/update). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
|
||||
Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines).
|
||||
|
||||
### Improperly formatted merge request
|
||||
|
||||
|
|
31
README.md
31
README.md
|
@ -1,10 +1,8 @@
|
|||
# GitLab
|
||||
# ![logo](https://about.gitlab.com/images/gitlab_logo.png) GitLab
|
||||
|
||||
## Open source software to collaborate on code
|
||||
|
||||
![logo](https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/gitlab_logo.png)
|
||||
|
||||
![animated-screenshots](https://gist.github.com/fnkr/2f9badd56bfe0ed04ee7/raw/4f48806fbae97f556c2f78d8c2d299c04500cb0d/compiled.gif)
|
||||
![Animated screenshots](https://about.gitlab.com/images/animated/compiled.gif)
|
||||
|
||||
- Manage Git repositories with fine grained access controls that keep your code secure
|
||||
- Perform code reviews and enhance collaboration with merge requests
|
||||
|
@ -21,6 +19,8 @@
|
|||
|
||||
- [![build status](https://ci.gitlab.org/projects/1/status.png?ref=master)](https://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch)
|
||||
|
||||
- [![Build Status](https://semaphoreapp.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/243338/badge.png)](https://semaphoreapp.com/gitlabhq/gitlabhq)
|
||||
|
||||
- [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
|
||||
|
||||
- [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
|
||||
|
@ -29,14 +29,14 @@
|
|||
|
||||
## Website
|
||||
|
||||
On [www.gitlab.com](https://www.gitlab.com/) you can find more information about:
|
||||
On [about.gitlab.com](https://about.gitlab.com/) you can find more information about:
|
||||
|
||||
- [Subscriptions](https://www.gitlab.com/subscription/)
|
||||
- [Consultancy](https://www.gitlab.com/consultancy/)
|
||||
- [Community](https://www.gitlab.com/community/)
|
||||
- [Hosted GitLab.com](https://www.gitlab.com/gitlab-com/) use GitLab as a free service
|
||||
- [GitLab Enterprise Edition](https://www.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations.
|
||||
- [GitLab CI](https://www.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
- [Subscriptions](https://about.gitlab.com/subscription/)
|
||||
- [Consultancy](https://about.gitlab.com/consultancy/)
|
||||
- [Community](https://about.gitlab.com/community/)
|
||||
- [Hosted GitLab.com](https://about.gitlab.com/gitlab-com/) use GitLab as a free service
|
||||
- [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations.
|
||||
- [GitLab CI](https://about.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab.
|
||||
|
||||
## Third-party applications
|
||||
|
||||
|
@ -61,11 +61,11 @@ These applications are maintained by contributors, GitLab B.V. does not offer su
|
|||
|
||||
## Installation
|
||||
|
||||
Please see [the installation page on the GitLab website](https://www.gitlab.com/installation/).
|
||||
Please see [the installation page on the GitLab website](https://about.gitlab.com/installation/).
|
||||
|
||||
### New versions
|
||||
|
||||
Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases come out when needed. New features are detailed on the [blog](https://www.gitlab.com/blog/) and in the [changelog](CHANGELOG). For more information about the release process see the release [documentation](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/release). Features that will likely be in the next releases can be found on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
|
||||
Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases come out when needed. New features are detailed on the [blog](https://about.gitlab.com/blog/) and in the [changelog](CHANGELOG). For more information about the release process see the release [documentation](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/release). Features that will likely be in the next releases can be found on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
|
||||
|
||||
### Upgrading
|
||||
|
||||
|
@ -85,7 +85,8 @@ Please login with `root` / `5iveL!fe`
|
|||
|
||||
## Install a development environment
|
||||
|
||||
We recommend setting up your development environment with [the cookbook](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/README.md#installation). If you do not use the cookbook you might need to copy the example development unicorn configuration file
|
||||
We recommend setting up your development environment with [the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit).
|
||||
If you do not use the development kit you might need to copy the example development unicorn configuration file
|
||||
|
||||
cp config/unicorn.rb.example.development config/unicorn.rb
|
||||
|
||||
|
@ -126,7 +127,7 @@ All documentation can be found on [doc.gitlab.com/ce/](http://doc.gitlab.com/ce/
|
|||
|
||||
## Getting help
|
||||
|
||||
Please see [Getting help for GitLab](https://www.gitlab.com/getting-help/) on our website for the many options to get help.
|
||||
Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on our website for the many options to get help.
|
||||
|
||||
## Is it any good?
|
||||
|
||||
|
|
|
@ -43,25 +43,31 @@
|
|||
|
||||
$(".selected_issue").bind "change", Issues.checkChanged
|
||||
|
||||
|
||||
# Make sure we trigger ajax request only after user stop typing
|
||||
initSearch: ->
|
||||
form = $("#issue_search_form")
|
||||
last_terms = ""
|
||||
@timer = null
|
||||
$("#issue_search").keyup ->
|
||||
terms = $(this).val()
|
||||
unless terms is last_terms
|
||||
last_terms = terms
|
||||
if terms.length >= 2 or terms.length is 0
|
||||
$.ajax
|
||||
type: "GET"
|
||||
url: location.href
|
||||
data: "issue_search=" + terms
|
||||
complete: ->
|
||||
$(".loading").hide()
|
||||
success: (data) ->
|
||||
$('.issues-holder').html(data.html)
|
||||
Issues.reload()
|
||||
dataType: "json"
|
||||
clearTimeout(@timer);
|
||||
@timer = setTimeout(Issues.filterResults, 500)
|
||||
|
||||
filterResults: =>
|
||||
form = $("#issue_search_form")
|
||||
search = $("#issue_search").val()
|
||||
$('.issues-holder').css("opacity", '0.5')
|
||||
issues_url = form.attr('action') + '? '+ form.serialize()
|
||||
|
||||
$.ajax
|
||||
type: "GET"
|
||||
url: form.attr('action')
|
||||
data: form.serialize()
|
||||
complete: ->
|
||||
$('.issues-holder').css("opacity", '1.0')
|
||||
success: (data) ->
|
||||
$('.issues-holder').html(data.html)
|
||||
# Change url so if user reload a page - search results are saved
|
||||
History.replaceState {page: issues_url}, document.title, issues_url
|
||||
Issues.reload()
|
||||
dataType: "json"
|
||||
|
||||
checkChanged: ->
|
||||
checked_issues = $(".selected_issue:checked")
|
||||
|
|
|
@ -26,6 +26,7 @@ class Notes
|
|||
# Reopen and close actions for Issue/MR combined with note form submit
|
||||
$(document).on "click", ".js-note-target-reopen", @targetReopen
|
||||
$(document).on "click", ".js-note-target-close", @targetClose
|
||||
$(document).on "click", ".js-comment-button", @updateCloseButton
|
||||
$(document).on "keyup", ".js-note-text", @updateTargetButtons
|
||||
|
||||
# remove a note (in general)
|
||||
|
@ -496,6 +497,11 @@ class Notes
|
|||
if noteText.trim().length > 0
|
||||
form.submit()
|
||||
|
||||
updateCloseButton: (e) =>
|
||||
textarea = $(e.target)
|
||||
form = textarea.parents('form')
|
||||
form.find('.js-note-target-close').text('Close')
|
||||
|
||||
updateTargetButtons: (e) =>
|
||||
textarea = $(e.target)
|
||||
form = textarea.parents('form')
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class @ShortcutsNavigation extends Shortcuts
|
||||
constructor: ->
|
||||
super()
|
||||
Mousetrap.bind('g a', -> ShortcutsNavigation.findAndollowLink('.shortcuts-activity'))
|
||||
Mousetrap.bind('g p', -> ShortcutsNavigation.findAndollowLink('.shortcuts-project'))
|
||||
Mousetrap.bind('g f', -> ShortcutsNavigation.findAndollowLink('.shortcuts-tree'))
|
||||
Mousetrap.bind('g c', -> ShortcutsNavigation.findAndollowLink('.shortcuts-commits'))
|
||||
Mousetrap.bind('g n', -> ShortcutsNavigation.findAndollowLink('.shortcuts-network'))
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
&:hover {
|
||||
background: $hover;
|
||||
border-bottom: 1px solid #ADF;
|
||||
border-bottom: 1px solid darken($hover, 10%);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
|
|
|
@ -40,7 +40,7 @@ a {
|
|||
outline: none;
|
||||
color: $link_color;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
text-decoration: underline;
|
||||
color: $link_hover_color;
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,8 @@ a:focus {
|
|||
.wiki {
|
||||
@include md-typography;
|
||||
|
||||
word-wrap: break-word;
|
||||
|
||||
/* Link to current header. */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
position: relative;
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
* General Colors
|
||||
*/
|
||||
$style_color: #474D57;
|
||||
$hover: #D9EDF7;
|
||||
$hover: #FFECDB;
|
||||
|
||||
/*
|
||||
* Link colors
|
||||
*/
|
||||
$link_color: #446e9b;
|
||||
$link_hover_color: #2FA0BB;
|
||||
$link_hover_color: darken($link-color, 10%);
|
||||
|
||||
$btn-border: 1px solid #ccc;
|
||||
|
||||
|
|
|
@ -100,14 +100,9 @@
|
|||
margin-right: 15px;
|
||||
font-size: 20px;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #EEE;
|
||||
padding: 8px 12px;
|
||||
border-radius: 50px;
|
||||
background: #f5f5f5;
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
color: #BBB;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,17 @@ class Projects::BranchesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@branch = CreateBranchService.new.execute(project, params[:branch_name], params[:ref], current_user)
|
||||
|
||||
redirect_to project_tree_path(@project, @branch.name)
|
||||
result = CreateBranchService.new.execute(project,
|
||||
params[:branch_name],
|
||||
params[:ref],
|
||||
current_user)
|
||||
if result[:status] == :success
|
||||
@branch = result[:branch]
|
||||
redirect_to project_tree_path(@project, @branch.name)
|
||||
else
|
||||
@error = result[:message]
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
@ -31,7 +31,7 @@ class Projects::EditTreeController < Projects::BaseTreeController
|
|||
|
||||
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
|
||||
include_diff_info: true)
|
||||
@diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/))
|
||||
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/))
|
||||
|
||||
render layout: false
|
||||
end
|
||||
|
|
|
@ -52,7 +52,7 @@ class Projects::LabelsController < Projects::ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_labels_path(@project), notice: 'Label was removed' }
|
||||
format.js { render nothing: true }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,10 +13,16 @@ class Projects::TagsController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
@tag = CreateTagService.new.execute(@project, params[:tag_name],
|
||||
params[:ref], current_user)
|
||||
|
||||
redirect_to project_tags_path(@project)
|
||||
result = CreateTagService.new.execute(@project, params[:tag_name],
|
||||
params[:ref], params[:message],
|
||||
current_user)
|
||||
if result[:status] == :success
|
||||
@tag = result[:tag]
|
||||
redirect_to project_tags_path(@project)
|
||||
else
|
||||
@error = result[:message]
|
||||
render action: 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
@ -103,7 +103,15 @@ class ProjectsController < ApplicationController
|
|||
::Projects::DestroyService.new(@project, current_user, {}).execute
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to root_path }
|
||||
format.html do
|
||||
flash[:alert] = "Project deleted."
|
||||
|
||||
if request.referer.include?("/admin")
|
||||
redirect_to admin_projects_path
|
||||
else
|
||||
redirect_to projects_dashboard_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,15 +5,23 @@ class SearchController < ApplicationController
|
|||
@project = Project.find_by(id: params[:project_id]) if params[:project_id].present?
|
||||
@group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
|
||||
@scope = params[:scope]
|
||||
@show_snippets = params[:snippets].eql? 'true'
|
||||
|
||||
@search_results = if @project
|
||||
return access_denied! unless can?(current_user, :download_code, @project)
|
||||
|
||||
unless %w(blobs notes issues merge_requests).include?(@scope)
|
||||
unless %w(blobs notes issues merge_requests wiki_blobs).
|
||||
include?(@scope)
|
||||
@scope = 'blobs'
|
||||
end
|
||||
|
||||
Search::ProjectService.new(@project, current_user, params).execute
|
||||
elsif @show_snippets
|
||||
unless %w(snippet_blobs snippet_titles).include?(@scope)
|
||||
@scope = 'snippet_blobs'
|
||||
end
|
||||
|
||||
Search::SnippetService.new(current_user, params).execute
|
||||
else
|
||||
unless %w(projects issues merge_requests).include?(@scope)
|
||||
@scope = 'projects'
|
||||
|
|
|
@ -178,6 +178,8 @@ module ApplicationHelper
|
|||
def search_placeholder
|
||||
if @project && @project.persisted?
|
||||
"Search in this project"
|
||||
elsif @snippet || @snippets || @show_snippets
|
||||
'Search snippets'
|
||||
elsif @group && @group.persisted?
|
||||
"Search in this group"
|
||||
else
|
||||
|
|
|
@ -16,38 +16,6 @@ module CommitsHelper
|
|||
commit_person_link(commit, options.merge(source: :committer))
|
||||
end
|
||||
|
||||
def each_diff_line(diff, index)
|
||||
Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
|
||||
.each do |full_line, type, line_code, line_new, line_old|
|
||||
yield(full_line, type, line_code, line_new, line_old)
|
||||
end
|
||||
end
|
||||
|
||||
def each_diff_line_near(diff, index, expected_line_code)
|
||||
max_number_of_lines = 16
|
||||
|
||||
prev_match_line = nil
|
||||
prev_lines = []
|
||||
|
||||
each_diff_line(diff, index) do |full_line, type, line_code, line_new, line_old|
|
||||
line = [full_line, type, line_code, line_new, line_old]
|
||||
if line_code != expected_line_code
|
||||
if type == "match"
|
||||
prev_lines.clear
|
||||
prev_match_line = line
|
||||
else
|
||||
prev_lines.push(line)
|
||||
prev_lines.shift if prev_lines.length >= max_number_of_lines
|
||||
end
|
||||
else
|
||||
yield(prev_match_line) if !prev_match_line.nil?
|
||||
prev_lines.each { |ln| yield(ln) }
|
||||
yield(line)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def image_diff_class(diff)
|
||||
if diff.deleted_file
|
||||
"deleted"
|
||||
|
@ -63,14 +31,6 @@ module CommitsHelper
|
|||
escape_javascript(render "projects/commits/#{template}", commit: commit, project: project) unless commit.nil?
|
||||
end
|
||||
|
||||
def diff_line_content(line)
|
||||
if line.blank?
|
||||
" "
|
||||
else
|
||||
line
|
||||
end
|
||||
end
|
||||
|
||||
# Breadcrumb links for a Project and, if applicable, a tree path
|
||||
def commits_breadcrumbs
|
||||
return unless @project && @ref
|
||||
|
@ -105,82 +65,6 @@ module CommitsHelper
|
|||
branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe
|
||||
end
|
||||
|
||||
def parallel_diff_lines(project, commit, diff, file)
|
||||
old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
|
||||
deleted_lines = {}
|
||||
added_lines = {}
|
||||
each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old|
|
||||
if type == "old"
|
||||
deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
|
||||
elsif type == "new"
|
||||
added_lines[line_new] = { line_code: line_code, type: type, line: line }
|
||||
end
|
||||
end
|
||||
max_length = old_file ? [old_file.loc, file.loc].max : file.loc
|
||||
|
||||
offset1 = 0
|
||||
offset2 = 0
|
||||
old_lines = []
|
||||
new_lines = []
|
||||
|
||||
max_length.times do |line_index|
|
||||
line_index1 = line_index - offset1
|
||||
line_index2 = line_index - offset2
|
||||
deleted_line = deleted_lines[line_index1 + 1]
|
||||
added_line = added_lines[line_index2 + 1]
|
||||
old_line = old_file.lines[line_index1] if old_file
|
||||
new_line = file.lines[line_index2]
|
||||
|
||||
if deleted_line && added_line
|
||||
elsif deleted_line
|
||||
new_line = nil
|
||||
offset2 += 1
|
||||
elsif added_line
|
||||
old_line = nil
|
||||
offset1 += 1
|
||||
end
|
||||
|
||||
old_lines[line_index] = DiffLine.new
|
||||
new_lines[line_index] = DiffLine.new
|
||||
|
||||
# old
|
||||
if line_index == 0 && diff.new_file
|
||||
old_lines[line_index].type = :file_created
|
||||
old_lines[line_index].content = 'File was created'
|
||||
elsif deleted_line
|
||||
old_lines[line_index].type = :deleted
|
||||
old_lines[line_index].content = old_line
|
||||
old_lines[line_index].num = line_index1 + 1
|
||||
old_lines[line_index].code = deleted_line[:line_code]
|
||||
elsif old_line
|
||||
old_lines[line_index].type = :no_change
|
||||
old_lines[line_index].content = old_line
|
||||
old_lines[line_index].num = line_index1 + 1
|
||||
else
|
||||
old_lines[line_index].type = :added
|
||||
end
|
||||
|
||||
# new
|
||||
if line_index == 0 && diff.deleted_file
|
||||
new_lines[line_index].type = :file_deleted
|
||||
new_lines[line_index].content = "File was deleted"
|
||||
elsif added_line
|
||||
new_lines[line_index].type = :added
|
||||
new_lines[line_index].num = line_index2 + 1
|
||||
new_lines[line_index].content = new_line
|
||||
new_lines[line_index].code = added_line[:line_code]
|
||||
elsif new_line
|
||||
new_lines[line_index].type = :no_change
|
||||
new_lines[line_index].num = line_index2 + 1
|
||||
new_lines[line_index].content = new_line
|
||||
else
|
||||
new_lines[line_index].type = :deleted
|
||||
end
|
||||
end
|
||||
|
||||
return old_lines, new_lines
|
||||
end
|
||||
|
||||
def link_to_browse_code(project, commit)
|
||||
if current_controller?(:projects, :commits)
|
||||
if @repo.blob_at(commit.id, @path)
|
||||
|
@ -229,14 +113,6 @@ module CommitsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def diff_file_mode_changed?(diff)
|
||||
diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
|
||||
end
|
||||
|
||||
def unfold_bottom_class(bottom)
|
||||
(bottom) ? 'js-unfold-bottom' : ''
|
||||
end
|
||||
|
||||
def view_file_btn(commit_sha, diff, project)
|
||||
link_to project_blob_path(project, tree_join(commit_sha, diff.new_path)),
|
||||
class: 'btn btn-small view-file js-view-file' do
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
module DiffHelper
|
||||
def safe_diff_files(diffs)
|
||||
def allowed_diff_size
|
||||
if diff_hard_limit_enabled?
|
||||
diffs.first(Commit::DIFF_HARD_LIMIT_FILES)
|
||||
Commit::DIFF_HARD_LIMIT_FILES
|
||||
else
|
||||
diffs.first(Commit::DIFF_SAFE_FILES)
|
||||
Commit::DIFF_SAFE_FILES
|
||||
end
|
||||
end
|
||||
|
||||
def show_diff_size_warninig?(diffs)
|
||||
safe_diff_files(diffs).size < diffs.size
|
||||
def safe_diff_files(diffs)
|
||||
diffs.first(allowed_diff_size).map do |diff|
|
||||
Gitlab::Diff::File.new(diff)
|
||||
end
|
||||
end
|
||||
|
||||
def show_diff_size_warning?(diffs)
|
||||
diffs.size > allowed_diff_size
|
||||
end
|
||||
|
||||
def diff_hard_limit_enabled?
|
||||
|
@ -19,4 +25,76 @@ module DiffHelper
|
|||
false
|
||||
end
|
||||
end
|
||||
|
||||
def generate_line_code(file_path, line)
|
||||
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, line_code, right_line_type, right_line_number, right_line_content]
|
||||
#
|
||||
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_type = next_line.type
|
||||
next_line = next_line.text
|
||||
end
|
||||
|
||||
line = [type, line_old, full_line, line_code, next_type, line_new]
|
||||
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]
|
||||
lines.push(line)
|
||||
elsif type == 'old'
|
||||
if next_type == 'new'
|
||||
# Left side has text removed, right side has text added
|
||||
line.push(next_line)
|
||||
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
|
||||
line.pop # remove the newline
|
||||
line.push(nil) # no line number on the right panel
|
||||
line.push(" ") # empty line on the right panel
|
||||
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]
|
||||
lines.push(line)
|
||||
end
|
||||
end
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
def unfold_bottom_class(bottom)
|
||||
(bottom) ? 'js-unfold-bottom' : ''
|
||||
end
|
||||
|
||||
def diff_line_content(line)
|
||||
if line.blank?
|
||||
" "
|
||||
else
|
||||
line
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -178,12 +178,6 @@ module Network
|
|||
space = find_free_space(time_range, 2, space_base)
|
||||
leaves.each do |l|
|
||||
l.spaces << space
|
||||
# Also add space to parent
|
||||
l.parents(@map).each do |parent|
|
||||
if 0 < parent.space && parent.space < space
|
||||
parent.spaces << space
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# and mark it as reserved
|
||||
|
|
|
@ -117,6 +117,25 @@ class Note < ActiveRecord::Base
|
|||
})
|
||||
end
|
||||
|
||||
def create_new_commits_note(noteable, project, author, commits)
|
||||
commits_text = ActionController::Base.helpers.pluralize(commits.size, 'new commit')
|
||||
body = "Added #{commits_text}:\n\n"
|
||||
|
||||
commits.each do |commit|
|
||||
message = "* #{commit.short_id} - #{commit.title}"
|
||||
body << message
|
||||
body << "\n"
|
||||
end
|
||||
|
||||
create(
|
||||
noteable: noteable,
|
||||
project: project,
|
||||
author: author,
|
||||
note: body,
|
||||
system: true
|
||||
)
|
||||
end
|
||||
|
||||
def discussions_from_notes(notes)
|
||||
discussion_ids = []
|
||||
discussions = []
|
||||
|
@ -190,9 +209,10 @@ class Note < ActiveRecord::Base
|
|||
noteable.diffs.each do |mr_diff|
|
||||
next unless mr_diff.new_path == self.diff.new_path
|
||||
|
||||
Gitlab::DiffParser.new(mr_diff.diff.lines.to_a, mr_diff.new_path).
|
||||
each do |full_line, type, line_code, line_new, line_old|
|
||||
if full_line == diff_line
|
||||
lines = Gitlab::Diff::Parser.new.parse(mr_diff.diff.lines.to_a)
|
||||
|
||||
lines.each do |line|
|
||||
if line.text == diff_line
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -213,6 +233,14 @@ class Note < ActiveRecord::Base
|
|||
diff.new_path if diff
|
||||
end
|
||||
|
||||
def file_path
|
||||
if diff.new_path.present?
|
||||
diff.new_path
|
||||
elsif diff.old_path.present?
|
||||
diff.old_path
|
||||
end
|
||||
end
|
||||
|
||||
def diff_old_line
|
||||
line_code.split('_')[1].to_i
|
||||
end
|
||||
|
@ -221,19 +249,49 @@ class Note < ActiveRecord::Base
|
|||
line_code.split('_')[2].to_i
|
||||
end
|
||||
|
||||
def generate_line_code(line)
|
||||
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
|
||||
end
|
||||
|
||||
def diff_line
|
||||
return @diff_line if @diff_line
|
||||
|
||||
if diff
|
||||
Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
|
||||
.each do |full_line, type, line_code, line_new, line_old|
|
||||
@diff_line = full_line if line_code == self.line_code
|
||||
diff_lines.each do |line|
|
||||
if generate_line_code(line) == self.line_code
|
||||
@diff_line = line.text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@diff_line
|
||||
end
|
||||
|
||||
def truncated_diff_lines
|
||||
max_number_of_lines = 16
|
||||
prev_match_line = nil
|
||||
prev_lines = []
|
||||
|
||||
diff_lines.each do |line|
|
||||
if generate_line_code(line) != self.line_code
|
||||
if line.type == "match"
|
||||
prev_lines.clear
|
||||
prev_match_line = line
|
||||
else
|
||||
prev_lines.push(line)
|
||||
prev_lines.shift if prev_lines.length >= max_number_of_lines
|
||||
end
|
||||
else
|
||||
prev_lines << line
|
||||
return prev_lines
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def diff_lines
|
||||
@diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a)
|
||||
end
|
||||
|
||||
def discussion_id
|
||||
@discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code)
|
||||
end
|
||||
|
|
|
@ -70,7 +70,7 @@ class Project < ActiveRecord::Base
|
|||
has_many :merge_requests, dependent: :destroy, foreign_key: "target_project_id"
|
||||
# Merge requests from source project should be kept when source project was removed
|
||||
has_many :fork_merge_requests, foreign_key: "source_project_id", class_name: MergeRequest
|
||||
has_many :issues, -> { order "state DESC, created_at DESC" }, dependent: :destroy
|
||||
has_many :issues, -> { order 'issues.state DESC, issues.created_at DESC' }, dependent: :destroy
|
||||
has_many :labels, dependent: :destroy
|
||||
has_many :services, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
|
@ -400,18 +400,35 @@ class Project < ActiveRecord::Base
|
|||
def update_merge_requests(oldrev, newrev, ref, user)
|
||||
return true unless ref =~ /heads/
|
||||
branch_name = ref.gsub("refs/heads/", "")
|
||||
c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
|
||||
commits = self.repository.commits_between(oldrev, newrev)
|
||||
c_ids = commits.map(&:id)
|
||||
|
||||
# Close merge requests
|
||||
mrs = self.merge_requests.opened.where(target_branch: branch_name).to_a
|
||||
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
|
||||
mrs.each { |merge_request| MergeRequests::MergeService.new.execute(merge_request, user, nil) }
|
||||
|
||||
mrs.uniq.each do |merge_request|
|
||||
MergeRequests::MergeService.new.execute(merge_request, user, nil)
|
||||
end
|
||||
|
||||
# Update code for merge requests into project between project branches
|
||||
mrs = self.merge_requests.opened.by_branch(branch_name).to_a
|
||||
# Update code for merge requests between project and project fork
|
||||
mrs += self.fork_merge_requests.opened.by_branch(branch_name).to_a
|
||||
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
|
||||
|
||||
mrs.uniq.each do |merge_request|
|
||||
merge_request.reload_code
|
||||
merge_request.mark_as_unchecked
|
||||
end
|
||||
|
||||
# Add comment about pushing new commits to merge requests
|
||||
mrs = self.merge_requests.opened.where(source_branch: branch_name).to_a
|
||||
mrs += self.fork_merge_requests.opened.where(source_branch: branch_name).to_a
|
||||
|
||||
mrs.uniq.each do |merge_request|
|
||||
Note.create_new_commits_note(merge_request, merge_request.project,
|
||||
user, commits)
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
|
|
@ -5,21 +5,17 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class AssemblaService < Service
|
||||
include HTTParty
|
||||
|
||||
prop_accessor :token, :subdomain
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,19 +5,15 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class CampfireService < Service
|
||||
prop_accessor :token, :subdomain, :room
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,16 +5,11 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
# Base class for CI services
|
||||
|
|
|
@ -5,19 +5,15 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class EmailsOnPushService < Service
|
||||
prop_accessor :recipients
|
||||
validates :recipients, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,21 +5,17 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
require "flowdock-git-hook"
|
||||
|
||||
class FlowdockService < Service
|
||||
prop_accessor :token
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,21 +5,17 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
require "gemnasium/gitlab_service"
|
||||
|
||||
class GemnasiumService < Service
|
||||
prop_accessor :token, :api_key
|
||||
validates :token, :api_key, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,19 +5,15 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# property :text
|
||||
#
|
||||
|
||||
class GitlabCiService < CiService
|
||||
prop_accessor :project_url, :token
|
||||
validates :project_url, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
|
|
|
@ -5,21 +5,17 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class HipchatService < Service
|
||||
MAX_COMMITS = 3
|
||||
|
||||
prop_accessor :token, :room
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,21 +5,17 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class PivotaltrackerService < Service
|
||||
include HTTParty
|
||||
|
||||
prop_accessor :token
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
||||
def title
|
||||
|
|
|
@ -5,19 +5,15 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
# properties :text
|
||||
#
|
||||
|
||||
class SlackService < Service
|
||||
prop_accessor :room, :subdomain, :token
|
||||
validates :room, presence: true, if: :activated?
|
||||
validates :subdomain, presence: true, if: :activated?
|
||||
validates :token, presence: true, if: :activated?
|
||||
|
|
|
@ -64,10 +64,10 @@ class Repository
|
|||
gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
|
||||
end
|
||||
|
||||
def add_tag(tag_name, ref)
|
||||
def add_tag(tag_name, ref, message = nil)
|
||||
Rails.cache.delete(cache_key(:tag_names))
|
||||
|
||||
gitlab_shell.add_tag(path_with_namespace, tag_name, ref)
|
||||
gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
|
||||
end
|
||||
|
||||
def rm_branch(branch_name)
|
||||
|
|
|
@ -5,22 +5,19 @@
|
|||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# token :string(255)
|
||||
# project_id :integer not null
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# active :boolean default(FALSE), not null
|
||||
# project_url :string(255)
|
||||
# subdomain :string(255)
|
||||
# room :string(255)
|
||||
# recipients :text
|
||||
# api_key :string(255)
|
||||
#
|
||||
# properties :text
|
||||
|
||||
# To add new service you should build a class inherited from Service
|
||||
# and implement a set of methods
|
||||
class Service < ActiveRecord::Base
|
||||
serialize :properties, JSON
|
||||
|
||||
default_value_for :active, false
|
||||
default_value_for :properties, {}
|
||||
|
||||
belongs_to :project
|
||||
has_one :service_hook
|
||||
|
@ -63,4 +60,20 @@ class Service < ActiveRecord::Base
|
|||
def can_test?
|
||||
!project.empty_repo?
|
||||
end
|
||||
|
||||
# Provide convenient accessor methods
|
||||
# for each serialized property.
|
||||
def self.prop_accessor(*args)
|
||||
args.each do |arg|
|
||||
class_eval %{
|
||||
def #{arg}
|
||||
properties['#{arg}']
|
||||
end
|
||||
|
||||
def #{arg}=(value)
|
||||
self.properties['#{arg}'] = value
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -65,4 +65,18 @@ class Snippet < ActiveRecord::Base
|
|||
def expired?
|
||||
expires_at && expires_at < Time.current
|
||||
end
|
||||
|
||||
class << self
|
||||
def search(query)
|
||||
where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%")
|
||||
end
|
||||
|
||||
def search_code(query)
|
||||
where('(content LIKE :query)', query: "%#{query}%")
|
||||
end
|
||||
|
||||
def accessible_to(user)
|
||||
where('private = ? OR author_id = ?', false, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,38 @@
|
|||
class CreateBranchService
|
||||
def execute(project, branch_name, ref, current_user)
|
||||
valid_branch = Gitlab::GitRefValidator.validate(branch_name)
|
||||
if valid_branch == false
|
||||
return error('Branch name invalid')
|
||||
end
|
||||
|
||||
repository = project.repository
|
||||
existing_branch = repository.find_branch(branch_name)
|
||||
if existing_branch
|
||||
return error('Branch already exists')
|
||||
end
|
||||
|
||||
repository.add_branch(branch_name, ref)
|
||||
new_branch = repository.find_branch(branch_name)
|
||||
|
||||
if new_branch
|
||||
Event.create_ref_event(project, current_user, new_branch, 'add')
|
||||
return success(new_branch)
|
||||
else
|
||||
return error('Invalid reference name')
|
||||
end
|
||||
end
|
||||
|
||||
new_branch
|
||||
def error(message)
|
||||
{
|
||||
message: message,
|
||||
status: :error
|
||||
}
|
||||
end
|
||||
|
||||
def success(branch)
|
||||
{
|
||||
branch: branch,
|
||||
status: :success
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,42 @@
|
|||
class CreateTagService
|
||||
def execute(project, tag_name, ref, current_user)
|
||||
def execute(project, tag_name, ref, message, current_user)
|
||||
valid_tag = Gitlab::GitRefValidator.validate(tag_name)
|
||||
if valid_tag == false
|
||||
return error('Tag name invalid')
|
||||
end
|
||||
|
||||
repository = project.repository
|
||||
repository.add_tag(tag_name, ref)
|
||||
existing_tag = repository.find_tag(tag_name)
|
||||
if existing_tag
|
||||
return error('Tag already exists')
|
||||
end
|
||||
|
||||
if message
|
||||
message.gsub!(/^\s+|\s+$/, '')
|
||||
end
|
||||
|
||||
repository.add_tag(tag_name, ref, message)
|
||||
new_tag = repository.find_tag(tag_name)
|
||||
|
||||
if new_tag
|
||||
Event.create_ref_event(project, current_user, new_tag, 'add', 'refs/tags')
|
||||
return success(new_tag)
|
||||
else
|
||||
return error('Invalid reference name')
|
||||
end
|
||||
end
|
||||
|
||||
new_tag
|
||||
def error(message)
|
||||
{
|
||||
message: message,
|
||||
status: :error
|
||||
}
|
||||
end
|
||||
|
||||
def success(branch)
|
||||
{
|
||||
tag: branch,
|
||||
status: :success
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,21 +5,21 @@ class DeleteBranchService
|
|||
|
||||
# No such branch
|
||||
unless branch
|
||||
return error('No such branch')
|
||||
return error('No such branch', 404)
|
||||
end
|
||||
|
||||
if branch_name == repository.root_ref
|
||||
return error('Cannot remove HEAD branch')
|
||||
return error('Cannot remove HEAD branch', 405)
|
||||
end
|
||||
|
||||
# Dont allow remove of protected branch
|
||||
if project.protected_branch?(branch_name)
|
||||
return error('Protected branch cant be removed')
|
||||
return error('Protected branch cant be removed', 405)
|
||||
end
|
||||
|
||||
# Dont allow user to remove branch if he is not allowed to push
|
||||
unless current_user.can?(:push_code, project)
|
||||
return error('You dont have push access to repo')
|
||||
return error('You dont have push access to repo', 405)
|
||||
end
|
||||
|
||||
if repository.rm_branch(branch_name)
|
||||
|
@ -30,9 +30,10 @@ class DeleteBranchService
|
|||
end
|
||||
end
|
||||
|
||||
def error(message)
|
||||
def error(message, return_code = 400)
|
||||
{
|
||||
message: message,
|
||||
return_code: return_code,
|
||||
state: :error
|
||||
}
|
||||
end
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module Search
|
||||
class SnippetService
|
||||
attr_accessor :current_user, :params
|
||||
|
||||
def initialize(user, params)
|
||||
@current_user, @params = user, params.dup
|
||||
end
|
||||
|
||||
def execute
|
||||
snippet_ids = Snippet.accessible_to(current_user).pluck(:id)
|
||||
Gitlab::SnippetSearchResults.new(snippet_ids, params[:search])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -70,6 +70,14 @@
|
|||
%strong.cred
|
||||
No
|
||||
|
||||
%li
|
||||
%span.light Current sign-in at:
|
||||
%strong
|
||||
- if @user.current_sign_in_at
|
||||
= @user.current_sign_in_at.stamp("Nov 12, 2031")
|
||||
- else
|
||||
never
|
||||
|
||||
%li
|
||||
%span.light Last sign-in at:
|
||||
%strong
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
%li
|
||||
.project-access-icon
|
||||
= visibility_level_icon(project.visibility_level)
|
||||
%h4.project-title
|
||||
.project-access-icon
|
||||
= visibility_level_icon(project.visibility_level)
|
||||
= link_to project.name_with_namespace, project
|
||||
|
||||
.project-description
|
||||
%h4.project-title
|
||||
= link_to project.name_with_namespace, project
|
||||
|
||||
- if current_page?(starred_explore_projects_path)
|
||||
%strong.pull-right
|
||||
= pluralize project.star_count, 'star'
|
||||
- if current_page?(starred_explore_projects_path)
|
||||
%strong.pull-right
|
||||
= pluralize project.star_count, 'star'
|
||||
|
||||
.project-info
|
||||
- if project.description.present?
|
||||
%p.project-description.str-truncated
|
||||
= project.description
|
||||
|
|
|
@ -78,9 +78,9 @@
|
|||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
.key a
|
||||
.key p
|
||||
%td
|
||||
Go to the activity feed
|
||||
Go to the project's activity feed
|
||||
%tr
|
||||
%td.shortcut
|
||||
.key g
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
- if @project && @project.persisted?
|
||||
= hidden_field_tag :project_id, @project.id
|
||||
= hidden_field_tag :search_code, true
|
||||
- if @snippet || @snippets
|
||||
= hidden_field_tag :snippets, true
|
||||
= hidden_field_tag :repository_ref, @ref
|
||||
= submit_tag 'Go' if ENV['RAILS_ENV'] == 'test'
|
||||
.search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%ul.project-navigation
|
||||
= nav_link(path: 'projects#show', html_options: {class: "home"}) do
|
||||
= link_to project_path(@project), title: 'Project', class: 'shortcuts-activity' do
|
||||
= link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
|
||||
Project
|
||||
- if project_nav_tab? :files
|
||||
= nav_link(controller: %w(tree blob blame edit_tree new_tree)) do
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
%p
|
||||
Assignee changed
|
||||
- if @previous_assignee
|
||||
from
|
||||
%strong #{@previous_assignee.name}
|
||||
to
|
||||
- if issuable.assignee_id
|
||||
%strong #{issuable.assignee_name}
|
||||
- else
|
||||
%strong Unassigned
|
|
@ -0,0 +1,6 @@
|
|||
Reassigned <%= issuable.class.model_name.human.titleize %> <%= issuable.iid %>
|
||||
|
||||
<%= url_for([issuable.project, issuable, {only_path: false}]) %>
|
||||
|
||||
Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%>
|
||||
to <%= "#{issuable.assignee_id ? issuable.assignee_name : 'Unassigned'}" %>
|
|
@ -1,11 +1 @@
|
|||
%p
|
||||
Assignee changed
|
||||
- if @previous_assignee
|
||||
from
|
||||
%strong #{@previous_assignee.name}
|
||||
to
|
||||
- if @issue.assignee_id
|
||||
%strong #{@issue.assignee_name}
|
||||
- else
|
||||
%strong Unassigned
|
||||
|
||||
= render 'reassigned_issuable_email', issuable: @issue
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
Reassigned Issue <%= @issue.iid %>
|
||||
|
||||
<%= url_for(project_issue_url(@issue.project, @issue)) %>
|
||||
|
||||
Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee %> to <%= "#{@issue.assignee_id ? @issue.assignee_name : 'Unassigned'}" %>
|
||||
<%= render 'reassigned_issuable_email', issuable: @issue %>
|
||||
|
|
|
@ -1,7 +1 @@
|
|||
%p
|
||||
Assignee changed
|
||||
- if @previous_assignee
|
||||
from
|
||||
%strong #{@previous_assignee.name}
|
||||
to
|
||||
%strong #{@merge_request.assignee_name}
|
||||
= render 'reassigned_issuable_email', issuable: @merge_request
|
||||
|
|
|
@ -1,7 +1 @@
|
|||
Reassigned Merge Request #<%= @merge_request.iid %>
|
||||
|
||||
<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
|
||||
|
||||
|
||||
Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee %> to <%= @merge_request.assignee_name %>
|
||||
|
||||
<%= render 'reassigned_issuable_email', issuable: @merge_request %>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
.form-group
|
||||
= f.label :title, class: 'control-label' do
|
||||
%strong= 'Title *'
|
||||
.col-sm-10
|
||||
= f.text_field :title, maxlength: 255, autofocus: true,
|
||||
class: 'form-control pad js-gfm-input', required: true
|
||||
.form-group
|
||||
= f.label :description, 'Description', class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.text_area :description, rows: 14,
|
||||
class: 'form-control js-gfm-input markdown-area'
|
||||
.col-sm-12.hint
|
||||
.pull-left
|
||||
Parsed with
|
||||
#{link_to 'GitLab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}.
|
||||
.pull-right
|
||||
Attach images (JPG, PNG, GIF) by dragging & dropping
|
||||
or #{link_to 'selecting them', '#', class: 'markdown-selector' }.
|
||||
.clearfix
|
||||
.error-alert
|
||||
%hr
|
||||
.form-group
|
||||
.issue-assignee
|
||||
= f.label :assignee_id, class: 'control-label' do
|
||||
%i.icon-user
|
||||
Assign to
|
||||
.col-sm-10
|
||||
= project_users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]",
|
||||
placeholder: 'Select a user', class: 'custom-form-control',
|
||||
selected: issuable.assignee_id)
|
||||
|
||||
= link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
|
||||
.form-group
|
||||
.issue-milestone
|
||||
= f.label :milestone_id, class: 'control-label' do
|
||||
%i.icon-time
|
||||
Milestone
|
||||
.col-sm-10= f.select(:milestone_id, milestone_options(issuable),
|
||||
{ include_blank: 'Select milestone' }, { class: 'select2' })
|
|
@ -13,6 +13,9 @@
|
|||
- else
|
||||
= link_to "blame", project_blame_path(@project, @id), class: "btn btn-small" unless @blob.empty?
|
||||
= link_to "history", project_commits_path(@project, @id), class: "btn btn-small"
|
||||
- if @ref != @commit.sha
|
||||
= link_to 'permalink', project_blob_path(@project,
|
||||
tree_join(@commit.sha, @path)), class: 'btn btn-small'
|
||||
|
||||
- if allowed_tree_edit?
|
||||
= link_to '#modal-remove-blob', class: "remove-blob btn btn-small btn-remove", "data-toggle" => "modal" do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- if @lines.present?
|
||||
- if @form.unfold? && @form.since != 1 && !@form.bottom?
|
||||
%tr.line_holder{ id: @form.since }
|
||||
= render "projects/commits/diffs/match_line", {line: @match_line,
|
||||
= render "projects/diffs/match_line", {line: @match_line,
|
||||
line_old: @form.since, line_new: @form.since, bottom: false}
|
||||
|
||||
- @lines.each_with_index do |line, index|
|
||||
|
@ -15,5 +15,5 @@
|
|||
|
||||
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
|
||||
%tr.line_holder{ id: @form.to }
|
||||
= render "projects/commits/diffs/match_line", {line: @match_line,
|
||||
= render "projects/diffs/match_line", {line: @match_line,
|
||||
line_old: @form.to, line_new: @form.to, bottom: true}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
%li(class="js-branch-#{branch.name}")
|
||||
%h4
|
||||
= link_to project_tree_path(@project, branch.name) do
|
||||
%strong= truncate(branch.name, length: 60)
|
||||
%strong.str-truncated= branch.name
|
||||
- if branch.name == @repository.root_ref
|
||||
%span.label.label-info default
|
||||
- if @project.protected_branch? branch.name
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
- if @error
|
||||
.alert.alert-danger
|
||||
%button{ type: "button", class: "close", "data-dismiss" => "alert"} ×
|
||||
= @error
|
||||
%h3.page-title
|
||||
%i.icon-code-fork
|
||||
New branch
|
||||
|
@ -5,11 +9,11 @@
|
|||
.form-group
|
||||
= label_tag :branch_name, 'Name for new branch', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :branch_name, nil, placeholder: 'enter new branch name', required: true, tabindex: 1, class: 'form-control'
|
||||
= text_field_tag :branch_name, params[:branch_name], placeholder: 'enter new branch name', required: true, tabindex: 1, class: 'form-control'
|
||||
.form-group
|
||||
= label_tag :ref, 'Create from', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :ref, nil, placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control'
|
||||
= text_field_tag :ref, params[:ref], placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control'
|
||||
.form-actions
|
||||
= submit_tag 'Create branch', class: 'btn btn-create', tabindex: 3
|
||||
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
= render "commit_box"
|
||||
= render "projects/commits/diffs", diffs: @diffs, project: @project
|
||||
= render "projects/diffs/diffs", diffs: @diffs, project: @project
|
||||
= render "projects/notes/notes_with_form"
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
- file = project.repository.blob_for_diff(@commit, diff)
|
||||
- return unless file
|
||||
- blob_diff_path = diff_project_blob_path(project,
|
||||
tree_join(@commit.id, diff.new_path))
|
||||
.diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }}
|
||||
.diff-header{id: "file-path-#{hexdigest(diff.new_path || diff.old_path)}"}
|
||||
- if diff.deleted_file
|
||||
%span= diff.old_path
|
||||
|
||||
.diff-btn-group
|
||||
- if @commit.parent_ids.present?
|
||||
= view_file_btn(@commit.parent_id, diff, project)
|
||||
- else
|
||||
%span= diff.new_path
|
||||
- if diff_file_mode_changed?(diff)
|
||||
%span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
|
||||
|
||||
.diff-btn-group
|
||||
%label
|
||||
= check_box_tag nil, 1, false, class: "js-toggle-diff-line-wrap"
|
||||
Wrap text
|
||||
|
||||
= link_to "#", class: "js-toggle-diff-comments btn btn-small" do
|
||||
%i.icon-chevron-down
|
||||
Diff comments
|
||||
|
||||
|
||||
- if @merge_request && @merge_request.source_project
|
||||
= link_to project_edit_tree_path(@merge_request.source_project, tree_join(@merge_request.source_branch, diff.new_path), from_merge_request_id: @merge_request.id), { class: 'btn btn-small' } do
|
||||
Edit
|
||||
|
||||
|
||||
= view_file_btn(@commit.id, diff, project)
|
||||
|
||||
.diff-content
|
||||
-# Skipp all non non-supported blobs
|
||||
- return unless file.respond_to?('text?')
|
||||
- if file.text?
|
||||
- if params[:view] == 'parallel'
|
||||
= render "projects/commits/parallel_view", diff: diff, project: project, file: file, index: i
|
||||
- else
|
||||
= render "projects/commits/text_file", diff: diff, index: i
|
||||
- elsif file.image?
|
||||
- old_file = project.repository.prev_blob_for_diff(@commit, diff)
|
||||
= render "projects/commits/image", diff: diff, old_file: old_file, file: file, index: i
|
||||
- else
|
||||
.nothing-here-block No preview for this file type
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/ Side-by-side diff view
|
||||
- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
|
||||
- num_lines = old_lines.length
|
||||
|
||||
%div.text-file
|
||||
%table
|
||||
- num_lines.times do |index|
|
||||
- new_line = new_lines[index]
|
||||
- old_line = old_lines[index]
|
||||
%tr.line_holder.parallel
|
||||
-# For old line
|
||||
- if old_line.type == :file_created
|
||||
%td.old_line= old_line.num
|
||||
%td.line_content.parallel= "File was created"
|
||||
- elsif old_line.type == :deleted
|
||||
%td.old_line.old= old_line.num
|
||||
%td.line_content{class: "parallel noteable_line old #{old_line.code}", "line_code" => old_line.code}= old_line.content
|
||||
- else old_line.type == :no_change
|
||||
%td.old_line= old_line.num
|
||||
%td.line_content.parallel= old_line.content
|
||||
|
||||
-# For new line
|
||||
- if new_line.type == :file_deleted
|
||||
%td.new_line= new_line.num
|
||||
%td.line_content.parallel= "File was deleted"
|
||||
- elsif new_line.type == :added
|
||||
%td.new_line.new= new_line.num
|
||||
%td.line_content{class: "parallel noteable_line new #{new_line.code}", "line_code" => new_line.code}= new_line.content
|
||||
- else new_line.type == :no_change
|
||||
%td.new_line= new_line.num
|
||||
%td.line_content.parallel= new_line.content
|
||||
|
||||
- if @reply_allowed
|
||||
- comments1 = @line_notes.select { |n| n.line_code == old_line.code }.sort_by(&:created_at)
|
||||
- comments2 = @line_notes.select { |n| n.line_code == new_line.code }.sort_by(&:created_at)
|
||||
- unless comments1.empty? and comments2.empty?
|
||||
= render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
- else
|
||||
%ul.well-list= render Commit.decorate(@commits), project: @project
|
||||
|
||||
= render "projects/commits/diffs", diffs: @diffs, project: @project
|
||||
= render "projects/diffs/diffs", diffs: @diffs, project: @project
|
||||
|
||||
- else
|
||||
.light-well
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.row
|
||||
.col-md-8
|
||||
= render 'projects/commits/diff_stats', diffs: diffs
|
||||
= render 'projects/diffs/stats', diffs: diffs
|
||||
.col-md-4
|
||||
%ul.nav.nav-tabs
|
||||
%li.pull-right{class: params[:view] == 'parallel' ? 'active' : ''}
|
||||
|
@ -11,16 +11,17 @@
|
|||
- params_copy[:view] = 'inline'
|
||||
= link_to "Inline Diff", url_for(params_copy), {id: "commit-diff-viewtype"}
|
||||
|
||||
- if show_diff_size_warninig?(diffs)
|
||||
= render 'projects/commits/diff_warning', diffs: diffs
|
||||
|
||||
- if show_diff_size_warning?(diffs)
|
||||
= render 'projects/diffs/warning', diffs: diffs
|
||||
|
||||
.files
|
||||
- safe_diff_files(diffs).each_with_index do |diff, i|
|
||||
= render 'projects/commits/diff_file', diff: diff, i: i, project: project
|
||||
- safe_diff_files(diffs).each_with_index do |diff_file, index|
|
||||
= render 'projects/diffs/file', diff_file: diff_file, i: index, project: project
|
||||
|
||||
- if @diff_timeout
|
||||
.alert.alert-danger
|
||||
%h4
|
||||
Failed to collect changes
|
||||
%p
|
||||
Maybe diff is really big and operation failed with timeout. Try to get diff localy
|
||||
Maybe diff is really big and operation failed with timeout. Try to get diff locally
|
|
@ -0,0 +1,48 @@
|
|||
- blob = project.repository.blob_for_diff(@commit, diff_file.diff)
|
||||
- return unless blob
|
||||
- blob_diff_path = diff_project_blob_path(project, tree_join(@commit.id, diff_file.file_path))
|
||||
.diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }}
|
||||
.diff-header{id: "file-path-#{hexdigest(diff_file.new_path || diff_file.old_path)}"}
|
||||
- if diff_file.deleted_file
|
||||
%span= diff_file.old_path
|
||||
|
||||
.diff-btn-group
|
||||
- if @commit.parent_ids.present?
|
||||
= view_file_btn(@commit.parent_id, diff_file, project)
|
||||
- else
|
||||
%span= diff_file.new_path
|
||||
- if diff_file.mode_changed?
|
||||
%span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
|
||||
|
||||
.diff-btn-group
|
||||
- unless params[:view] == 'parallel'
|
||||
%label
|
||||
= check_box_tag nil, 1, false, class: "js-toggle-diff-line-wrap"
|
||||
Wrap text
|
||||
|
||||
= link_to "#", class: "js-toggle-diff-comments btn btn-small" do
|
||||
%i.icon-chevron-down
|
||||
Diff comments
|
||||
|
||||
|
||||
- if @merge_request && @merge_request.source_project
|
||||
= link_to project_edit_tree_path(@merge_request.source_project, tree_join(@merge_request.source_branch, diff_file.new_path), from_merge_request_id: @merge_request.id), { class: 'btn btn-small' } do
|
||||
Edit
|
||||
|
||||
|
||||
= view_file_btn(@commit.id, diff_file, project)
|
||||
|
||||
.diff-content
|
||||
-# Skipp all non non-supported blobs
|
||||
- return unless blob.respond_to?('text?')
|
||||
- if blob.text?
|
||||
- if params[:view] == 'parallel'
|
||||
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i
|
||||
- else
|
||||
= render "projects/diffs/text_file", diff_file: diff_file, index: i
|
||||
- elsif blob.image?
|
||||
- old_file = project.repository.prev_blob_for_diff(@commit, diff_file)
|
||||
= render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i
|
||||
- else
|
||||
.nothing-here-block No preview for this file type
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
- diff = diff_file.diff
|
||||
- if diff.renamed_file || diff.new_file || diff.deleted_file
|
||||
.image
|
||||
%span.wrap
|
|
@ -0,0 +1,4 @@
|
|||
%td.old_line
|
||||
%td.line_content.parallel.matched= line
|
||||
%td.new_line
|
||||
%td.line_content.parallel.matched= line
|
|
@ -0,0 +1,27 @@
|
|||
/ Side-by-side diff view
|
||||
%div.text-file.diff-wrap-lines
|
||||
%table
|
||||
- parallel_diff(diff_file, index).each do |line|
|
||||
- type_left = line[0]
|
||||
- line_number_left = line[1]
|
||||
- line_content_left = line[2]
|
||||
- line_code = line[3]
|
||||
- type_right = line[4]
|
||||
- line_number_right = line[5]
|
||||
- line_content_right = line[6]
|
||||
|
||||
%tr.line_holder.parallel{id: line_code}
|
||||
- if type_left == 'match'
|
||||
= render "projects/diffs/match_line_parallel", { line: line_content_left,
|
||||
line_old: line_number_left, line_new: line_number_right }
|
||||
- elsif type_left == 'old' || type_left.nil?
|
||||
%td.old_line{class: "#{type_left}"}
|
||||
= link_to raw(line_number_left), "##{line_code}", id: line_code
|
||||
%td.line_content{class: "parallel noteable_line #{type_left} #{line_code}", "line_code" => line_code }= raw line_content_left
|
||||
%td.new_line{ class: "#{type_right == 'new' ? 'new' : nil}", data: { linenumber: line_number_right }}
|
||||
= link_to raw(line_number_right), "##{line_code}", id: line_code
|
||||
%td.line_content.parallel{class: "noteable_line #{type_right == 'new' ? 'new' : nil} #{line_code}", "line_code" => line_code}= raw line_content_right
|
||||
|
||||
- if diff_file.diff.diff.blank? && diff_file.mode_changed?
|
||||
.file-mode-changed
|
||||
File mode changed
|
|
@ -1,33 +1,36 @@
|
|||
- too_big = diff.diff.lines.count > Commit::DIFF_SAFE_LINES
|
||||
- too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES
|
||||
- if too_big
|
||||
%a.supp_diff_link Changes suppressed. Click to show
|
||||
|
||||
%table.text-file{class: "#{'hide' if too_big}"}
|
||||
- last_line = 0
|
||||
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
|
||||
- last_line = line_new
|
||||
- diff_file.diff_lines.each_with_index do |line, index|
|
||||
- type = line.type
|
||||
- last_line = line.new_pos
|
||||
- line_code = generate_line_code(diff_file.file_path, line)
|
||||
- line_old = line.old_pos
|
||||
%tr.line_holder{ id: line_code, class: "#{type}" }
|
||||
- if type == "match"
|
||||
= render "projects/commits/diffs/match_line", {line: line,
|
||||
line_old: line_old, line_new: line_new, bottom: false}
|
||||
= render "projects/diffs/match_line", {line: line.text,
|
||||
line_old: line_old, line_new: line.new_pos, bottom: false}
|
||||
- else
|
||||
%td.old_line
|
||||
= link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code
|
||||
- if @comments_allowed
|
||||
= link_to_new_diff_note(line_code)
|
||||
%td.new_line{data: {linenumber: line_new}}
|
||||
= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
|
||||
%td.new_line{data: {linenumber: line.new_pos}}
|
||||
= link_to raw(type == "old" ? " " : line.new_pos) , "##{line_code}", id: line_code
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
|
||||
|
||||
- if @reply_allowed
|
||||
- comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at)
|
||||
- unless comments.empty?
|
||||
= render "projects/notes/diff_notes_with_reply", notes: comments, line: line
|
||||
= render "projects/notes/diff_notes_with_reply", notes: comments, line: line.text
|
||||
|
||||
- if last_line > 0
|
||||
= render "projects/commits/diffs/match_line", {line: "",
|
||||
= render "projects/diffs/match_line", {line: "",
|
||||
line_old: last_line, line_new: last_line, bottom: true}
|
||||
|
||||
- if diff.diff.blank? && diff_file_mode_changed?(diff)
|
||||
- if diff_file.diff.blank? && diff_file.mode_changed?
|
||||
.file-mode-changed
|
||||
File mode changed
|
|
@ -14,6 +14,6 @@
|
|||
= link_to "Email patch", project_merge_request_path(@project, @merge_request, format: :patch), class: "btn btn-warning btn-small"
|
||||
%p
|
||||
To preserve performance only
|
||||
%strong #{safe_diff_files(diffs).size} of #{diffs.size}
|
||||
%strong #{allowed_diff_size} of #{diffs.size}
|
||||
files displayed.
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
%table.text-file
|
||||
- each_diff_line(diff, 1) do |line, type, line_code, line_new, line_old, raw_line|
|
||||
%tr.line_holder{ id: line_code, class: "#{type}" }
|
||||
- if type == "match"
|
||||
%td.old_line= "..."
|
||||
%td.new_line= "..."
|
||||
%td.line_content.matched= line
|
||||
- else
|
||||
%td.old_line
|
||||
= link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code
|
||||
%td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
|
||||
|
|
@ -9,18 +9,17 @@
|
|||
= raw render_markup(@blob.name, @content)
|
||||
- else
|
||||
.file-content.code
|
||||
- unless @diff.empty?
|
||||
- unless @diff_lines.empty?
|
||||
%table.text-file
|
||||
- @diff.each do |line, type, line_code, line_new, line_old, raw_line|
|
||||
%tr.line_holder{ id: line_code, class: "#{type}" }
|
||||
- if type == "match"
|
||||
- @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
|
||||
%td.line_content.matched= line.text
|
||||
- else
|
||||
%td.old_line
|
||||
= link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code
|
||||
%td.new_line= link_to raw(type == "old" ? " " : line_new) , "##{line_code}", id: line_code
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
|
||||
%td.new_line
|
||||
%td.line_content{class: "#{line.type}"}= raw diff_line_content(line.text)
|
||||
- else
|
||||
.nothing-here-block No changes.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
.col-sm-10
|
||||
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
|
||||
.bs-callout.bs-callout-info
|
||||
This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
%br
|
||||
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
|
||||
.form-actions
|
||||
|
|
|
@ -16,37 +16,7 @@
|
|||
- @issue.errors.full_messages.each do |msg|
|
||||
%span= msg
|
||||
%br
|
||||
.form-group
|
||||
= f.label :title, class: 'control-label' do
|
||||
%strong= 'Title *'
|
||||
.col-sm-10
|
||||
= f.text_field :title, maxlength: 255, class: "form-control js-gfm-input", autofocus: true, required: true
|
||||
.form-group
|
||||
= f.label :description, 'Description', class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.text_area :description, class: 'form-control js-gfm-input markdown-area', rows: 14
|
||||
.col-sm-12.hint
|
||||
.pull-left Issues are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.clearfix
|
||||
.error-alert
|
||||
%hr
|
||||
.form-group
|
||||
.issue-assignee
|
||||
= f.label :assignee_id, class: 'control-label' do
|
||||
%i.icon-user
|
||||
Assign to
|
||||
.col-sm-10
|
||||
= project_users_select_tag('issue[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @issue.assignee_id)
|
||||
|
||||
= link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
|
||||
.form-group
|
||||
.issue-milestone
|
||||
= f.label :milestone_id, class: 'control-label' do
|
||||
%i.icon-time
|
||||
Milestone
|
||||
.col-sm-10= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2'})
|
||||
|
||||
= render 'projects/issuable_form', f: f, issuable: @issue
|
||||
.form-group
|
||||
= f.label :label_ids, class: 'control-label' do
|
||||
%i.icon-tag
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
%i.icon.icon-list
|
||||
= form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do
|
||||
.append-right-10.hidden-xs.hidden-sm
|
||||
= search_field_tag :issue_search, nil, { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
|
||||
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
|
||||
= hidden_field_tag :state, params['state']
|
||||
= hidden_field_tag :scope, params['scope']
|
||||
= hidden_field_tag :assignee_id, params['assignee_id']
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
- if @project.labels.size == 0
|
||||
$('.labels').load(document.URL + ' .light-well').hide().fadeIn(1000)
|
|
@ -7,11 +7,11 @@
|
|||
Labels
|
||||
%hr
|
||||
|
||||
- if @labels.present?
|
||||
%ul.bordered-list.manage-labels-list
|
||||
= render @labels
|
||||
= paginate @labels, theme: 'gitlab'
|
||||
|
||||
- else
|
||||
.light-well
|
||||
.nothing-here-block Create first label or #{link_to 'generate', generate_project_labels_path(@project), method: :post} default set of labels
|
||||
.labels
|
||||
- if @labels.present?
|
||||
%ul.bordered-list.manage-labels-list
|
||||
= render @labels
|
||||
= paginate @labels, theme: 'gitlab'
|
||||
- else
|
||||
.light-well
|
||||
.nothing-here-block Create first label or #{link_to 'generate', generate_project_labels_path(@project), method: :post} default set of labels
|
||||
|
|
|
@ -15,37 +15,7 @@
|
|||
%div= msg
|
||||
|
||||
.merge-request-form-info
|
||||
.form-group
|
||||
= f.label :title, class: 'control-label' do
|
||||
%strong= "Title *"
|
||||
.col-sm-10= f.text_field :title, class: "form-control pad js-gfm-input", maxlength: 255, rows: 5, required: true
|
||||
.form-group
|
||||
= f.label :description, "Description", class: 'control-label'
|
||||
.col-sm-10
|
||||
= f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 14
|
||||
.col-sm-12.hint
|
||||
.pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.clearfix
|
||||
.error-alert
|
||||
%hr
|
||||
.form-group
|
||||
.issue-assignee
|
||||
= f.label :assignee_id, class: 'control-label' do
|
||||
%i.icon-user
|
||||
Assign to
|
||||
.col-sm-10
|
||||
= project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id)
|
||||
|
||||
= link_to 'Assign to me', '#', class: 'btn assign-to-me-link'
|
||||
.form-group
|
||||
.issue-milestone
|
||||
= f.label :milestone_id, class: 'control-label' do
|
||||
%i.icon-time
|
||||
Milestone
|
||||
.col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
|
||||
|
||||
|
||||
= render 'projects/issuable_form', f: f, issuable: @merge_request
|
||||
.form-group
|
||||
= f.label :label_ids, class: 'control-label' do
|
||||
%i.icon-tag
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
|
||||
%h4 Changes
|
||||
- if @diffs.present?
|
||||
= render "projects/commits/diffs", diffs: @diffs, project: @project
|
||||
= render "projects/diffs/diffs", diffs: @diffs, project: @project
|
||||
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
|
||||
.bs-callout.bs-callout-danger
|
||||
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- if @merge_request_diff.collected?
|
||||
= render "projects/commits/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
|
||||
= render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
|
||||
- elsif @merge_request_diff.empty?
|
||||
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
|
||||
- else
|
||||
|
|
|
@ -48,9 +48,9 @@
|
|||
.col-sm-10
|
||||
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
|
||||
.bs-callout.bs-callout-info
|
||||
This url must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
|
||||
%br
|
||||
The import will time out after 2 minutes. For big repositories, use a clone/push combination.
|
||||
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
|
||||
%hr
|
||||
|
||||
.form-group
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
- note = @project.notes.new(@comments_target.merge({ line_code: line_code }))
|
||||
= link_to "",
|
||||
"javascript:;",
|
||||
class: "add-diff-note js-add-diff-note-button",
|
||||
data: { noteable_type: note.noteable_type,
|
||||
noteable_id: note.noteable_id,
|
||||
commit_id: note.commit_id,
|
||||
line_code: note.line_code,
|
||||
discussion_id: note.discussion_id },
|
||||
title: "Add a comment to this line"
|
|
@ -11,16 +11,17 @@
|
|||
%br/
|
||||
.diff-content
|
||||
%table
|
||||
- each_diff_line_near(diff, note.diff_file_index, note.line_code) do |line, type, line_code, line_new, line_old|
|
||||
- note.truncated_diff_lines.each do |line|
|
||||
- line_code = generate_line_code(note.file_path, line)
|
||||
%tr.line_holder{ id: line_code }
|
||||
- if type == "match"
|
||||
- if line.type == "match"
|
||||
%td.old_line= "..."
|
||||
%td.new_line= "..."
|
||||
%td.line_content.matched= line
|
||||
%td.line_content.matched= line.text
|
||||
- else
|
||||
%td.old_line= raw(type == "new" ? " " : line_old)
|
||||
%td.new_line= raw(type == "old" ? " " : line_new)
|
||||
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} "
|
||||
%td.old_line= raw(line.type == "new" ? " " : line.old_pos)
|
||||
%td.new_line= raw(line.type == "old" ? " " : line.new_pos)
|
||||
%td.line_content{class: "noteable_line #{line.type} #{line_code}", "line_code" => line_code}= raw "#{line.text} "
|
||||
|
||||
- if line_code == note.line_code
|
||||
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
- if @error
|
||||
.alert.alert-danger
|
||||
%button{ type: "button", class: "close", "data-dismiss" => "alert"} ×
|
||||
= @error
|
||||
%h3.page-title
|
||||
%i.icon-code-fork
|
||||
New tag
|
||||
|
@ -5,12 +9,17 @@
|
|||
.form-group
|
||||
= label_tag :tag_name, 'Name for new tag', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :tag_name, nil, placeholder: 'v3.0.1', required: true, tabindex: 1, class: 'form-control'
|
||||
= text_field_tag :tag_name, params[:tag_name], placeholder: 'v3.0.1', required: true, tabindex: 1, class: 'form-control'
|
||||
.form-group
|
||||
= label_tag :ref, 'Create from', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2, class: 'form-control'
|
||||
= text_field_tag :ref, params[:ref], placeholder: 'master', required: true, tabindex: 2, class: 'form-control'
|
||||
.light Branch name or commit SHA
|
||||
.form-group
|
||||
= label_tag :message, 'Message', class: 'control-label'
|
||||
.col-sm-10
|
||||
= text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control'
|
||||
.light (Optional) Entering a message will create an annotated tag.
|
||||
.form-actions
|
||||
= submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3
|
||||
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
|
||||
|
|
|
@ -23,3 +23,9 @@
|
|||
Comments
|
||||
.pull-right
|
||||
= @search_results.notes_count
|
||||
%li{class: ("active" if @scope == 'wiki_blobs')}
|
||||
= link_to search_filter_path(scope: 'wiki_blobs') do
|
||||
Wiki
|
||||
.pull-right
|
||||
= @search_results.wiki_blobs_count
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
%h4
|
||||
#{@search_results.total_count} results found
|
||||
- if @project
|
||||
for #{link_to @project.name_with_namespace, @project}
|
||||
- elsif @group
|
||||
for #{link_to @group.name, @group}
|
||||
- unless @show_snippets
|
||||
- if @project
|
||||
for #{link_to @project.name_with_namespace, @project}
|
||||
- elsif @group
|
||||
for #{link_to @group.name, @group}
|
||||
|
||||
%hr
|
||||
|
||||
|
@ -11,6 +12,8 @@
|
|||
.col-sm-3
|
||||
- if @project
|
||||
= render "project_filter"
|
||||
- elsif @show_snippets
|
||||
= render 'snippet_filter'
|
||||
- else
|
||||
= render "global_filter"
|
||||
.col-sm-9
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
%ul.nav.nav-pills.nav-stacked.search-filter
|
||||
%li{class: ("active" if @scope == 'snippet_blobs')}
|
||||
= link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do
|
||||
%i.icon-code
|
||||
Snippet Contents
|
||||
.pull-right
|
||||
= @search_results.snippet_blobs_count
|
||||
%li{class: ("active" if @scope == 'snippet_titles')}
|
||||
= link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do
|
||||
%i.icon-book
|
||||
Titles and Filenames
|
||||
.pull-right
|
||||
= @search_results.snippet_titles_count
|
|
@ -0,0 +1,65 @@
|
|||
.search-result-row
|
||||
%span
|
||||
= snippet_blob[:snippet_object].title
|
||||
by
|
||||
= link_to user_snippets_path(snippet_blob[:snippet_object].author) do
|
||||
= image_tag avatar_icon(snippet_blob[:snippet_object].author_email), class: "avatar avatar-inline s16", alt: ''
|
||||
= snippet_blob[:snippet_object].author_name
|
||||
%span.light #{time_ago_with_tooltip(snippet_blob[:snippet_object].created_at)}
|
||||
%h4.snippet-title
|
||||
- snippet_path = reliable_snippet_path(snippet_blob[:snippet_object])
|
||||
= link_to snippet_path do
|
||||
.file-holder
|
||||
.file-title
|
||||
%i.icon-file
|
||||
%strong= snippet_blob[:snippet_object].file_name
|
||||
%span.options
|
||||
.btn-group.tree-btn-group.pull-right
|
||||
- if snippet_blob[:snippet_object].author == current_user
|
||||
= link_to "Edit", edit_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", title: 'Edit Snippet'
|
||||
= link_to "Delete", snippet_path(snippet_blob[:snippet_object]), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-tiny", title: 'Delete Snippet'
|
||||
= link_to "Raw", raw_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", target: "_blank"
|
||||
- if gitlab_markdown?(snippet_blob[:snippet_object].file_name)
|
||||
.file-content.wiki
|
||||
- snippet_blob[:snippet_chunks].each do |snippet|
|
||||
- unless snippet[:data].empty?
|
||||
= preserve do
|
||||
= markdown(snippet[:data])
|
||||
- else
|
||||
.file-content.code
|
||||
.nothing-here-block Empty file
|
||||
- elsif markup?(snippet_blob[:snippet_object].file_name)
|
||||
.file-content.wiki
|
||||
- snippet_blob[:snippet_chunks].each do |snippet|
|
||||
- unless snippet[:data].empty?
|
||||
= render_markup(snippet_blob[:snippet_object].file_name, snippet[:data])
|
||||
- else
|
||||
.file-content.code
|
||||
.nothing-here-block Empty file
|
||||
- else
|
||||
.file-content.code
|
||||
%div.highlighted-data{class: user_color_scheme_class}
|
||||
.line-numbers
|
||||
- snippet_blob[:snippet_chunks].each do |snippet|
|
||||
- unless snippet[:data].empty?
|
||||
- snippet[:data].lines.to_a.size.times do |index|
|
||||
- offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
|
||||
- i = index + offset
|
||||
= link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do
|
||||
%i.icon-link
|
||||
= i
|
||||
- unless snippet == snippet_blob[:snippet_chunks].last
|
||||
%a
|
||||
= "."
|
||||
.highlight.term
|
||||
%pre
|
||||
%code
|
||||
- snippet_blob[:snippet_chunks].each do |snippet|
|
||||
- unless snippet[:data].empty?
|
||||
= snippet[:data]
|
||||
- unless snippet == snippet_blob[:snippet_chunks].last
|
||||
%a
|
||||
= "..."
|
||||
- else
|
||||
.file-content.code
|
||||
.nothing-here-block Empty file
|
|
@ -0,0 +1,23 @@
|
|||
.search-result-row
|
||||
%h4.snippet-title.term
|
||||
= link_to reliable_snippet_path(snippet_title) do
|
||||
= truncate(snippet_title.title, length: 60)
|
||||
- if snippet_title.private?
|
||||
%span.label.label-gray
|
||||
%i.icon-lock
|
||||
private
|
||||
%span.cgray.monospace.tiny.pull-right.term
|
||||
= snippet_title.file_name
|
||||
|
||||
%small.pull-right.cgray
|
||||
- if snippet_title.project_id?
|
||||
= link_to snippet_title.project.name_with_namespace, project_path(snippet_title.project)
|
||||
|
||||
.snippet-info
|
||||
= "##{snippet_title.id}"
|
||||
%span
|
||||
by
|
||||
= link_to user_snippets_path(snippet_title.author) do
|
||||
= image_tag avatar_icon(snippet_title.author_email), class: "avatar avatar-inline s16", alt: ''
|
||||
= snippet_title.author_name
|
||||
%span.light #{time_ago_with_tooltip(snippet_title.created_at)}
|
|
@ -0,0 +1,9 @@
|
|||
.blob-result
|
||||
.file-holder
|
||||
.file-title
|
||||
= link_to project_wiki_path(@project, wiki_blob.filename) do
|
||||
%i.icon-file
|
||||
%strong
|
||||
= wiki_blob.filename
|
||||
.file-content.code.term
|
||||
= render 'shared/file_hljs', blob: wiki_blob, first_line_number: wiki_blob.startline
|
|
@ -9,10 +9,12 @@
|
|||
= submit_tag 'Search', class: "btn btn-create"
|
||||
.form-group
|
||||
.col-sm-2
|
||||
.col-sm-10
|
||||
= render 'filter', f: f
|
||||
- unless params[:snippets].eql? 'true'
|
||||
.col-sm-10
|
||||
= render 'filter', f: f
|
||||
= hidden_field_tag :project_id, params[:project_id]
|
||||
= hidden_field_tag :group_id, params[:group_id]
|
||||
= hidden_field_tag :snippets, params[:snippets]
|
||||
= hidden_field_tag :scope, params[:scope]
|
||||
|
||||
.results.prepend-top-10
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
cd $(dirname $0)/..
|
||||
app_root=$(pwd)
|
||||
|
@ -6,22 +6,22 @@ sidekiq_pidfile="$app_root/tmp/pids/sidekiq.pid"
|
|||
sidekiq_logfile="$app_root/log/sidekiq.log"
|
||||
gitlab_user=$(ls -l config.ru | awk '{print $3}')
|
||||
|
||||
function warn
|
||||
warn()
|
||||
{
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
function stop
|
||||
stop()
|
||||
{
|
||||
bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1
|
||||
}
|
||||
|
||||
function killall
|
||||
killall()
|
||||
{
|
||||
pkill -u $gitlab_user -f 'sidekiq [0-9]'
|
||||
}
|
||||
|
||||
function restart
|
||||
restart()
|
||||
{
|
||||
if [ -f $sidekiq_pidfile ]; then
|
||||
stop
|
||||
|
@ -30,20 +30,20 @@ function restart
|
|||
start_sidekiq -d -L $sidekiq_logfile
|
||||
}
|
||||
|
||||
function start_no_deamonize
|
||||
start_no_deamonize()
|
||||
{
|
||||
start_sidekiq
|
||||
}
|
||||
|
||||
function start_sidekiq
|
||||
start_sidekiq()
|
||||
{
|
||||
bundle exec sidekiq -q post_receive -q mailer -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1
|
||||
}
|
||||
|
||||
function load_ok
|
||||
load_ok()
|
||||
{
|
||||
sidekiq_pid=$(cat $sidekiq_pidfile)
|
||||
if [[ -z $sidekiq_pid ]] ; then
|
||||
if [ -z "$sidekiq_pid" ] ; then
|
||||
warn "Could not find a PID in $sidekiq_pidfile"
|
||||
exit 0
|
||||
fi
|
||||
|
|
12
bin/web
12
bin/web
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
cd $(dirname $0)/..
|
||||
app_root=$(pwd)
|
||||
|
@ -6,28 +6,28 @@ app_root=$(pwd)
|
|||
unicorn_pidfile="$app_root/tmp/pids/unicorn.pid"
|
||||
unicorn_config="$app_root/config/unicorn.rb"
|
||||
|
||||
function get_unicorn_pid
|
||||
get_unicorn_pid()
|
||||
{
|
||||
local pid=$(cat $unicorn_pidfile)
|
||||
if [ -z $pid ] ; then
|
||||
if [ -z "$pid" ] ; then
|
||||
echo "Could not find a PID in $unicorn_pidfile"
|
||||
exit 1
|
||||
fi
|
||||
unicorn_pid=$pid
|
||||
}
|
||||
|
||||
function start
|
||||
start()
|
||||
{
|
||||
bundle exec unicorn_rails -D -c $unicorn_config -E $RAILS_ENV
|
||||
}
|
||||
|
||||
function stop
|
||||
stop()
|
||||
{
|
||||
get_unicorn_pid
|
||||
kill -QUIT $unicorn_pid
|
||||
}
|
||||
|
||||
function reload
|
||||
reload()
|
||||
{
|
||||
get_unicorn_pid
|
||||
kill -USR2 $unicorn_pid
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
# # # # # # # # # # # # # # # # # #
|
||||
#
|
||||
# How to use:
|
||||
# 1. copy file as gitlab.yml
|
||||
# 2. Replace gitlab -> host with your domain
|
||||
# 3. Replace gitlab -> email_from
|
||||
# 1. Copy file as gitlab.yml
|
||||
# 2. Update gitlab -> host with your fully qualified domain name
|
||||
# 3. Update gitlab -> email_from
|
||||
# 4. If you installed Git from source, change git -> bin_path to /usr/local/bin/git
|
||||
# 5. Review this configuration file for other settings you may want to adjust
|
||||
|
||||
production: &base
|
||||
#
|
||||
|
@ -16,8 +18,8 @@ production: &base
|
|||
gitlab:
|
||||
## Web server settings (note: host is the FQDN, do not include http://)
|
||||
host: localhost
|
||||
port: 80
|
||||
https: false
|
||||
port: 80 # Set to 443 if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
|
||||
https: false # Set to true if using HTTPS, see installation.md#using-https for additional HTTPS configuration details
|
||||
|
||||
# Uncommment this line below if your ssh host is different from HTTP/HTTPS one
|
||||
# (you'd obviously need to replace ssh.host_example.com with your own host).
|
||||
|
|
|
@ -4,10 +4,10 @@ Sidekiq::Testing.inline! do
|
|||
Gitlab::Seeder.quiet do
|
||||
project_urls = [
|
||||
'https://github.com/documentcloud/underscore.git',
|
||||
'https://github.com/gitlabhq/gitlabhq.git',
|
||||
'https://github.com/gitlabhq/gitlab-ci.git',
|
||||
'https://github.com/gitlabhq/gitlab-shell.git',
|
||||
'https://github.com/gitlabhq/testme.git',
|
||||
'https://gitlab.com/gitlab-org/gitlab-ce.git',
|
||||
'https://gitlab.com/gitlab-org/gitlab-ci.git',
|
||||
'https://gitlab.com/gitlab-org/gitlab-shell.git',
|
||||
'https://gitlab.com/gitlab-org/testme.git',
|
||||
'https://github.com/twitter/flight.git',
|
||||
'https://github.com/twitter/typeahead.js.git',
|
||||
'https://github.com/h5bp/html5-boilerplate.git',
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
password = if ENV['GITLAB_ROOT_PASSWORD'].nil? || ENV['GITLAB_ROOT_PASSWORD'].empty?
|
||||
"5iveL!fe"
|
||||
else
|
||||
ENV['GITLAB_ROOT_PASSWORD']
|
||||
end
|
||||
|
||||
admin = User.create(
|
||||
email: "admin@example.com",
|
||||
name: "Administrator",
|
||||
username: 'root',
|
||||
password: "5iveL!fe",
|
||||
password_confirmation: "5iveL!fe",
|
||||
password: password,
|
||||
password_confirmation: password,
|
||||
password_expires_at: Time.now,
|
||||
theme_id: Gitlab::Theme::MARS
|
||||
|
||||
|
@ -19,6 +25,6 @@ puts %q[
|
|||
Administrator account created:
|
||||
|
||||
login.........root
|
||||
password......5iveL!fe
|
||||
password......#{password}
|
||||
]
|
||||
end
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
class MigrateToNewShell < ActiveRecord::Migration
|
||||
def change
|
||||
gitlab_shell_path = Gitlab.config.gitlab_shell.path
|
||||
if system("#{gitlab_shell_path}/bin/create-hooks")
|
||||
puts 'Repositories updated with new hooks'
|
||||
else
|
||||
raise 'Failed to rewrite gitlab-shell hooks in repositories'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
class SerializeServiceProperties < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :services, :properties, :text
|
||||
|
||||
associations =
|
||||
{
|
||||
AssemblaService: [:token, :subdomain],
|
||||
CampfireService: [:token, :subdomain, :room],
|
||||
EmailsOnPushService: [:recipients],
|
||||
FlowdockService: [:token],
|
||||
GemnasiumService: [:api_key, :token],
|
||||
GitlabCiService: [:token, :project_url],
|
||||
HipchatService: [:token, :room],
|
||||
PivotaltrackerService: [:token],
|
||||
SlackService: [:subdomain, :token, :room],
|
||||
JenkinsService: [:token, :subdomain],
|
||||
JiraService: [:project_url, :username, :password,
|
||||
:api_version, :jira_issue_transition_id],
|
||||
}
|
||||
|
||||
Service.all.each do |service|
|
||||
associations[service.type.to_sym].each do |attribute|
|
||||
service.send("#{attribute}=", service.attributes[attribute.to_s])
|
||||
end
|
||||
service.save!
|
||||
end
|
||||
|
||||
remove_column :services, :project_url, :string
|
||||
remove_column :services, :subdomain, :string
|
||||
remove_column :services, :room, :string
|
||||
remove_column :services, :recipients, :text
|
||||
remove_column :services, :api_key, :string
|
||||
remove_column :services, :token, :string
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue