Commit 3f559cc9 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq

Conflicts:
	app/views/help/index.html.haml
parents e34eac08 d3c429ed
......@@ -16,6 +16,8 @@ v 6.0.0
- Generate fingerprint for ssh keys
- You an use arrows to navigate at tree view
- Apply user project limit only for personal projects
- API: Allow login with LDAP credentials
- Ability to remove branches/tags with UI
v 5.4.0
- Ability to edit own comments
......@@ -24,8 +26,13 @@ v 5.4.0
- Fixed nav for empty repos
- GitLab Markdown help page
- Misspelling fixes
- Added suppoort of unicorn and fog gems
- Added support of unicorn and fog gems
- Added client list to API doc
- Fix PostgreSQL database restoration problem
- Increase snippet content column size
- allow project import via git:// url
- Show participants on issues, including mentions
- Notify mentioned users with email
v 5.3.0
- Refactored services
......
......@@ -137,7 +137,7 @@ group :assets do
gem "modernizr", "2.6.2"
gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
gem 'bootstrap-sass'
gem "font-awesome-rails", "~> 3.1.1"
gem "font-awesome-rails"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
gem "gon"
end
......
......@@ -143,7 +143,7 @@ GEM
net-ssh (>= 2.1.3)
nokogiri (~> 1.5.0)
ruby-hmac
font-awesome-rails (3.1.1.3)
font-awesome-rails (3.2.1.2)
railties (>= 3.2, < 5.0)
foreman (0.63.0)
dotenv (>= 0.7)
......@@ -560,7 +560,7 @@ DEPENDENCIES
factory_girl_rails
ffaker
fog (~> 1.3.1)
font-awesome-rails (~> 3.1.1)
font-awesome-rails
foreman
gemoji (~> 1.2.1)
github-linguist
......
......@@ -14,7 +14,7 @@ class Admin
$('.log-bottom').click (e) ->
e.preventDefault()
visible_log = $(".file_content:visible")
visible_log = $(".file-content:visible")
visible_log.animate({ scrollTop: visible_log.find('ol').height() }, "fast")
modal = $('.change-owner-holder')
......
......@@ -50,5 +50,5 @@
callback(users)
buildUrl: (url) ->
url = gon.relative_url_root + url if gon.relative_url_root.present?
url = gon.relative_url_root + url if gon.relative_url_root?
return url.replace(':version', gon.api_version)
......@@ -15,7 +15,7 @@ class Dashboard
uiBox.find(".dash-list li").show()
else
uiBox.find(".dash-list li").each (index) ->
name = $(this).find(".well-title").text()
name = $(this).find(".filter-title").text()
if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide()
......
......@@ -30,7 +30,7 @@ class Dispatcher
new Wall(project_id)
when 'projects:teams:members:index'
new TeamMembers()
when 'groups:people'
when 'groups:members'
new GroupMembers()
when 'projects:tree:show'
new TreeView()
......
......@@ -62,6 +62,9 @@ $ ->
# Click a .one_click_select field, select the contents
$(".one_click_select").on 'click', -> $(@).select()
$('.remove-row').bind 'ajax:success', ->
$(this).closest('li').fadeOut()
# Click a .appear-link, appear-data fadeout
$(".appear-link").on 'click', (e) ->
$('.appear-data').fadeIn()
......
class Network
constructor: (opts) ->
$("#filter_ref").click ->
$(this).closest('form').submit()
branch_graph = new BranchGraph($(".network-graph"), opts)
vph = $(window).height() - 250
$('.network-graph').css 'height': (vph + 'px')
@Network = Network
......@@ -23,6 +23,12 @@ var NoteList = {
$(document).off("click", ".js-note-attachment-input");
$(document).off("click", ".js-close-discussion-note-form");
$(document).off("click", ".js-note-delete");
$(document).off("click", ".js-note-edit");
$(document).off("click", ".js-note-edit-cancel");
$(document).off("click", ".js-note-attachment-delete");
$(document).off("click", ".js-choose-note-attachment-button");
$(document).off("click", ".js-show-outdated-discussion");
$(document).off("ajax:complete", ".js-main-target-form");
......
......@@ -46,7 +46,11 @@ class window.ContributorsGraph
class window.ContributorsMasterGraph extends ContributorsGraph
constructor: (@data) ->
@width = 1100
if $(window).width() > 1214
@width = 1100
else
@width = 870
@height = 125
@x = null
@y = null
......@@ -118,7 +122,11 @@ class window.ContributorsMasterGraph extends ContributorsGraph
class window.ContributorsAuthorGraph extends ContributorsGraph
constructor: (@data) ->
@width = 490
if $(window).width() > 1214
@width = 490
else
@width = 380
@height = 130
@x = null
@y = null
......
......@@ -23,12 +23,8 @@ body {
.help li { color:$style_color; }
.back_link {
text-decoration: underline;
.back-link {
font-size: 14px;
font-weight: bold;
padding: 10px 0;
padding-bottom: 0;
}
table a code {
......@@ -146,23 +142,6 @@ input[type=text] {
}
}
li.commit {
.avatar {
width: 24px;
top:-5px;
margin-right: 10px;
margin-left: 10px;
}
code {
padding: 2px 2px 0;
margin-top: -2px;
&:hover {
color: black;
border: 1px solid #ccc;
}
}
}
p.time {
color: #999;
font-size: 90%;
......@@ -412,7 +391,7 @@ img.emoji {
}
.navless-container {
margin-top: 30px;
margin-top: 20px;
}
.description-block {
......@@ -420,3 +399,8 @@ img.emoji {
@extend .light;
margin-bottom: 10px;
}
.group-name {
font-size: 14px;
line-height: 24px;
}
......@@ -17,9 +17,6 @@
&.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; }
&.s32 { width: 32px; height: 32px; margin-right: 10px; }
&.s60 { width: 60px; height: 60px; margin-right: 12px; }
&.s90 { width: 90px; height: 90px; margin-right: 15px; }
}
img.lil_av { padding-left: 4px; padding-right: 3px; }
img.small { width: 80px; }
......@@ -11,7 +11,7 @@
*/
.ui-box {
background: #F9F9F9;
margin-bottom: 25px;
margin-bottom: 20px;
border: 1px solid #CCC;
word-wrap: break-word;
@include solid-shade;
......@@ -62,7 +62,6 @@
.ui-box-body {
border: none;
font-size: 12px;
background-color: #f5f5f5;
border: none;
border-top: 1px solid #eee;
......@@ -86,10 +85,11 @@
color: #456;
font-size: 16px;
text-shadow: 0 1px 1px #fff;
padding: 0px 10px;
line-height: 36px;
padding: 0 10px;
font-size: 14px;
line-height: 40px;
font-weight: normal;
margin: 0;
> a {
text-shadow: 0 1px 1px #fff;
......@@ -101,8 +101,7 @@
}
.btn {
position: relative;
top: -2px;
vertical-align: middle;
}
.nav-pills {
......@@ -132,15 +131,6 @@
margin-bottom: 0;
padding: 5px 20px;
}
.middle_title {
background: #f5f5f5;
margin:20px -20px;
padding: 0 20px;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
font-size: 14px;
color: #777;
}
}
.row_title {
......
......@@ -43,11 +43,8 @@
}
}
&.success {
@extend .btn-success;
&.btn-success {
&:hover {
@extend .btn-success;
background: #51a351;
}
......@@ -59,7 +56,7 @@
&.btn-create {
@extend .wide;
@extend .success;
@extend .btn-success;
}
&.btn-save {
......
......@@ -68,10 +68,6 @@ input[type='text'].danger {
fieldset legend { font-size: 17px; }
/** PAGINATION **/
.gitlab_pagination {
}
.tab-content {
overflow: visible;
}
......
......@@ -2,12 +2,12 @@
* File content holder
*
*/
.file_holder {
.file-holder {
border: 1px solid #BBB;
margin-bottom: 1em;
@include solid-shade;
.file_title {
.file-title {
border-bottom: 1px solid #bbb;
@include bg-dark-gray-gradient;
margin: 0;
......@@ -33,7 +33,7 @@
}
}
}
.file_content {
.file-content {
background: #fff;
font-size: 11px;
......@@ -48,7 +48,8 @@
&.wiki {
padding: 20px;
font-size: 13px;
font-size: 14px;
line-height: 1.6;
.highlight {
margin-bottom: 9px;
......
......@@ -75,7 +75,6 @@ ul.bordered-list {
display: block;
margin: 0px;
&:last-child { border:none }
&.active {
background: #f9f9f9;
a { font-weight: bold; }
......
......@@ -70,19 +70,24 @@
@mixin header-font {
color: $style_color;
text-shadow: 0 1px 1px #FFF;
font-size: 18px;
font-size: 16px;
line-height: 40px;
font-weight: normal;
letter-spacing: -1px;
}
@mixin md-typography {
code { padding: 0 4px; }
p { font-size: 13px; }
h1 { font-size: 26px; line-height: 40px; margin: 10px 0;}
h2 { font-size: 22px; line-height: 40px; margin: 10px 0;}
h3 { font-size: 18px; line-height: 40px; margin: 10px 0;}
h4 { font-size: 16px; line-height: 20px; margin: 10px 0;}
h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
h1 { margin-top: 30px;}
h2 { margin-top: 25px;}
h3 { margin-top: 20px;}
h4 { margin-top: 15px;}
}
@mixin page-title {
color: $style_color;
font-size: 20px;
font-weight: normal;
line-height: 1.5;
margin-top: 0px;
margin-bottom: 15px;
}
......@@ -3,15 +3,18 @@
*
*/
h1, h2, h3, h4, h5, h6 { margin: 0; }
h3, h4, h5, h6 { line-height: 36px; }
h5 { font-size: 14px; }
h3.page_title {
color: #456;
font-size: 20px;
font-weight: normal;
line-height: 28px;
h1.page-title {
@include page-title;
font-size: 28px;
}
h2.page-title {
@include page-title;
font-size: 24px;
}
h3.page-title {
@include page-title;
}
h6 {
......@@ -91,11 +94,10 @@ a:focus {
*
*/
.wiki {
font-size: 14px;
line-height: 1.6;
@include md-typography;
font-size: 13px;
line-height: 20px;
.white .highlight pre { background: #f5f5f5; }
ul { margin: 0 0 9px 25px !important; }
}
......
......@@ -437,3 +437,30 @@
border: none;
margin: 0;
}
.ui-box.commit-box {
margin-top: 0;
}
.commit-stat-summary {
color: #666;
line-height: 2;
}
li.commit {
.avatar {
width: 24px;
top:-5px;
margin-right: 5px;
margin-left: 10px;
}
code {
padding: 2px 2px 0;
margin-top: -2px;
&:hover {
color: black;
border: 1px solid #ccc;
}
}
}
......@@ -10,9 +10,6 @@
margin: 0px;
box-shadow: none;
> .title {
padding: 2px 15px;
}
.nav-projects-tabs li { padding: 0; }
}
}
......@@ -33,12 +30,10 @@
.dashboard {
.dash-filter {
margin: 0;
margin: 7px 0;
padding: 4px 6px;
width: 202px;
float: left;
margin-top: 3px;
margin-left: -2px;
}
}
......@@ -71,7 +66,7 @@
}
.project-row, .group-row {
padding: 15px !important;
padding: 12px 15px !important;
.namespace-name {
color: #666;
......
......@@ -31,6 +31,10 @@
*
*/
.event-item {
&:first-child {
padding-top: 0;
}
border-bottom: 1px solid #eee;
.event-title {
color: #333;
......@@ -99,7 +103,7 @@
}
}
padding: 16px 5px;
padding: 14px 0px;
&:last-child { border:none }
.event_commits {
......@@ -125,30 +129,6 @@
}
}
/**
* Push event widget
*
*/
.event_lp {
color: #777;
padding: 10px;
min-height: 22px;
border-left: 5px solid $primary_color;
margin-bottom: 20px;
background: #f9f9f9;
.avatar {
width: 24px;
}
.btn-new-mr {
@extend .btn-primary;
@extend .small;
@extend .pull-right;
margin: -2px;
}
}
/**
* Event filter
*
......
.graph_holder {
.project-network {
border: 1px solid #aaa;
padding: 1px;
h4 {
padding: 0 10px;
.tip {
color: #888;
font-size: 14px;
padding: 10px;
border-bottom: 1px solid #bbb;
@include bg-gray-gradient;
}
.graph {
.network-graph {
background: #f1f1f1;
height: 500px;
overflow-y: scroll;
......
......@@ -13,7 +13,7 @@ header {
.nav > li > a {
color: $style_color;
text-shadow: 0 1px 0 #fff;
font-size: 16px;
font-size: 14px;
padding: 10px;
}
......@@ -45,6 +45,7 @@ header {
margin: 0 6px;
h1 {
margin: 0;
background: url('logo-black.png') no-repeat center 1px;
background-size: 38px;
float: left;
......@@ -68,7 +69,7 @@ header {
position: relative;
float: left;
margin: 0;
margin-left: 10px;
margin-left: 5px;
@include header-font;
}
......@@ -92,7 +93,7 @@ header {
margin-left: 10px;
.search-input {
@extend .span2;
@extend .span3;
background-image: url("icon-search.png");
background-repeat: no-repeat;
background-position: 10px;
......@@ -103,7 +104,7 @@ header {
box-shadow: none;
@include transition(all 0.15s ease-in 0s);
&:focus {
@extend .span3;
@extend .span4;
}
}
}
......@@ -160,7 +161,7 @@ header {
}
.project_name {
a {
color: #DDD;
color: #BBB;
&:hover {
color: #FFF;
}
......
......@@ -82,10 +82,6 @@
}
}
.mr_direction_tip {
margin-top:40px
}
.label-branch {
@include border-radius(4px);
padding: 2px 4px;
......@@ -113,3 +109,12 @@
}
}
}
.merge-request-angle {
text-align: center;
margin-top: 45px;
}
.merge-request-form-info {
padding: 15px 0;
}
.main-nav {
background: #f5f5f5;
margin: 30px 0;
margin: 20px 0;
margin-top: 0;
padding-top: 4px;
border-bottom: 1px solid #E1E1E1;
ul {
margin: auto;
height: 40px;
height: 42px;
overflow: hidden;
.count {
font-weight: normal;
......@@ -74,7 +74,7 @@
text-align: center;
font-weight: normal;
height: 38px;
line-height: 34px;
line-height: 36px;
color: #777;
text-shadow: 0 1px 1px white;
padding: 0 10px;
......
.profile_history {
.event_feed {
min-height: 20px;
.avatar {
width: 20px;
}
}
}
.profile_avatar_holder {
float: left;
width: 60px;
height: 60px;
margin-right: 20px;
img {
width: 60px;
height: 60px;
background: #fff;
padding: 1px;
border: 1px solid #ddd;
}
}
.save-status-fixed {
position: fixed;
left: 20px;
......
......@@ -48,7 +48,7 @@
margin-bottom: 50px;
}
h3 {
@extend .page_title;
@extend .page-title;
}
}
......@@ -86,8 +86,13 @@ ul.nav.nav-projects-tabs {
border-bottom: 1px solid #eee;
.description {
margin-left: 22px;
margin-left: 15px;
color: #aaa;
}
}
}
.new-tag-btn {
position: relative;
top: -5px;
}
.snippet.file_holder {
.file_title {
.snippet.file-holder {
.file-title {
.snippet-file-name {
position: relative;
top: -4px;
......@@ -7,3 +7,9 @@
}
}
}
.my-snippets li:first-child {
h4 { margin-top: 0; }
padding-top: 0;
}
......@@ -14,27 +14,29 @@
font-size: 10px;
}
#contributors .person {
&:nth-child(even) {
float: right;
#contributors {
.contributors-list {
margin: 0 0 10px 0;
list-style: none;
padding: 0;
}
float: left;
margin-top: 10px;
}
.contributors-list {
margin: 0 0 10px 0;
list-style: none;
padding: 0;
}
.person {
&:nth-child(even) {
float: right;
}
float: left;
margin-top: 10px;
}
#contributors .person .spark {
display: block;
background: #f3f3f3;
}
.person .spark {
display: block;
background: #f3f3f3;
}
#contributors .person .area-contributor {
fill: #f17f49;
.person .area-contributor {
fill: #f17f49;
}
}
.selection rect {
......
......@@ -27,7 +27,7 @@
}
}
.votes-block {
margin: 14px 6px 6px 0;
margin: 6px;
.downvotes {
float: right;
}
......
h3.page_title .edit-wiki-header {
h3.page-title .edit-wiki-header {
width: 780px;
margin-left: auto;
margin-right: auto;
......
......@@ -31,4 +31,8 @@
border-left: 1px solid #666;
}
}
.main-nav {
box-shadow: 0 -1px 0 white inset;
}
}
......@@ -91,6 +91,10 @@ class ApplicationController < ActionController::Base
return access_denied! unless can?(current_user, :download_code, project) or project.public?
end
def authorize_push!
return access_denied! unless can?(current_user, :push_code, project)
end
def authorize_create_team!
return access_denied! unless can?(current_user, :create_team, nil)
end
......
......@@ -35,8 +35,6 @@ class DashboardController < ApplicationController
current_user.authorized_projects
end.sorted_by_activity
@projects = @projects.search(params[:search]) if params[:search].present?
@labels = current_user.authorized_projects.tags_on(:labels)
@projects = @projects.tagged_with(params[:label]) if params[:label].present?
......
......@@ -61,7 +61,7 @@ class GroupsController < ApplicationController
end
end
def people
def members
@project = group.projects.find(params[:project_id]) if params[:project_id]
@members = group.users_groups.order('group_access DESC')
@users_group = UsersGroup.new
......
class Profiles::GroupsController < ApplicationController
layout "profile"
def index
@groups = current_user.authorized_groups.page(params[:page]).per(20)
end
def leave
@users_group = group.users_groups.where(user_id: current_user.id).first
if group.owner == current_user
redirect_to(profile_groups_path, alert: "You can't leave group. You must transfer it to another owner before leaving.")
else
@users_group.destroy
redirect_to(profile_groups_path, info: "You left #{group.name} group.")
end
end
private
def group
@group ||= Group.find_by_path(params[:id])
end
end
class Projects::BranchesController < Projects::ApplicationController
# Authorize
before_filter :authorize_read_project!
before_filter :require_non_empty_project
before_filter :authorize_code_access!
before_filter :authorize_push!, only: [:create]
before_filter :authorize_admin_project!, only: [:destroy]
def index
@branches = Kaminari.paginate_array(@repository.branches).page(params[:page]).per(30)
end
def create
@repository.add_branch(params[:branch_name], params[:ref])
if new_branch = @repository.find_branch(params[:branch_name])
Event.create_ref_event(@project, current_user, new_branch, 'add')
end
redirect_to project_branches_path(@project)
end
def destroy
branch = @repository.find_branch(params[:id])
if branch && @repository.rm_branch(branch.name)
Event.create_ref_event(@project, current_user, branch, 'rm')
end
respond_to do |format|
format.html { redirect_to project_branches_path(@project) }
format.js { render nothing: true }
end
end
end
......@@ -8,14 +8,6 @@ class Projects::RepositoriesController < Projects::ApplicationController
@activities = @repository.commits_with_refs(20)
end
def branches
@branches = @repository.branches
end
def tags
@tags = @repository.tags
end
def stats
@stats = Gitlab::Git::Stats.new(@repository.raw, @repository.root_ref)
@graph = @stats.graph
......@@ -26,7 +18,6 @@ class Projects::RepositoriesController < Projects::ApplicationController
render_404 and return
end
storage_path = Rails.root.join("tmp", "repositories")
file_path = @repository.archive_repo(params[:ref], storage_path)
......
class Projects::TagsController < Projects::ApplicationController
# Authorize
before_filter :authorize_read_project!
before_filter :require_non_empty_project
before_filter :authorize_code_access!
before_filter :authorize_push!, only: [:create]
before_filter :authorize_admin_project!, only: [:destroy]
def index
@tags = Kaminari.paginate_array(@repository.tags).page(params[:page]).per(30)
end
def create
@repository.add_tag(params[:tag_name], params[:ref])
if new_tag = @repository.find_tag(params[:tag_name])
Event.create_ref_event(@project, current_user, new_tag, 'add', 'refs/tags')
end
redirect_to project_tags_path(@project)
end
def destroy
tag = @repository.find_tag(params[:id])
if tag && @repository.rm_tag(tag.name)
Event.create_ref_event(@project, current_user, tag, 'rm', 'refs/tags')
end
respond_to do |format|
format.html { redirect_to project_tags_path }
format.js { render nothing: true }
end
end
end
......@@ -9,7 +9,7 @@ class UsersGroupsController < ApplicationController
def create
@group.add_users(params[:user_ids].split(','), params[:group_access])
redirect_to people_group_path(@group), notice: 'Users were successfully added.'
redirect_to members_group_path(@group), notice: 'Users were successfully added.'
end
def update
......@@ -21,7 +21,7 @@ class UsersGroupsController < ApplicationController
@users_group.destroy unless @users_group.user == @group.owner
respond_to do |format|
format.html { redirect_to people_group_path(@group), notice: 'User was successfully removed from group.' }
format.html { redirect_to members_group_path(@group), notice: 'User was successfully removed from group.' }
format.js { render nothing: true }
end
end
......
......@@ -134,7 +134,7 @@ module CommitsHelper
parts = @path.split('/')
parts.each_with_index do |part, i|
crumbs += content_tag(:span, '/', class: 'divider')
crumbs += content_tag(:span, ' / ', class: 'divider')
crumbs += content_tag(:li) do
# The text is just the individual part, but the link needs all the parts before it
link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
......
......@@ -81,8 +81,8 @@ module TabHelper
end
def branches_tab_class
if current_page?(branches_project_repository_path(@project)) ||
current_controller?(:protected_branches) ||
if current_controller?(:protected_branches) ||
current_controller?(:branches) ||
current_page?(project_repository_path(@project))
'active'
end
......
......@@ -54,6 +54,27 @@ class Event < ActiveRecord::Base
Event::COMMENTED
end
end
def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
if action.to_s == 'add'
before = '00000000'
after = ref.commit.id
else
before = ref.commit.id
after = '00000000'
end
Event.create(
project: project,
action: Event::PUSHED,
data: {
ref: "#{prefix}/#{ref.name}",
before: before,
after: after
},
author_id: user.id
)
end
end
def proper?
......
......@@ -21,11 +21,11 @@ class Key < ActiveRecord::Base
attr_accessible :key, :title
before_validation :strip_white_space
before_validation :strip_white_space, :generate_fingerpint
validates :title, presence: true, length: { within: 0..255 }
validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\Assh-.*\Z/ }, uniqueness: true
validate :fingerprintable_key
validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ }, uniqueness: true
validates :fingerprint, uniqueness: true, presence: { message: 'cannot be generated' }
delegate :name, :email, to: :user, prefix: true
......@@ -33,15 +33,6 @@ class Key < ActiveRecord::Base
self.key = key.strip unless key.blank?
end
def fingerprintable_key
return true unless key # Don't test if there is no key.
unless generate_fingerpint
errors.add(:key, "can't be fingerprinted")
false
end
end
# projects that has this key
def projects
user.authorized_projects
......@@ -54,26 +45,21 @@ class Key < ActiveRecord::Base
private
def generate_fingerpint
self.fingerprint = nil
return unless key.present?
cmd_status = 0
cmd_output = ''
file = Tempfile.new('gitlab_key_file')
begin
Tempfile.open('gitlab_key_file') do |file|
file.puts key
file.rewind
cmd_output, cmd_status = popen("ssh-keygen -lf #{file.path}", '/tmp')
ensure
file.close
file.unlink # deletes the temp file
end
if cmd_status.zero?
cmd_output.gsub /([\d\h]{2}:)+[\d\h]{2}/ do |match|
self.fingerprint = match
end
true
else
false
end
end
end
......@@ -88,7 +88,7 @@ class Project < ActiveRecord::Base
validates_uniqueness_of :path, scope: :namespace_id
validates :import_url,
format: { with: URI::regexp(%w(http https)), message: "should be a valid url" },
format: { with: URI::regexp(%w(git http https)), message: "should be a valid url" },
if: :import?
validate :check_limit
......
class Repository
include Gitlab::ShellAdapter
attr_accessor :raw_repository
def initialize(path_with_namespace, default_branch)
......@@ -33,6 +35,38 @@ class Repository
commits
end
def find_branch(name)
branches.find { |branch| branch.name == name }
end
def find_tag(name)
tags.find { |tag| tag.name == name }
end
def add_branch(branch_name, ref)
Rails.cache.delete(cache_key(:branch_names))
gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
end
def add_tag(tag_name, ref)
Rails.cache.delete(cache_key(:tag_names))
gitlab_shell.add_tag(path_with_namespace, tag_name, ref)
end
def rm_branch(branch_name)
Rails.cache.delete(cache_key(:branch_names))
gitlab_shell.rm_branch(path_with_namespace, branch_name)
end
def rm_tag(tag_name)
Rails.cache.delete(cache_key(:tag_names))
gitlab_shell.rm_tag(path_with_namespace, tag_name)
end
def round_commit_count
if commit_count > 10000
'10000+'
......
%h3.page_title Background Jobs
%h3.page-title Background Jobs
%br
.ui-box
%iframe{src: sidekiq_path, width: '100%', height: 900, style: "border: none"}
.admin_dash.row
.span4
.ui-box
%h5.title Projects
.title Projects
.data.padded
= link_to admin_projects_path do
%h1= Project.count
......@@ -9,7 +9,7 @@
= link_to 'New Project', new_project_path, class: "btn btn-small"
.span4
.ui-box
%h5.title Users
.title Users
.data.padded
= link_to admin_users_path do
%h1= User.count
......@@ -17,7 +17,7 @@
= link_to 'New User', new_admin_user_path, class: "btn btn-small"
.span4
.ui-box
%h5.title Groups
.title Groups
.data.padded
= link_to admin_groups_path do
%h1= Group.count
......
%h3.page_title Edit Group
%h3.page-title Edit Group
%hr
= form_for [:admin, @group] do |f|
- if @group.errors.any?
......
%h3.page_title
%h3.page-title
Groups (#{@groups.total_count})
%small
allows you to keep projects organized.
......
%h3.page_title New Group
%h3.page-title New Group
%hr
= form_for [:admin, @group] do |f|
- if @group.errors.any?
......
%h3.page_title
%h3.page-title
Group: #{@group.name}
= link_to edit_admin_group_path(@group), class: "btn btn-small pull-right" do
......@@ -8,7 +8,7 @@
.row
.span6
.ui-box
%h5.title
.title
Group info:
%ul.well-list
%li
......@@ -50,7 +50,7 @@
= @group.created_at.stamp("March 1, 1999")
.ui-box
%h5.title
.title
Projects
%small
(#{@group.projects.count})
......@@ -64,7 +64,7 @@
.span6
.ui-box
%h5.title
.title
Add user(s) to the group:
.ui-box-body.form-holder
%p.light
......@@ -79,7 +79,7 @@
%hr
= submit_tag 'Add users into group', class: "btn btn-create"
.ui-box
%h5.title
.title
%strong #{@group.name}
Group Members
%small
......
......@@ -11,57 +11,57 @@
%p.light To prevent performance issues admin logs output the last 2000 lines
.tab-content
.tab-pane.active#githost
.file_holder#README
.file_title
.file-holder#README
.file-title
%i.icon-file
githost.log
.pull-right
= link_to '#', class: 'log-bottom' do
%i.icon-arrow-down
Scroll down
.file_content.logs
.file-content.logs
%ol
- Gitlab::GitLogger.read_latest.each do |line|
%li
%p= line
.tab-pane#application
.file_holder#README
.file_title
.file-holder#README
.file-title
%i.icon-file
application.log
.pull-right
= link_to '#', class: 'log-bottom' do
%i.icon-arrow-down
Scroll down
.file_content.logs
.file-content.logs
%ol
- Gitlab::AppLogger.read_latest.each do |line|
%li
%p= line
.tab-pane#production
.file_holder#README
.file_title
.file-holder#README
.file-title
%i.icon-file
production.log
.pull-right
= link_to '#', class: 'log-bottom' do
%i.icon-arrow-down
Scroll down
.file_content.logs
.file-content.logs
%ol
- Gitlab::Logger.read_latest_for('production.log').each do |line|
%li
%p= line
.tab-pane#sidekiq
.file_holder#README
.file_title
.file-holder#README
.file-title
%i.icon-file
sidekiq.log
.pull-right
= link_to '#', class: 'log-bottom' do
%i.icon-arrow-down
Scroll down
.file_content.logs
.file-content.logs
%ol
- Gitlab::Logger.read_latest_for('sidekiq.log').each do |line|
%li
......
%h3.page_title
Projects
= link_to 'New Project', new_project_path, class: "btn btn-small pull-right"
%hr
.row
.span4
.admin-filter
......@@ -41,8 +35,10 @@
= link_to "Reset", admin_projects_path, class: "btn"
.span8
.ui-box
%h5.title
.title
Projects (#{@projects.total_count})
.pull-right
= link_to 'New Project', new_project_path, class: "btn btn-small btn-primary wide"
%ul.well-list
- @projects.each do |project|
%li
......
%h3.page_title
%h3.page-title
Project: #{@project.name_with_namespace}
= link_to edit_project_path(@project), class: "btn pull-right" do
%i.icon-edit
......@@ -7,7 +7,7 @@
.row
.span6
.ui-box
%h5.title
.title
Project info:
%ul.well-list
%li
......@@ -76,7 +76,7 @@
.span6
- if @group
.ui-box
%h5.title
.title
%strong #{@group.name} Group
members (#{@group.users_groups.count})
.pull-right
......@@ -87,7 +87,7 @@
= render 'users_groups/users_group', member: member, show_controls: false
.ui-box
%h5.title
.title
Team
%small
(#{@project.users.count})
......
%h3.page_title
%h3.page-title
#{@user.name} &rarr;
%i.icon-edit
Edit user
......
%h3.page_title
Users
= link_to 'New User', new_admin_user_path, class: "btn btn-small pull-right"
%br
.row
.span3
.admin-filter
......@@ -32,8 +27,10 @@
.span9
.ui-box
%h5.title
.title
Users (#{@users.total_count})
.pull-right
= link_to 'New User', new_admin_user_path, class: "btn btn-small wide btn-primary"
%ul.well-list
- @users.each do |user|
%li
......
%h3.page_title
%h3.page-title
%i.icon-plus
New user
%hr
......
%h3.page_title
%h3.page-title
User:
= @user.name
- if @user.blocked?
......@@ -21,7 +21,7 @@
.row
.span6
.ui-box
%h5.title
.title
Account:
.pull-right
= image_tag gravatar_icon(@user.email, 32), class: "avatar s32"
......@@ -65,7 +65,7 @@
- if @user.users_groups.present?
.ui-box
%h5.title Groups:
.title Groups:
%ul.well-list
- @user.users_groups.each do |user_group|
- group = user_group.group
......@@ -76,7 +76,7 @@
.span6
.ui-box
%h5.title Projects (#{@projects.count})
.title Projects (#{@projects.count})
%ul.well-list
- @projects.sort_by(&:name_with_namespace).each do |project|
- tm = project.team.find_tm(@user.id)
......
= form_tag dashboard_filter_path(entity), method: 'get' do
%fieldset.dashboard-search-filter
= search_field_tag "search", params[:search], { id: 'filter_search', placeholder: 'Search', class: 'search-text-input' }
= button_tag type: 'submit', class: 'btn' do
%i.icon-search
%fieldset
%legend Status:
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if !params[:status])}
= link_to dashboard_filter_path(entity, status: nil) do
......
.ui-box
%h5.title.clearfix
.title.clearfix
= search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter'
- if current_user.can_create_group?
%span.pull-right
......@@ -10,7 +10,7 @@
- groups.each do |group|
%li.group-row
= link_to group_path(id: group.path), class: dom_class(group) do
%span.group-name
%span.group-name.filter-title
= truncate(group.name, length: 35)
%span.arrow
%i.icon-angle-right
......
.ui-box
%h5.title.clearfix
.title.clearfix
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter'
- if current_user.can_create_project?
%span.pull-right
......@@ -15,7 +15,7 @@
- if project.namespace
= project.namespace.human_name
\/
%span.project-name
%span.project-name.filter-title
= truncate(project.name, length: 25)
%span.arrow
%i.icon-angle-right
......
%h3.page_title
%h3.page-title
Issues
%small (assigned to you)
%small.pull-right #{@issues.total_count} issues
%hr
%span.light
&ndash;
Assigned to you
%span.pull-right #{@issues.total_count} issues
.row
.span3
......@@ -13,7 +13,7 @@
- @issues.group_by(&:project).each do |group|
%div.ui-box
- project = group[0]
%h5.title
.title
= link_to_project project
&nbsp;
%i.icon-angle-right
......
%h3.page_title
%h3.page-title
Merge Requests
%small (authored by or assigned to you)
%small.pull-right #{@merge_requests.total_count} merge requests
%span.light
&ndash;
Authored by or assigned to you
%span.pull-right #{@merge_requests.total_count} merge requests
%hr
.row
.span3
= render 'filter', entity: 'merge_request'
......
......@@ -22,7 +22,7 @@
.span9
.ui-box
%h5.title
.title
Projects (#{@projects.total_count})
.pull-right.light
%small Last activity
......
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { class: "login-box", method: :post }) do |f|
%h3.page_title Reset password
%h3.page-title Reset password
%br
= devise_error_messages!
= f.email_field :email, placeholder: "Email", class: "text"
......
= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: "login-box" }) do |f|
%h3.page_title Sign Up
%h3.page-title Sign Up
%br
= devise_error_messages!
%div
......
.login-box
%h3.page_title Sign in
%h3.page-title Sign in
%br
- if ldap_enabled?
%ul.nav.nav-tabs
......
%h1.http_status_code 403
%h3.page_title Access Denied
%h3.page-title Access Denied
%hr
%p You are not allowed to access this page.
%p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"}
%h1.http_status_code 500
%h3.page_title Encoding Error
%h3.page-title Encoding Error
%hr
%p Page can't be loaded because of an encoding error.
%h1.http_status_code 404
%h3.page_title Git Resource Not found
%h3.page-title Git Resource Not found
%hr
%p
Application can't get access to some branch or commit in your repository. It
......
%h1.http_status_code 404
%h3.page_title The resource you were looking for doesn't exist.
%h3.page-title The resource you were looking for doesn't exist.
%hr
%p You may have mistyped the address or the page may have moved.
- if show_last_push_widget?(event)
.event_lp
.event-last-push
%span You pushed to
= link_to project_commits_path(event.project, event.ref_name) do
%strong= truncate(event.ref_name, length: 28)
......@@ -8,6 +8,7 @@
%span
= time_ago_in_words(event.created_at)
ago.
= link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-new-mr" do
Create Merge Request
.pull-right
= link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-small" do
Create Merge Request
%hr
......@@ -13,9 +13,10 @@
= sanitize(markdown(truncate(event.target.note, length: 150)), tags: %w(a img b pre p))
- note = event.target
- if note.attachment.url
= link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do
- if note.attachment.image?
- if note.attachment.image?
= link_to note.attachment.url, target: '_blank' do
= image_tag note.attachment.url, class: 'note-image-attach'
- else
- else
= link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do
%i.icon-paper-clip
= note.attachment_identifier
= form_tag group_filter_path(entity), method: 'get' do
%fieldset.dashboard-search-filter
= search_field_tag "search", params[:search], { placeholder: 'Search', class: 'search-text-input' }
= button_tag type: 'submit', class: 'btn' do
%i.icon-search
%fieldset
%legend Status:
%ul.nav.nav-pills.nav-stacked
%li{class: ("active" if !params[:status])}
= link_to group_filter_path(entity, status: nil) do
......
......@@ -2,7 +2,7 @@
%fieldset
%legend= "New Group member(s) for #{@group.name}"
%h6 1. Choose people you want in the group
%h6 1. Choose users you want in the group
.clearfix
= f.label :user_ids, "People"
.input= users_select_tag(:user_ids, multiple: true, class: 'input-large')
......@@ -13,6 +13,5 @@
.input= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select chosen"
.form-actions
= hidden_field_tag :redirect_to, people_group_path(@group)
= f.submit 'Add users into group', class: "btn btn-create"
.ui-box
%h5.title
.title
Projects (#{projects.count})
- if can? current_user, :manage_group, @group
%span.pull-right
......
......@@ -18,7 +18,7 @@
.tab-content
.tab-pane.active#tab-edit
.ui-box
%h5.title
.title
%strong= @group.name
Group Settings:
%div.form-holder
......@@ -42,7 +42,7 @@
.tab-pane#tab-projects
.ui-box
%h5.title
.title
%strong= @group.name
Projects:
- if can? current_user, :manage_group, @group
......@@ -67,7 +67,7 @@
.tab-pane#tab-transfer
.ui-box.ui-box-danger
%h5.title Transfer group
.title Transfer group
.ui-box-body
%p
Transferring group will cause loss of admin control over group and all child projects
......@@ -78,7 +78,7 @@
.tab-pane#tab-remove
.ui-box.ui-box-danger
%h5.title Remove group
.title Remove group
.ui-box-body
%p
Remove of group will cause removing all child projects and resources.
......
%h3.page_title
%h3.page-title
Issues
%small (assigned to you)
%small.pull-right #{@issues.total_count} issues
......@@ -12,7 +12,7 @@
- @issues.group_by(&:project).each do |group|
%div.ui-box
- project = group[0]
%h5.title
.title
= link_to_project project
%ul.well-list.issues-list
- group[1].each do |issue|
......
......@@ -9,8 +9,9 @@
Only group owners can manage group members
.span6
.ui-box
%h5.title
#{@group.name} Group Members
.title
%strong #{@group.name}
Group Members
%small
(#{@members.count})
%ul.well-list
......
%h3.page_title
%h3.page-title
Merge Requests
%small (authored by or assigned to you)
%small.pull-right #{@merge_requests.total_count} merge requests
......
= render layout: 'help/api_layout' do
%h3.page_title
%h3.page-title
%span.light API
%span
\/
= @category.titleize
%br
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
= @category
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "api", "#{@category}.md"))
%h3.page_title
GITLAB
%h2.page-title
GitLab
%span.light Enterprise Edition
.pull-right
%span= Gitlab::VERSION
%small= Gitlab::REVISION
%hr
%p.lead
%p.slead
Self Hosted Git Management
%br
Fast, secure and stable solution based on Ruby on Rails.
......@@ -16,7 +15,7 @@
.span4
.ui-box
.title
%h5 Quick help
Quick help
%ul.well-list
%li
Email your
......@@ -40,7 +39,7 @@
.span4
.ui-box
.title
%h5 User documentation
User documentation
%ul.well-list
%li
%strong= link_to "Workflow", help_workflow_path
......@@ -69,7 +68,7 @@
.span4
.ui-box
.title
%h5 Admin documentation
Admin documentation
%ul.well-list
%li
......
= render layout: 'help/layout' do
%h3.page_title GitLab Flavored Markdown
%h3.page-title GitLab Flavored Markdown
%br
.help_body
......
= render layout: 'help/layout' do
%h3.page_title Permissions
%h3.page-title Permissions
%br
%fieldset
......
= render layout: 'help/layout' do
%h3.page_title Public Access
%h3.page-title Public Access
%br
%p
......
= render layout: 'help/layout' do
%h3.page_title GitLab Rake Tasks
%h3.page-title GitLab Rake Tasks
%br
%p.slead
......@@ -19,46 +19,46 @@
.tab-content
.tab-pane.active#features
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
Features
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "features.md"))
.tab-pane#maintenance
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
Maintenance
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "maintenance.md"))
.tab-pane#user_management
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
User Management
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "user_management.md"))
.tab-pane#cleanup
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
Cleanup
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "cleanup.md"))
.tab-pane#backup_restore
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
Backup & Restore
.file_content.wiki
.file-content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "raketasks", "backup_restore.md"))
= render layout: 'help/layout' do
%h3.page_title SSH Keys
%h3.page-title SSH Keys
%br
%p.slead
......
= render layout: 'help/layout' do
%h3.page_title System hooks
%h3.page-title System hooks
%br
%p.slead
......
= render layout: 'help/layout' do
%h3.page_title Web hooks
%h3.page-title Web hooks
%br
%p.slead
......@@ -9,5 +9,5 @@
%br
GitLab will send POST request with commits information on every push.
%h5 Hooks request example:
= render "hooks/data_ex"
= render "projects/hooks/data_ex"
= render layout: 'help/layout' do
%h3.page_title Workflow
%h3.page-title Workflow
%br
%ol.help
......
.flash-container
- if alert
.alert
.alert.alert-error
%span= alert
- elsif notice
......
- if content_for?(:page_title)
= yield :page_title
- if content_for?(:page-title)
= yield :page-title
......@@ -10,8 +10,8 @@
= link_to merge_requests_group_path(@group) do
Merge Requests
%span.count= current_user.cared_merge_requests.opened.of_group(@group).count
= nav_link(path: 'groups#people') do
= link_to "People", people_group_path(@group)
= nav_link(path: 'groups#members') do
= link_to "Members", members_group_path(@group)
- if can?(current_user, :manage_group, @group)
= nav_link(path: 'groups#edit') do
......
......@@ -12,6 +12,8 @@
%span.count= current_user.keys.count
= nav_link(path: 'profiles#design') do
= link_to "Design", design_profile_path
= nav_link(controller: :groups) do
= link_to "Groups", profile_groups_path
= nav_link(path: 'profiles#history') do
= link_to "History", history_profile_path
......@@ -4,11 +4,11 @@
%i.icon-home
- if project_nav_tab? :files
= nav_link(controller: %w(tree blob blame)) do
= nav_link(controller: %w(tree blob blame edit_tree)) do
= link_to 'Files', project_tree_path(@project, @ref || @repository.root_ref)
- if project_nav_tab? :commits
= nav_link(controller: %w(commit commits compare repositories protected_branches)) do
= nav_link(controller: %w(commit commits compare repositories protected_branches tags branches)) do
= link_to "Commits", project_commits_path(@project, @ref || @repository.root_ref)
- if project_nav_tab? :network
......
.ui-box
.title
%strong Groups
(#{@groups.count})
- if current_user.can_create_group?
%span.pull-right
= link_to new_group_path, class: "btn btn-small btn-primary" do
%i.icon-plus
New Group
%ul.well-list
- @groups.each do |group|
%li
.pull-right
- if can?(current_user, :manage_group, group)
= link_to edit_group_path(group), class: "btn-small btn grouped" do
%i.icon-cogs
Settings
= link_to leave_profile_group_path(group), confirm: "Are you sure you want to leave #{group.name} group?", method: :delete, class: "btn-small btn grouped", title: 'Remove user from group' do
%i.icon-signout
Leave
= link_to group, class: 'group-name' do
= group.name
= paginate @groups
%h3.page_title
SSH Keys
= link_to "Add SSH Key", new_profile_key_path, class: "btn pull-right btn-primary"
%br
%p.light
SSH key allows you to establish a secure connection between your computer and GitLab
%p.light
......@@ -12,9 +7,10 @@
.ui-box
%h5.title
.title
SSH Keys (#{@keys.count})
.pull-right
= link_to "Add SSH Key", new_profile_key_path, class: "btn btn-small btn-primary"
%ul.well-list#keys-table
= render @keys
- if @keys.blank?
......
%h3.page_title Add an SSH Key
%h3.page-title Add an SSH Key
%hr
= render 'form'
......
.row
.span4
.ui-box
%h5.title
.title
SSH Key
%ul.well-list
%li
......
%h3.page_title Setup your notification level
%br
%h3.page-title Setup your notification level
%p.light
%strong Disabled
......
.profile_avatar_holder
= image_tag gravatar_icon(@user.email, 90), alt: ''
%h3.page_title
= image_tag gravatar_icon(@user.email, 60), alt: '', class: 'avatar s60'
%h3.page-title
= @user.name
%br
%small
......
......@@ -11,14 +11,14 @@
%li= link
.clear
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
%span.file_name
= @blob.name
%small= number_to_human_size @blob.size
%span.options= render "projects/blob/actions"
.file_content.blame
.file-content.blame
%table
- current_line = 1
- @blame.each do |commit, lines|
......
......@@ -17,8 +17,8 @@
= link_to title, '#'
%div#tree-content-holder.tree-content-holder
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
%span.file_name
= blob.name
......
.file_content.blob_file
.file-content.blob_file
%center
= link_to project_blob_path(@project, @id) do
= link_to project_raw_path(@project, @id) do
%div.padded
%h4
%i.icon-download-alt
......
.file_content.image_file
.file-content.image_file
%img{ src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"}
- if gitlab_markdown?(blob.name)
.file_content.wiki
.file-content.wiki
= preserve do
= markdown(blob.data)
- elsif markup?(blob.name)
.file_content.wiki
.file-content.wiki
= raw GitHub::Markup.render(blob.name, blob.data)
- else
.file_content.code
.file-content.code
- unless blob.empty?
%div{class: user_color_scheme_class}
= raw blob.colorize(formatter: :gitlab)
......
- commit = Commit.new(Gitlab::Git::Commit.new(branch.commit))
%tr
%td
%li
%h4
= link_to project_commits_path(@project, branch.name) do
- if @project.protected_branch? branch.name
%i.icon-lock
- else
%i.icon-unlock
%strong= truncate(branch.name, length: 60)
- if branch.name == @repository.root_ref
%span.label default
%td
%span.label.label-info default
- if @project.protected_branch? branch.name
%span.label.label-success
%i.icon-lock
.pull-right
- if can?(current_user, :download_code, @project)
= link_to archive_project_repository_path(@project, ref: branch.name), class: 'btn grouped btn-small' do
%i.icon-download-alt
Download
- if can?(current_user, :admin_project, @project) && branch.name != @repository.root_ref
= link_to project_branch_path(@project, branch.name), class: 'btn grouped btn-small remove-row', method: :delete, confirm: 'Removed branch cannot be restored. Are you sure?', remote: true do
%i.icon-trash
%p
= link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
= commit.short_id
= image_tag gravatar_icon(commit.author_email), class: "avatar s16", alt: ''
......@@ -18,9 +26,3 @@
%span
= time_ago_in_words(commit.committed_date)
ago
%td
- if can? current_user, :download_code, @project
= link_to archive_project_repository_path(@project, ref: branch.name) do
%i.icon-download-alt
Download
= render "projects/commits/head"
.row
.span3
= render "projects/repositories/filter"
.span9
- unless @branches.empty?
%ul.bordered-list
- @branches.each do |branch|
= render "projects/branches/branch", branch: branch
= paginate @branches, theme: 'gitlab'
%h3.page-title
%i.icon-code-fork
New branch
= form_tag project_branches_path, method: :post do
.control-group
= label_tag :branch_name, 'Name for new branch', class: 'control-label'
.controls
= text_field_tag :branch_name, nil, placeholder: 'feature/dashboard', required: true, tabindex: 1
.control-group
= label_tag :ref, 'Create from', class: 'control-label'
.controls
= text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2
.light branch name or commit SHA
.form-actions
= submit_tag 'Create branch', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel'
:javascript
var availableTags = #{@project.repository.ref_names.to_json};
$("#ref").autocomplete({
source: availableTags,
minLength: 1
});
.ui-box.ui-box-show
.ui-box.ui-box-show.commit-box
.ui-box-head
.pull-right
- if @notes_count > 0
......@@ -15,7 +15,7 @@
%li= link_to "Plain Diff", project_commit_path(@project, @commit, format: :diff)
= link_to project_tree_path(@project, @commit), class: "btn btn-primary grouped" do
%span Browse Code »
%h3.commit-title.page_title
%h3.commit-title.page-title
= gfm escape_once(@commit.title)
- if @commit.description.present?
%pre.commit-description
......
= render "commit/commit_box"
= render "projects/commit/commit_box"
.alert.alert-error
%h4 Commit diffs are too big to be displayed
= render "commit_box"
- unless @commit.has_zero_stats?
%p.pull-right.cgray
This commit has
%span.cgreen #{@commit.stats.additions} additions
and
%span.cred #{@commit.stats.deletions} deletions
= render "projects/commits/diffs", diffs: @commit.diffs
= render "projects/notes/notes_with_form"
- @commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits|
%div.ui-box
%h5.title
.title
%i.icon-calendar
%span= day.stamp("28 Aug, 2010")
......
......@@ -7,8 +7,15 @@
But if you still want to see diff
= link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "underlined_link"
%p.cgray
Showing #{pluralize(diffs.count, "changed file")}
%p.commit-stat-summary
Showing
%strong.cdark #{pluralize(diffs.count, "changed file")}
- if current_controller?(:commit)
- unless @commit.has_zero_stats?
with
%strong.cgreen #{@commit.stats.additions} additions
and
%strong.cred #{@commit.stats.deletions} deletions
.file-stats
= render "projects/commits/diff_head", diffs: diffs
......
......@@ -11,8 +11,8 @@
Branches
%span.badge= @repository.branches.length
= nav_link(controller: :repositories, action: :tags) do
= link_to tags_project_repository_path(@project) do
= nav_link(controller: :tags) do
= link_to project_tags_path(@project) do
Tags
%span.badge= @repository.tags.length
......
......@@ -2,6 +2,8 @@
- if @path.present?
%ul.breadcrumb
%li.light
History for
= commits_breadcrumbs
%div{id: dom_id(@project)}
......
......@@ -19,7 +19,7 @@
= text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
.pull-left
&nbsp;
= submit_tag "Compare", class: "btn btn-primary wide commits-compare-btn"
= submit_tag "Compare", class: "btn btn-create commits-compare-btn"
- if @refs_are_same
.alert
%span Refs are the same
......
= render "projects/commits/head"
%h3.page_title
%h3.page-title
Compare View
%hr
= render "form"
= render "projects/commits/head"
%h3.page_title
%h3.page-title
Compare View
%hr
= render "form"
......@@ -14,7 +13,7 @@
- if @commits.present?
%div.ui-box
%h5.title
.title
Commits (#{@commits.count})
%ul.well-list= render Commit.decorate(@commits)
......
%h3.page_title New Deploy key
%h3.page-title New Deploy key
%hr
= render 'form'
%h3.page_title
%h3.page-title
Deploy key:
= @key.title
%small
created at
= @key.created_at.stamp("Aug 21, 2011")
.back_link
.back-link
= link_to project_deploy_keys_path(@project) do
&larr; To keys list
%hr
......
......@@ -2,7 +2,7 @@
.project-edit-errors
.project-edit-content
.ui-box.white
%h5.title
.title
%strong= @project.name
Project Settings:
.form-holder
......@@ -102,7 +102,7 @@
- if can?(current_user, :change_namespace, @project)
.ui-box.ui-box-danger
%h5.title Transfer project
.title Transfer project
.errors-holder
.form-holder
= form_for(@project, url: transfer_project_path(@project), remote: true, html: { class: 'transfer-project' }) do |f|
......@@ -122,7 +122,7 @@
%p.nothing_here_message Only project owner can transfer a project
.ui-box.ui-box-danger
%h5.title Rename repository
.title Rename repository
.errors-holder
.form-holder
= form_for(@project) do |f|
......@@ -140,7 +140,7 @@
- if can?(current_user, :remove_project, @project)
.ui-box.ui-box-danger
%h5.title Remove project
.title Remove project
.ui-box-body
%p
Remove of project will cause removing repository and all related resources like issues, merge requests etc.
......
.file-editor
= form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
%span.file_name
= @path
......@@ -11,7 +11,7 @@
%span.options
.btn-group.tree-btn-group
= link_to "Cancel", project_blob_path(@project, @id), class: "btn btn-tiny btn-cancel", confirm: leave_edit_message
.file_content.code
.file-content.code
%pre#editor= @blob.data
.control-group.commit_message-group
......@@ -21,7 +21,7 @@
= text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3
.form-actions
= hidden_field_tag 'last_commit', @last_commit
= hidden_field_tag 'content', '', id: :file_content
= hidden_field_tag 'content', '', id: "file-content"
.commit-button-annotation
= button_tag "Commit changes", class: 'btn commit-btn js-commit-button btn-primary'
.message
......@@ -40,6 +40,6 @@
disableButtonIfEmptyField("#commit_message", ".js-commit-button");
$(".js-commit-button").click(function(){
$("#file_content").val(editor.getValue());
$("#file-content").val(editor.getValue());
$(".file-editor form").submit();
});
.loading-graph
%center
.loading
%h3.page_title Building repository graph. Please wait a moment.
%h3.page-title Building repository graph. Please wait a moment.
.stat-graph
.header.clearfix
......@@ -10,7 +10,7 @@
%option{:value => "commits"} Commits
%option{:value => "additions"} Additions
%option{:value => "deletions"} Deletions
%h3#date_header.page_title
%h3#date_header.page-title
%input#brush_change{:type => "hidden"}
.graphs
#contributors-master
......
......@@ -21,7 +21,7 @@
-if @hooks.any?
.ui-box
%h5.title
.title
Hooks (#{@hooks.count})
%ul.well-list
- @hooks.each do |hook|
......
%div.issue-form-holder
%h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
%h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
= form_for [@project, @issue] do |f|
-if @issue.errors.any?
.alert.alert-error
......
......@@ -18,7 +18,7 @@
%span
%i.icon-comments
= issue.notes.count
- if issue.milestone_id?
- if issue.milestone
%span
%i.icon-time
= issue.milestone.title
......
= render "head"
.issues_content
%h3.page_title
%h3.page-title
Issues
%span (<span class=issue_counter>#{@issues.total_count}</span>)
.pull-right
......@@ -16,8 +16,6 @@
= hidden_field_tag :label_name, params[:label_name], id: 'search_label_name'
= search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search input-xlarge append-right-10 search-text-input' }
.clearfix
.row
.span3
= render 'filter', entity: 'issue'
......
%h3.page_title
%h3.page-title
Issue ##{@issue.id}
%small
......@@ -22,7 +22,7 @@
.pull-right
.span3#votes= render 'votes/votes_block', votable: @issue
.back_link
.back-link
= link_to project_issues_path(@project) do
&larr; To issues list
......
= render "projects/issues/head"
%h3.page_title
Labels
%br
- if @labels.present?
%ul.bordered-list.labels-table
- @labels.each do |label|
......
......@@ -5,49 +5,48 @@
- @merge_request.errors.full_messages.each do |msg|
%li= msg
%fieldset
%legend 1. Select Branches
%h3.page-title
%i.icon-code-fork
Branches
.merge-request-branches
.row
.span5
.light-well
%h5.cgray From (Head Branch)
= f.select(:source_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
.mr_source_commit.prepend-top-10
.row
.span5
.mr_branch_box
%h5.cgray From (Head Branch)
.body
.padded= f.select(:source_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
.mr_source_commit
.span2
%h1.merge-request-angle
%i.icon-angle-right
.span5
.light-well
%h5.cgray To (Base Branch)
= f.select(:target_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
.mr_target_commit.prepend-top-10
.span2
%center= image_tag "merge.png", class: 'mr_direction_tip'
.span5
.mr_branch_box
%h5.cgray To (Base Branch)
.body
.padded= f.select(:target_branch, @repository.branch_names, { include_blank: "Select branch" }, {class: 'chosen span4'})
.mr_target_commit
%hr
%fieldset
%legend 2. Fill info
%h3.page-title
%i.icon-paper-clip
Details
.merge-request-form-info
.clearfix
= f.label :title do
%strong= "Title *"
.input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
.clearfix
.left
= f.label :assignee_id do
%i.icon-user
Assign to
.input= f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
.left
= f.label :milestone_id do
%i.icon-time
Milestone
.input= f.select(:milestone_id, @project.milestones.active.all.map {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
.ui-box.ui-box-show
.ui-box-head
.clearfix
= f.label :title do
%strong= "Title *"
.input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true
.ui-box-body
.clearfix
.left
= f.label :assignee_id do
%i.icon-user
Assign to
.input= f.select(:assignee_id, @project.team.members.sort_by(&:name).map {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
.left
= f.label :milestone_id do
%i.icon-time
Milestone
.input= f.select(:milestone_id, @project.milestones.active.all.map {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'})
.control-group
.form-actions
- if @merge_request.new_record?
......
%h3.page_title
%h3.page-title
= "Edit merge request #{@merge_request.id}"
%hr
= render 'form'
......@@ -2,11 +2,9 @@
= link_to new_project_merge_request_path(@project), class: "pull-right btn btn-primary", title: "New Merge Request" do
%i.icon-plus
New Merge Request
%h3.page_title
%h3.page-title
Merge Requests
%br
.row
.span3
......
%h3.page_title New Merge Request
%h3.page-title New Merge Request
%hr
= render 'form'
- if @commits.present?
.ui-box
%h5.title
.title
%i.icon-list
Commits (#{@commits.count})
.commits
......
......@@ -14,7 +14,7 @@
%strong= link_to "click here", "#", class: "how_to_merge_link vlink", title: "How To Merge"
for instructions
.accept_group
= f.submit "Accept Merge Request", class: "btn success accept_merge_request"
= f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request"
- unless @project.root_ref? @merge_request.source_branch
.remove_branch_holder
= label_tag :should_remove_source_branch, class: "checkbox" do
......
%h3.page_title
%h3.page-title
= "Merge Request ##{@merge_request.id}:"
&nbsp;
%span.label-branch= @merge_request.source_branch
......@@ -26,6 +26,6 @@
.pull-right
.span3#votes= render 'votes/votes_block', votable: @merge_request
.back_link
.back-link
= link_to project_merge_requests_path(@project) do
&larr; To merge requests
%h3.page_title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
.back_link
%h3.page-title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
.back-link
= link_to project_milestones_path(@project) do
&larr; To milestones
......
.ui-box
%h5.title= title
.title= title
%ul.well-list
- issues.each do |issue|
%li
......
= render "projects/issues/head"
.milestones_content
%h3.page_title
%h3.page-title
Milestones
- if can? current_user, :admin_milestone, @project
= link_to new_project_milestone_path(@project), class: "pull-right btn btn-primary", title: "New Milestone" do
%i.icon-plus
New Milestone
%br
.row
.span3
......
= render "projects/issues/head"
.row
.span6
%h3.page_title
%h3.page-title
Milestone ##{@milestone.id}
%small
= @milestone.expires_at
.back_link
.back-link
= link_to project_milestones_path(@project) do
&larr; To milestones list
.span6
......@@ -84,13 +84,13 @@
.row
.span6
.ui-box
%h5.title Open
.title Open
%ul.well-list
- @merge_requests.opened.each do |merge_request|
= render 'merge_request', merge_request: merge_request
.span6
.ui-box
%h5.title Closed
.title Closed
%ul.well-list
- @merge_requests.closed.each do |merge_request|
= render 'merge_request', merge_request: merge_request
......
%h3.page_title Project Network Graph
%hr
.clearfix
.pull-left
= render partial: 'shared/ref_switcher', locals: {destination: 'graph'}
......
= render "head"
.graph_holder
%h4
%small You can move around the graph by using the arrow keys.
#holder.graph
.project-network
.tip
You can move around the graph by using the arrow keys.
.network-graph
.loading.loading-gray
:javascript
var branch_graph;
$("#filter_ref").click(function() {
$(this).closest('form').submit();
});
branch_graph = new BranchGraph($("#holder"), {
new Network({
url: '#{project_network_path(@project, @ref, @options.merge(format: :json))}',
commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}',
ref: '#{@ref}',
commit_id: '#{@commit.id}'
});
})
......@@ -51,7 +51,8 @@
- if note.attachment.url
.note-attachment
- if note.attachment.image?
= image_tag note.attachment.url, class: 'note-image-attach'
= link_to note.attachment.url, target: '_blank' do
= image_tag note.attachment.url, class: 'note-image-attach'
.attachment.pull-right
= link_to note.attachment.secure_url, target: "_blank" do
%i.icon-paper-clip
......
......@@ -3,13 +3,13 @@
.span3
= render "projects/repositories/filter"
.span9
.alert
.alert.alert-info
%p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}.
%p This ability allows:
%ul
%li keep stable branches secured
%li forced code review before merge to protected branches
%p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"}
%p Read more about project permissions #{link_to "here", help_permissions_path, class: "underlined_link"}
- if can? current_user, :admin_project, @project
= form_for [@project, @protected_branch] do |f|
......@@ -24,31 +24,30 @@
.span3
= f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"})
&nbsp;
= f.submit 'Protect', class: "btn-primary btn"
= f.submit 'Protect', class: "btn-create btn"
- unless @branches.empty?
%table
%thead
%tr
%th Name
%th Last commit
%th
%tbody
- @branches.each do |branch|
%tr
%td
= link_to project_commits_path(@project, branch.name) do
%strong= branch.name
- if @project.root_ref?(branch.name)
%span.label default
%td
- if branch.commit
= link_to project_commit_path(@project, branch.commit.id) do
= truncate branch.commit.id.to_s, length: 10
= time_ago_in_words(branch.commit.committed_date)
ago
- else
(branch was removed from repository)
%td
%h5 Already Protected:
%ul.bordered-list.protected-branches-list
- @branches.each do |branch|
%li
%h4
= link_to project_commits_path(@project, branch.name) do
%strong= branch.name
- if @project.root_ref?(branch.name)
%span.label.label-info default
%span.label.label-success
%i.icon-lock
.pull-right
- if can? current_user, :admin_project, @project
= link_to 'Unprotect', [@project, branch], confirm: 'Branch will be writable for developers. Are you sure?', method: :delete, class: "btn btn-remove btn-small"
- if commit = branch.commit
= link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do
= commit.short_id
%span.light
= gfm escape_once(truncate(commit.title, length: 40))
%span
= time_ago_in_words(commit.committed_date)
ago
- else
(branch was removed from repository)
......@@ -5,5 +5,13 @@
= link_to project_protected_branches_path(@project) do
Protected
%i.icon-lock
= nav_link(path: 'repositories#branches') do
= link_to 'All branches', branches_project_repository_path(@project)
= nav_link(path: 'branches#index') do
= link_to 'All branches', project_branches_path(@project)
%hr
- if can? current_user, :push_code, @project
= link_to new_project_branch_path(@project), class: 'btn btn-create' do
%i.icon-add-sign
New branch
= render "projects/commits/head"
.row
.span3
= render "filter"
.span9
- unless @branches.empty?
%table
%thead
%tr
%th Name
%th Last commit
%th
%tbody
- @branches.each do |branch|
= render "projects/repositories/branch", branch: branch
......@@ -3,12 +3,7 @@
.span3
= render "filter"
.span9
%table
%thead
%tr
%th Name
%th Last commit
%th
%ul.bordered-list
- @activities.each do |update|
= render "branch", branch: update.head
= render "projects/branches/branch", branch: update.head
%h3.page_title
%h3.page-title
- if @service.activated?
%span.cgreen
%i.icon-circle
......@@ -9,7 +9,7 @@
%p= @service.description
.back_link
.back-link
= link_to project_services_path(@project) do
&larr; to services
......
%h3.page_title Services
%br
%h3.page-title Services
%ul.bordered-list
- @services.each do |service|
......
......@@ -7,7 +7,7 @@
.loading.hide
.span3
.light-well
%h3.page_title
%h3.page-title
= @project.name
- if @project.description.present?
%p.light= @project.description
......@@ -38,7 +38,7 @@
%p
= link_to pluralize(@repository.branch_names.count, 'branch'), project_repository_path(@project)
%p
= link_to pluralize(@repository.tag_names.count, 'tag'), tags_project_repository_path(@project)
= link_to pluralize(@repository.tag_names.count, 'tag'), project_tags_path(@project)
- if @project.gitlab_ci?
%hr
......
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
%strong= @snippet.file_name
%span.options
......@@ -7,7 +7,7 @@
- if can?(current_user, :admin_project_snippet, @project) || @snippet.author == current_user
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-tiny", title: 'Edit Snippet'
= link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn btn-tiny", target: "_blank"
.file_content.code
.file-content.code
- unless @snippet.content.empty?
%div{class: user_color_scheme_class}
= raw @snippet.colorize(formatter: :gitlab)
......
%h3.page_title
%h3.page-title
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
%hr
.snippet-form-holder
......@@ -19,10 +19,10 @@
.file-editor
= f.label :file_name, "File"
.input
.file_holder.snippet
.file_title
.file-holder.snippet
.file-title
= f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true
.file_content.code
.file-content.code
%pre#editor= @snippet.content
= f.hidden_field :content, class: 'snippet-file-content'
......
%li
.snippet-title
- if snippet.private?
%i.icon-lock.cgreen
- else
%i.icon-globe.cblue
%h4.snippet-title
= link_to reliable_snippet_path(snippet) do
%h5.inline
= truncate(snippet.title, length: 60)
%span.cgray
= truncate(snippet.title, length: 60)
%span.cgray.monospace.tiny.pull-right
= snippet.file_name
%small.pull-right.cgray
......@@ -17,9 +12,10 @@
- else
Never
.snippet-info.prepend-left-20
.snippet-info
= "##{snippet.id}"
%span.light
%span
by
= image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16"
= snippet.author_name
%span.light #{time_ago_in_words(snippet.created_at)} ago
%h3.page_title
%h3.page-title
Snippets
%small share code pastes with others out of git repository
......
%h3.page_title
%i.icon-lock.cgreen
%h3.page-title
= @snippet.title
%small.pull-right
......@@ -8,6 +7,5 @@
by
= image_tag gravatar_icon(@snippet.author_email), class: "avatar avatar-inline s16"
= @snippet.author_name
%br
%div= render 'projects/snippets/blob'
%div#notes= render "projects/notes/notes_with_form"
= render "projects/commits/head"
- if can? current_user, :push_code, @project
.pull-right
= link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do
%i.icon-add-sign
New tag
%p
Tags give ability to mark specific points in history as being important
%hr
- unless @tags.empty?
%ul.bordered-list
- @tags.each do |tag|
- commit = Commit.new(Gitlab::Git::Commit.new(tag.commit))
%li
%h5
%h4
= link_to project_commits_path(@project, tag.name), class: "" do
%i.icon-tag
= tag.name
%small
= truncate(tag.message || '', length: 70)
.pull-right
%span.light
%small.cdark
%i.icon-calendar
= time_ago_in_words(commit.committed_date)
ago
%div.prepend-left-20
%p.prepend-left-20
= link_to commit.short_id(8), project_commit_path(@project, commit), class: "monospace"
&ndash;
= link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "cdark"
- if can? current_user, :download_code, @project
.pull-right
= link_to archive_project_repository_path(@project, ref: tag.name) do
%span.pull-right
- if can? current_user, :download_code, @project
= link_to archive_project_repository_path(@project, ref: tag.name), class: 'btn grouped btn-small' do
%i.icon-download-alt
Download
- if can?(current_user, :admin_project, @project)
= link_to project_tag_path(@project, tag.name), class: 'btn btn-small remove-row', method: :delete, confirm: 'Removed tag cannot be restored. Are you sure?', remote: true do
%i.icon-trash
= paginate @tags, theme: 'gitlab'
- else
%h3.nothing_here_message
......
%h3.page-title
%i.icon-code-fork
New tag
= form_tag project_tags_path, method: :post do
.control-group
= label_tag :tag_name, 'Name for new tag', class: 'control-label'
.controls
= text_field_tag :tag_name, nil, placeholder: 'v3.0.1', required: true, tabindex: 1
.control-group
= label_tag :ref, 'Create from', class: 'control-label'
.controls
= text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2
.light Branch name or commit SHA
.form-actions
= submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
:javascript
var availableTags = #{@project.repository.ref_names.to_json};
$("#ref").autocomplete({
source: availableTags,
minLength: 1
});
%h3.page_title
%h3.page-title
= "New Team member(s)"
%hr
= form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project) do |f|
-if @user_project_relation.errors.any?
.alert.alert-error
......
.ui-box
%h5.title
.title
%strong #{@group.name} Group
members (#{@group.users_groups.count})
.pull-right
= link_to people_group_path(@group), class: 'btn btn-small' do
= link_to members_group_path(@group), class: 'btn btn-small' do
%i.icon-edit
%ul.well-list
- @group.users_groups.order('group_access DESC').each do |member|
......
.team-table
- can_admin_project = (can? current_user, :admin_project, @project)
.ui-box
%h5.title
.title
%strong #{@project.name} Project
members (#{members.count})
%ul.well-list
......
%h3.page_title
%h3.page-title
= "Import team from another project"
%hr
%p.slead
......
%h3.page_title
%h3.page-title
Users with access to this project
- if can? current_user, :admin_team_member, @project
......
.file_holder#README
.file_title
.file-holder#README
.file-title
%i.icon-file
= readme.name
.file_content.wiki
.file-content.wiki
- if gitlab_markdown?(readme.name)
= preserve do
= markdown(readme.data)
......
......@@ -8,7 +8,7 @@
.ui-box.ui-box-show
.ui-box-head
%h3.page_title
%h3.page-title
.edit-wiki-header
= @wiki.title.titleize
= f.hidden_field :title, value: @wiki.title
......
%div#modal-new-wiki.modal.hide
.modal-header
%a.close{href: "#"} ×
%h3.page_title New Wiki Page
%h3.page-title New Wiki Page
.modal-body
= label_tag :new_wiki_path do
%span Page slug
......
= render 'nav'
%h3.page_title
%h3.page-title
Editing page
= render 'main_links'
= render 'form'
......
%h3.page_title Empty page
%h3.page-title Empty page
%hr
.error_message
You are not allowed to create wiki pages
= render 'nav'
%h3.page_title
%h3.page-title
Git Access
%strong= @gollum_wiki.path_with_namespace
= render 'main_links'
......
= render 'nav'
%h3.page_title
%h3.page-title
%span.light History for
= @wiki.title.titleize
= render 'main_links'
......
= render 'nav'
%h3.page_title
%h3.page-title
All Pages
= render 'main_links'
%br
......
= render 'nav'
%h3.page_title
%h3.page-title
= @wiki.title.titleize
= render 'main_links'
%br
- if @wiki.historical?
.warning_message
This is an old version of this page.
You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}.
.file_holder
.file_content.wiki
.file-holder
.file-content.wiki
= preserve do
= render_wiki_content(@wiki)
......
.row
.span6
%h3.page_title
%h3.page-title
Projects (#{@projects.total_count})
%small with read-only access
.span6
......@@ -17,7 +17,7 @@
%ul.unstyled
- @projects.each do |project|
%li.clearfix
%h5
%div
%i.icon-share
- if current_user
= link_to_project project
......@@ -25,7 +25,7 @@
= project.name_with_namespace
.pull-right
%pre.dark.tiny git clone #{project.http_url_to_repo}
%p.description
%div.description
= project.description
- unless @projects.present?
%h3.nothing_here_message No public projects
......
%li
.file_holder
.file_title
.file-holder
.file-title
= link_to project_blob_path(@project, tree_join(blob.ref, blob.filename), :anchor => "L" + blob.startline.to_s) do
%i.icon-file
%strong
= blob.filename
.file_content.code.term
.file-content.code.term
%div{class: user_color_scheme_class}
= raw blob.colorize( formatter: :gitlab, options: { first_line_number: blob.startline } )
......@@ -2,7 +2,7 @@
- @merge_requests.group_by(&:project).each do |group|
.ui-box
- project = group[0]
%h5.title
.title
= link_to_project project
%ul.well-list.mr-list
- group[1].each do |merge_request|
......
.file_holder
.file_title
.file-holder
.file-title
%i.icon-file
%strong= @snippet.file_name
%span.options
......@@ -8,7 +8,7 @@
= link_to "Edit", edit_snippet_path(@snippet), class: "btn btn-tiny", title: 'Edit Snippet'
= link_to "Delete", snippet_path(@snippet), method: :delete, confirm: "Are you sure?", class: "btn btn-tiny", title: 'Delete Snippet'
= link_to "Raw", raw_snippet_path(@snippet), class: "btn btn-tiny", target: "_blank"
.file_content.code
.file-content.code
- unless @snippet.content.empty?
%div{class: user_color_scheme_class}
= raw @snippet.colorize(formatter: :gitlab)
......
%h3.page_title
%h3.page-title
= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
%hr
.snippet-form-holder
......@@ -15,22 +15,23 @@
.clearfix
= f.label "Private?"
.input= f.check_box :private, {class: ''}
.clearfix
= f.label "Lifetime"
.input= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'}
.clearfix
.file-editor
= f.label :file_name, "File"
.input
.file_holder.snippet
.file_title
.file-holder.snippet
.file-title
= f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true
.file_content.code
.file-content.code
%pre#editor= @snippet.content
= f.hidden_field :content, class: 'snippet-file-content'
.form-actions
= f.submit 'Save', class: "btn-save btn"
- if @snippet.new_record?
= f.submit 'Create snippet', class: "btn-create btn"
- else
= f.submit 'Save', class: "btn-save btn"
= link_to "Cancel", snippets_path(@project), class: " btn"
- unless @snippet.new_record?
.pull-right= link_to 'Destroy', snippet_path(@snippet), confirm: 'Removed snippet cannot be restored! Are you sure?', method: :delete, class: "btn pull-right danger delete-snippet", id: "destroy_snippet_#{@snippet.id}"
......
%li
.snippet-title
- if snippet.private?
= private_icon
- else
= public_icon
%h4.snippet-title
= link_to reliable_snippet_path(snippet) do
%h5.inline
= truncate(snippet.title, length: 60)
%span.cgray
= truncate(snippet.title, length: 60)
- if snippet.private?
%span.label.label-success
%i.icon-lock
private
%span.cgray.monospace.tiny.pull-right
= snippet.file_name
%small.pull-right.cgray
- if snippet.project_id?
= link_to snippet.project.name_with_namespace, project_path(snippet.project)
%span
\|
Expires:
- if snippet.expires_at
= snippet.expires_at.to_date.to_s(:short)
- else
Never
.snippet-info.prepend-left-20
.snippet-info
= "##{snippet.id}"
%span.light
%span
by
= image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: ''
= snippet.author_name
= link_to user_snippets_path(snippet.author) do
= image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: ''
= snippet.author_name
%span.light #{time_ago_in_words(snippet.created_at)} ago
......@@ -4,4 +4,4 @@
%li
%h3.nothing_here_message Nothing here.
= paginate @snippets
= paginate @snippets, theme: 'gitlab'
%h3.page_title
%h3.page-title
My Snippets
%small share code pastes with others out of git repository
.pull-right
......@@ -19,6 +19,6 @@
= nav_tab :scope, 'public' do
= link_to "Public", user_snippets_path(@user, scope: 'public')
.span9
.span9.my-snippets
= render 'snippets'
%h3.page_title
%h3.page-title
Public snippets
%small share code pastes with others out of git repository
......@@ -9,7 +9,5 @@
My snippets
%hr
.row
.span12
= render 'snippets'
= render 'snippets'
%h3.page_title
%h3.page-title
= @snippet.title
- if @snippet.private?
%i{:class => "icon-lock cgreen has_bottom_tooltip", "data-original-title" => "Private snippet"}
- else
%i{:class => "icon-globe cblue has_bottom_tooltip", "data-original-title" => "Public snippet"}
%span.label.label-success
%i.icon-lock
private
= @snippet.title
.pull-right
= link_to new_snippet_path, class: "btn btn-small add_new grouped btn-primary", title: "New Snippet" do
Add new snippet
%small.pull-right
.append-bottom-20
.pull-right
= "##{@snippet.id}"
%span.light
by
= image_tag gravatar_icon(@snippet.author_email), class: "avatar avatar-inline s16"
= @snippet.author_name
%br
= link_to user_snippets_path(@snippet.author) do
= image_tag gravatar_icon(@snippet.author_email), class: "avatar avatar-inline s16"
= @snippet.author_name
.back-link
- if @snippet.author == current_user
= link_to user_snippets_path(current_user) do
&larr; my snippets
- else
= link_to snippets_path do
&larr; discover snippets
%div= render 'blob'
%h3.page_title
%h3.page-title
= image_tag gravatar_icon(@user.email), class: "avatar s24"
= @user.name
%span
\/
Snippets
%small share code pastes with others out of git repository
= link_to new_snippet_path, class: "btn btn-small add_new pull-right", title: "New Snippet" do
Add new snippet
......
.ui-box
%h5.title
.title
Profile
%ul.well-list
%li
......
.ui-box
%h5.title Projects
.title Projects
%ul.well-list
- @projects.each do |project|
%li
......
.row
.span8
%h3.page_title
%h3.page-title
= image_tag gravatar_icon(@user.email, 90), class: "avatar s90", alt: ''
= @user.name
- if @user == current_user
......
......@@ -13,6 +13,7 @@
- else
= member.human_access
- if show_controls && user != current_user && user != @group.owner
- if show_controls && user != @group.owner && user != current_user
= link_to group_users_group_path(@group, member), confirm: remove_user_from_group_message(@group, user), method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do
%i.icon-minus.icon-white
......@@ -97,6 +97,7 @@ production: &base
method: 'ssl' # "ssl" or "plain"
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
allow_username_or_email_login: true
## OmniAuth settings
omniauth:
......
......@@ -37,6 +37,8 @@ end
# Default settings
Settings['ldap'] ||= Settingslogic.new({})
Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil?
Settings.ldap['allow_username_or_email_login'] = false if Settings.ldap['allow_username_or_email_login'].nil?
Settings['omniauth'] ||= Settingslogic.new({})
Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil?
......
......@@ -206,6 +206,12 @@ Devise.setup do |config|
# end
if Gitlab.config.ldap.enabled
if Gitlab.config.ldap.allow_username_or_email_login
email_stripping_proc = ->(name) {name.gsub(/@.*$/,'')}
else
email_stripping_proc = ->(name) {name}
end
config.omniauth :ldap,
host: Gitlab.config.ldap['host'],
base: Gitlab.config.ldap['base'],
......@@ -213,7 +219,8 @@ Devise.setup do |config|
port: Gitlab.config.ldap['port'],
method: Gitlab.config.ldap['method'],
bind_dn: Gitlab.config.ldap['bind_dn'],
password: Gitlab.config.ldap['password']
password: Gitlab.config.ldap['password'],
name_proc: email_stripping_proc
end
Gitlab.config.omniauth.providers.each do |provider|
......
......@@ -116,6 +116,11 @@ Gitlab::Application.routes.draw do
resource :notifications, only: [:show, :update]
resource :password, only: [:new, :create]
resources :keys
resources :groups, only: [:index] do
member do
delete :leave
end
end
end
end
......@@ -141,7 +146,7 @@ Gitlab::Application.routes.draw do
member do
get :issues
get :merge_requests
get :people
get :members
end
resources :users_groups, only: [:create, :update, :destroy]
......@@ -200,8 +205,6 @@ Gitlab::Application.routes.draw do
resource :repository, only: [:show] do
member do
get "branches"
get "tags"
get "stats"
get "archive"
end
......@@ -220,6 +223,8 @@ Gitlab::Application.routes.draw do
end
end
resources :tags, only: [:index, :new, :create, :destroy]
resources :branches, only: [:index, :new, :create, :destroy]
resources :protected_branches, only: [:index, :create, :destroy]
resources :refs, only: [] do
......
ActiveRecord::Base.observers.disable :all
Gitlab::Seeder.quiet do
contents = [
`curl https://gist.github.com/randx/4275756/raw/da2f262920c96d1a970d48bf2e99147954b1f4bd/glus1204.sh`,
`curl https://gist.github.com/randx/3754594/raw/11026a295e6ef3a151c635707a3e1e8e15fc4725/gitlab_setup.sh `,
`curl https://gist.github.com/randx/3065552/raw/29fbd09f4605a5ea22a5a9095e35fd1938dea4d6/gistfile1.sh`,
]
(1..50).each do |i|
user = User.all.sample
PersonalSnippet.seed(:id, [{
id: i,
author_id: user.id,
title: Faker::Lorem.sentence(3),
file_name: Faker::Internet.domain_word + '.sh',
private: [true, false].sample,
content: contents.sample,
}])
print('.')
end
end
class IncreaseSnippetTextColumnSize < ActiveRecord::Migration
def up
# MYSQL LARGETEXT for snippet
change_column :snippets, :content, :text, :limit => 4294967295
end
def down
end
end
......@@ -208,14 +208,14 @@ ActiveRecord::Schema.define(:version => 20130624162710) do
create_table "snippets", :force => true do |t|
t.string "title"
t.text "content"
t.integer "author_id", :null => false
t.text "content", :limit => 2147483647
t.integer "author_id", :null => false
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "file_name"
t.datetime "expires_at"
t.boolean "private", :default => true, :null => false
t.boolean "private", :default => true, :null => false
t.string "type"
end
......
......@@ -69,18 +69,18 @@ When listing resources you can pass the following parameters:
## Contents
+ [Users](api/users.md)
+ [Session](api/session.md)
+ [Projects](api/projects.md)
+ [Project Snippets](api/project_snippets.md)
+ [Repositories](api/repositories.md)
+ [Issues](api/issues.md)
+ [Milestones](api/milestones.md)
+ [Notes](api/notes.md)
+ [Deploy Keys](api/deploy_keys.md)
+ [System Hooks](api/system_hooks.md)
+ [Groups](api/groups.md)
+ [User Teams](api/user_teams.md)
+ [Users](users.md)
+ [Session](session.md)
+ [Projects](projects.md)
+ [Project Snippets](project_snippets.md)
+ [Repositories](repositories.md)
+ [Issues](issues.md)
+ [Milestones](milestones.md)
+ [Notes](notes.md)
+ [Deploy Keys](deploy_keys.md)
+ [System Hooks](system_hooks.md)
+ [Groups](groups.md)
+ [User Teams](user_teams.md)
## Clients
......
......@@ -53,6 +53,7 @@ GET /projects
"merge_requests_enabled": true,
"wall_enabled": true,
"wiki_enabled": true,
"snippets_enabled": true,
"created_at": "2012-05-30T12:49:20Z",
"last_activity_at": "2012-05-23T08:05:02Z"
}
......@@ -95,6 +96,7 @@ Parameters:
"merge_requests_enabled": true,
"wall_enabled": true,
"wiki_enabled": true,
"snippets_enabled": true,
"created_at": "2012-05-30T12:49:20Z",
"last_activity_at": "2012-05-23T08:05:02Z"
}
......@@ -182,10 +184,12 @@ Parameters:
+ `name` (required) - new project name
+ `description` (optional) - short project description
+ `default_branch` (optional) - 'master' by default
+ `issues_enabled` (optional) - enabled by default
+ `wall_enabled` (optional) - enabled by default
+ `merge_requests_enabled` (optional) - enabled by default
+ `wiki_enabled` (optional) - enabled by default
+ `issues_enabled` (optional)
+ `wall_enabled` (optional)
+ `merge_requests_enabled` (optional)
+ `wiki_enabled` (optional)
+ `snippets_enabled` (optional)
+ `public` (optional)
**Project access levels**
......@@ -213,10 +217,12 @@ Parameters:
+ `name` (required) - new project name
+ `description` (optional) - short project description
+ `default_branch` (optional) - 'master' by default
+ `issues_enabled` (optional) - enabled by default
+ `wall_enabled` (optional) - enabled by default
+ `merge_requests_enabled` (optional) - enabled by default
+ `wiki_enabled` (optional) - enabled by default
+ `issues_enabled` (optional)
+ `wall_enabled` (optional)
+ `merge_requests_enabled` (optional)
+ `wiki_enabled` (optional)
+ `snippets_enabled` (optional)
+ `public` (optional)
......@@ -477,4 +483,4 @@ DELETE /projects/:id/fork
Parameter:
+ `id` (required) - The ID of the project
\ No newline at end of file
+ `id` (required) - The ID of the project
......@@ -6,10 +6,13 @@ POST /session
Parameters:
+ `email` (required) - The email of user
+ `login` (required) - The login of user
+ `email` (required if login missing) - The email of user
+ `password` (required) - Valid password
__You can login with both GitLab and LDAP credentials now__
```json
{
"id": 1,
......
......@@ -280,8 +280,8 @@ However there are still a few steps left.
# 7. Nginx
**Note:**
If you can't or don't want to use Nginx as your web server, have a look at the
[`Advanced Setup Tips`](./installation.md#advanced-setup-tips) section.
Nginx is the officially supported web server for GitLab. If you cannot or do not want to use Nginx as your web server, have a look at the
[GitLab recipes](https://github.com/gitlabhq/gitlab-recipes).
## Installation
sudo apt-get install -y nginx
......
# From 5.3 to 5.4
### 0. Backup
It's useful to make a backup just in case things go south:
(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version)
```bash
cd /home/git/gitlab
sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create
```
### 1. Stop server
sudo service gitlab stop
### 2. Get latest code
```bash
cd /home/git/gitlab
sudo -u git -H git fetch
sudo -u git -H git checkout 5-4-stable
```
### 3. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
# MySQL
sudo -u git -H bundle install --without development test postgres --deployment
#PostgreSQL
sudo -u git -H bundle install --without development test mysql --deployment
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
```
### 4. Update config files
* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/gitlab.yml.example but with your settings.
* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/puma.rb.example but with your settings.
### 5. Update Init script
```bash
sudo rm /etc/init.d/gitlab
sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-4-stable/lib/support/init.d/gitlab
sudo chmod +x /etc/init.d/gitlab
```
### 6. Start application
sudo service gitlab start
sudo service nginx restart
### 7. Check application status
Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
To make sure you didn't miss anything run a more thorough check with:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
If all items are green, then congratulations upgrade complete!
## Things went south? Revert to previous version (5.3)
### 1. Revert the code to the previous version
Follow the [`upgrade guide from 5.2 to 5.3`](5.2-to-5.3.md), except for the database migration
(The backup is already migrated to the previous version)
### 2. Restore from the backup:
```bash
cd /home/git/gitlab
sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:restore
```
......@@ -36,7 +36,7 @@ sudo -u git -H bundle install --without development test mysql --deployment
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
sudo -u git -H bundle exec rake migrate_groups RAILS_ENV=production
sudo -u git -H bundle exec rake migrate_global_projects RAILS_ENV=production
sudo -u git -H bundle exec rake migrate_global_keys RAILS_ENV=production
sudo -u git -H bundle exec rake migrate_keys RAILS_ENV=production
```
......
......@@ -22,7 +22,7 @@ Feature: Groups
@javascript
Scenario: I should add user to projects in Group
Given I have new user "John"
When I visit group people page
When I visit group members page
And I select user "John" from list with role "Reporter"
Then I should see user "John" in team list
......
......@@ -22,7 +22,7 @@ class ProjectBrowseBranches < Spinach::FeatureSteps
end
Then 'I should see "Shop" protected branches list' do
within "table" do
within ".protected-branches-list" do
page.should have_content "stable"
page.should_not have_content "master"
end
......
......@@ -48,7 +48,7 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
page.should have_selector('ul.breadcrumb span.divider', count: 3)
page.should have_selector('ul.breadcrumb a', count: 4)
find('ul.breadcrumb li:first a')['href'].should match(/#{@project.path_with_namespace}\/commits\/master\z/)
find('ul.breadcrumb li:nth-child(2) a')['href'].should match(/#{@project.path_with_namespace}\/commits\/master\z/)
find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z})
end
......
......@@ -3,8 +3,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
include SharedProject
Then 'page should have network graph' do
page.should have_content "Project Network Graph"
page.should have_selector ".graph"
page.should have_selector ".network-graph"
end
When 'I visit project "Shop" network page' do
......@@ -24,7 +23,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
end
And 'page should have "master" on graph' do
within '.graph' do
within '.network-graph' do
page.should have_content 'master'
end
end
......@@ -50,13 +49,13 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
end
Then 'page should have content not cotaining "v2.1.0"' do
within '.graph' do
within '.network-graph' do
page.should have_content 'cleaning'
end
end
Then 'page should not have content not cotaining "v2.1.0"' do
within '.graph' do
within '.network-graph' do
page.should_not have_content 'cleaning'
end
end
......@@ -70,7 +69,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
end
And 'page should have "stable" on graph' do
within '.graph' do
within '.network-graph' do
page.should have_content 'stable'
end
end
......@@ -84,7 +83,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
end
And 'page should have "v2.1.0" on graph' do
within '.graph' do
within '.network-graph' do
page.should have_content 'v2.1.0'
end
end
......
......@@ -42,7 +42,7 @@ class ProjectSnippets < Spinach::FeatureSteps
end
And 'I click link "Edit"' do
within ".file_title" do
within ".file-title" do
click_link "Edit"
end
end
......
......@@ -21,8 +21,8 @@ module SharedPaths
visit merge_requests_group_path(current_group)
end
step 'I visit group people page' do
visit people_group_path(current_group)
step 'I visit group members page' do
visit members_group_path(current_group)
end
step 'I visit group settings page' do
......@@ -189,7 +189,7 @@ module SharedPaths
end
step 'I visit project branches page' do
visit branches_project_repository_path(@project)
visit project_branches_path(@project)
end
step 'I visit compare refs page' do
......@@ -217,7 +217,7 @@ module SharedPaths
end
step 'I visit project tags page' do
visit tags_project_repository_path(@project)
visit project_tags_path(@project)
end
step 'I visit project commit page' do
......
......@@ -13,7 +13,7 @@ class SnippetsFeature < Spinach::FeatureSteps
end
And 'I click link "Edit"' do
within ".file_title" do
within ".file-title" do
click_link "Edit"
end
end
......@@ -24,12 +24,11 @@ class SnippetsFeature < Spinach::FeatureSteps
And 'I submit new snippet "Personal snippet three"' do
fill_in "personal_snippet_title", :with => "Personal snippet three"
select "forever", :from => "personal_snippet_expires_at"
fill_in "personal_snippet_file_name", :with => "my_snippet.rb"
within('.file-editor') do
find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of snippet three'
end
click_button "Save"
click_button "Create snippet"
end
Then 'I should see snippet "Personal snippet three"' do
......
......@@ -36,7 +36,7 @@ module API
expose :owner, using: Entities::UserBasic
expose :name, :name_with_namespace
expose :path, :path_with_namespace
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at, :last_activity_at
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at, :public
expose :namespace
expose :forked_from_project, using: Entities::ForkedFromProject, :if => lambda{ | project, options | project.forked? }
end
......
......@@ -61,11 +61,13 @@ module API
# name (required) - name for new project
# description (optional) - short project description
# default_branch (optional) - 'master' by default
# issues_enabled (optional) - enabled by default
# wall_enabled (optional) - enabled by default
# merge_requests_enabled (optional) - enabled by default
# wiki_enabled (optional) - enabled by default
# issues_enabled (optional)
# wall_enabled (optional)
# merge_requests_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
# namespace_id (optional) - defaults to user namespace
# public (optional) - false by default
# Example Request
# POST /projects
post do
......@@ -77,7 +79,9 @@ module API
:wall_enabled,
:merge_requests_enabled,
:wiki_enabled,
:namespace_id]
:snippets_enabled,
:namespace_id,
:public]
@project = ::Projects::CreateContext.new(current_user, attrs).execute
if @project.saved?
present @project, with: Entities::Project
......@@ -96,10 +100,12 @@ module API
# name (required) - name for new project
# description (optional) - short project description
# default_branch (optional) - 'master' by default
# issues_enabled (optional) - enabled by default
# wall_enabled (optional) - enabled by default
# merge_requests_enabled (optional) - enabled by default
# wiki_enabled (optional) - enabled by default
# issues_enabled (optional)
# wall_enabled (optional)
# merge_requests_enabled (optional)
# wiki_enabled (optional)
# snippets_enabled (optional)
# public (optional)
# Example Request
# POST /projects/user/:user_id
post "user/:user_id" do
......@@ -111,7 +117,9 @@ module API
:issues_enabled,
:wall_enabled,
:merge_requests_enabled,
:wiki_enabled]
:wiki_enabled,
:snippets_enabled,
:public]
@project = ::Projects::CreateContext.new(user, attrs).execute
if @project.saved?
present @project, with: Entities::Project
......
......@@ -3,18 +3,19 @@ module API
class Session < Grape::API
# Login to get token
#
# Parameters:
# login (*required) - user login
# email (*required) - user email
# password (required) - user password
#
# Example Request:
# POST /session
post "/session" do
resource = User.find_for_database_authentication(email: params[:email])
return unauthorized! unless resource
auth = Gitlab::Auth.new
user = auth.find(params[:email] || params[:login], params[:password])
if resource.valid_password?(params[:password])
present resource, with: Entities::UserLogin
else
unauthorized!
end
return unauthorized! unless user
present user, with: Entities::UserLogin
end
end
end
......@@ -26,7 +26,7 @@ module Backup
system("mysql #{mysql_args} #{config['database']} < #{db_file_name}")
when "postgresql" then
pg_env
system("pg_restore #{config['database']} #{db_file_name}")
system("psql #{config['database']} -f #{db_file_name}")
end
end
......
module Gitlab
class Auth
def find(login, password)
user = User.find_by_email(login) || User.find_by_username(login)
if user.nil? || user.ldap_user?
# Second chance - try LDAP authentication
return nil unless ldap_conf.enabled
ldap_auth(login, password)
else
user if user.valid_password?(password)
end
end
def find_for_ldap_auth(auth, signed_in_resource = nil)
uid = auth.info.uid
provider = auth.provider
......
......@@ -64,19 +64,8 @@ module Grack
end
def authenticate_user(login, password)
user = User.find_by_email(login) || User.find_by_username(login)
# If the provided login was not a known email or username
# then user is nil
if user.nil? || user.ldap_user?
# Second chance - try LDAP authentication
return nil unless ldap_conf.enabled
auth = Gitlab::Auth.new
auth.ldap_auth(login, password)
else
return user if user.valid_password?(password)
end
auth = Gitlab::Auth.new
auth.find(login, password)
end
def authorize_request(service)
......
......@@ -3,7 +3,7 @@ module Grack
def project_by_path(path)
if m = /^\/([\w\.\/-]+)\.git/.match(path).to_a
path_with_namespace = m.last
path_with_namespace.gsub!(/.wiki$/, '')
path_with_namespace.gsub!(/\.wiki$/, '')
Project.find_with_namespace(path_with_namespace)
end
......
......@@ -71,6 +71,56 @@ module Gitlab
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-project", "#{name}.git"
end
# Add repository branch from passed ref
#
# path - project path with namespace
# branch_name - new branch name
# ref - HEAD for new branch
#
# Ex.
# add_branch("gitlab/gitlab-ci", "4-0-stable", "master")
#
def add_branch(path, branch_name, ref)
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-branch", "#{path}.git", branch_name, ref
end
# Remove repository branch
#
# path - project path with namespace
# branch_name - branch name to remove
#
# Ex.
# rm_branch("gitlab/gitlab-ci", "4-0-stable")
#
def rm_branch(path, branch_name)
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-branch", "#{path}.git", branch_name
end
# Add repository tag from passed ref
#
# path - project path with namespace
# tag_name - new tag name
# ref - HEAD for new tag
#
# Ex.
# add_tag("gitlab/gitlab-ci", "v4.0", "master")
#
def add_tag(path, tag_name, ref)
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "create-tag", "#{path}.git", tag_name, ref
end
# Remove repository tag
#
# path - project path with namespace
# tag_name - tag name to remove
#
# Ex.
# rm_tag("gitlab/gitlab-ci", "v4.0")
#
def rm_tag(path, tag_name)
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-projects", "rm-tag", "#{path}.git", tag_name
end
# Add new key to gitlab-shell
#
# Ex.
......@@ -89,6 +139,15 @@ module Gitlab
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "rm-key", key_id, key_content
end
# Remove all ssh keys from gitlab shell
#
# Ex.
# remmove_all_keys
#
def remove_all_keys
system "#{gitlab_shell_user_home}/gitlab-shell/bin/gitlab-keys", "clear"
end
# Add empty directory for storing repositories
#
# Ex.
......
......@@ -20,6 +20,7 @@ APP_USER="git"
DAEMON_OPTS="-C $APP_ROOT/config/puma.rb"
PID_PATH="$APP_ROOT/tmp/pids"
SOCKET_PATH="$APP_ROOT/tmp/sockets"
SOCKET_FILE="$SOCKET_PATH/gitlab.socket"
WEB_SERVER_PID="$PID_PATH/puma.pid"
SIDEKIQ_PID="$PID_PATH/sidekiq.pid"
STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop"
......@@ -51,7 +52,7 @@ start() {
exit 1
else
if [ `whoami` = root ]; then
execute "rm -f $SOCKET_PATH/gitlab.socket"
! [ -e $SOCKET_FILE ] || execute "rm $SOCKET_FILE"
execute "RAILS_ENV=production bundle exec puma $DAEMON_OPTS"
execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"
echo "$DESC started"
......@@ -65,12 +66,13 @@ stop() {
if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
## Program is running, stop it.
kill -QUIT `cat $WEB_SERVER_PID`
! [ -e $SOCKET_FILE ] || execute "rm $SOCKET_FILE"
execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &"
rm "$WEB_SERVER_PID" >> /dev/null
echo "$DESC stopped"
else
## Program is not running, exit with error.
echo "Error! $DESC not started!"
echo "Error! $DESC is not started!"
exit 1
fi
}
......@@ -81,7 +83,7 @@ restart() {
if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
echo "Restarting $DESC..."
kill -USR2 `cat $WEB_SERVER_PID`
execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &"
execute "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1"
if [ `whoami` = root ]; then
execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"
fi
......
......@@ -657,7 +657,7 @@ namespace :gitlab do
end
def check_gitlab_shell
required_version = Gitlab::VersionInfo.new(1, 4, 0)
required_version = Gitlab::VersionInfo.new(1, 7, 0)
current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
print "GitLab Shell version >= #{required_version} ? ... "
......
......@@ -29,8 +29,6 @@ namespace :gitlab do
# Skip if group or user
next if namespaces.include?(name)
next if name == 'gitolite-admin'
puts "Processing #{repo_path}".yellow
project = Project.find_with_namespace(path)
......
......@@ -25,15 +25,14 @@ namespace :gitlab do
def setup
warn_user_is_not_gitlab
gitlab_shell_authorized_keys = File.join(File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}"),'.ssh/authorized_keys')
unless ENV['force'] == 'yes'
puts "This will rebuild an authorized_keys file."
puts "You will lose any data stored in #{gitlab_shell_authorized_keys}."
puts "You will lose any data stored in authorized_keys file."
ask_to_continue
puts ""
end
system("echo '# Managed by gitlab-shell' > #{gitlab_shell_authorized_keys}")
Gitlab::Shell.new.remove_all_keys
Key.find_each(batch_size: 1000) do |key|
if Gitlab::Shell.new.add_key(key.shell_id, key.key)
......
......@@ -41,7 +41,7 @@ describe "GitLab Flavored Markdown" do
end
it "should render title in repositories#branches" do
visit branches_project_repository_path(project)
visit project_branches_path(project)
page.should have_link("##{issue.id}")
end
......
......@@ -66,12 +66,6 @@ describe "On a merge request", js: true do
within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) }
within(".js-main-target-form") { should have_css(".js-note-text", visible: true) }
end
it "should be removable" do
find('.note').hover
find(".js-note-delete").click
should_not have_css(".note")
end
end
describe "when editing a note", js: true do
......
......@@ -187,7 +187,7 @@ describe "Application access" do
end
describe "GET /project_code/repository/branches" do
subject { branches_project_repository_path(project) }
subject { project_branches_path(project) }
before do
# Speed increase
......@@ -203,7 +203,7 @@ describe "Application access" do
end
describe "GET /project_code/repository/tags" do
subject { tags_project_repository_path(project) }
subject { project_tags_path(project) }
before do
# Speed increase
......@@ -429,7 +429,7 @@ describe "Application access" do
end
describe "GET /project_code/repository/branches" do
subject { branches_project_repository_path(project) }
subject { project_branches_path(project) }
before do
# Speed increase
......@@ -445,7 +445,7 @@ describe "Application access" do
end
describe "GET /project_code/repository/tags" do
subject { tags_project_repository_path(project) }
subject { project_tags_path(project) }
before do
# Speed increase
......
......@@ -42,17 +42,22 @@ describe Key do
build(:key, user: user).should be_valid
end
it "does not accepts the key twice" do
it "does not accept the exact same key twice" do
create(:key, user: user)
build(:key, user: user).should_not be_valid
end
it "does not accept a duplicate key with a different comment" do
create(:key, user: user)
duplicate = build(:key, user: user)
duplicate.key << ' extra comment'
duplicate.should_not be_valid
end
end
context "validate it is a fingerprintable key" do
let(:user) { create(:user) }
it "accepts the fingerprintable key" do
build(:key, user: user).should be_valid
build(:key).should be_valid
end
it "rejects the unfingerprintable key (contains space in middle)" do
......
......@@ -104,6 +104,21 @@ describe API::API do
json_response[k.to_s].should == v
end
end
it "should set a project as public" do
project = attributes_for(:project, { public: true })
post api("/projects", user), project
json_response['public'].should be_true
end
it "should set a project as private" do
project = attributes_for(:project, { public: false })
post api("/projects", user), project
json_response['public'].should be_false
end
end
describe "POST /projects/user/:id" do
......@@ -144,6 +159,21 @@ describe API::API do
json_response[k.to_s].should == v
end
end
it "should set a project as public" do
project = attributes_for(:project, { public: true })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_true
end
it "should set a project as private" do
project = attributes_for(:project, { public: false })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
end
end
describe "GET /projects/:id" do
......
......@@ -126,14 +126,6 @@ end
# archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive
# edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit
describe Projects::RepositoriesController, "routing" do
it "to #branches" do
get("/gitlabhq/repository/branches").should route_to('projects/repositories#branches', project_id: 'gitlabhq')
end
it "to #tags" do
get("/gitlabhq/repository/tags").should route_to('projects/repositories#tags', project_id: 'gitlabhq')
end
it "to #archive" do
get("/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlabhq')
end
......@@ -143,6 +135,19 @@ describe Projects::RepositoriesController, "routing" do
end
end
describe Projects::BranchesController, "routing" do
it "to #branches" do
get("/gitlabhq/branches").should route_to('projects/branches#index', project_id: 'gitlabhq')
end
end
describe Projects::TagsController, "routing" do
it "to #tags" do
get("/gitlabhq/tags").should route_to('projects/tags#index', project_id: 'gitlabhq')
end
end
# project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index
# POST /:project_id/deploy_keys(.:format) deploy_keys#create
# new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment