Merge branch 'master' of git://github.com/gitlabhq/gitlabhq

This commit is contained in:
Florian Unglaub 2012-08-24 15:25:52 +02:00
commit 48443d20ca
114 changed files with 1524 additions and 1674 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -7,8 +7,6 @@
//= require jquery
//= require jquery.ui.all
//= require jquery_ujs
//= require jquery.ui.selectmenu
//= require jquery.tagify
//= require jquery.cookie
//= require jquery.endless-scroll
//= require jquery.highlight
@ -74,7 +72,7 @@ $(document).ready(function(){
* Note markdown preview
*
*/
$('#preview-link').on('click', function(e) {
$(document).on('click', '#preview-link', function(e) {
$('#preview-note').text('Loading...');
var previewLinkText = ($(this).text() == 'Preview' ? 'Edit' : 'Preview');

View file

@ -112,6 +112,7 @@ var MergeRequest = {
already_cannot_be_merged:
function(){
$(".automerge_widget").hide();
$(".merge_in_progress").hide();
$(".automerge_widget.already_cannot_be_merged").show();
}
}

View file

@ -3,8 +3,7 @@
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require jquery.ui.all
*= require jquery-ui/jquery.ui.selectmenu
*= require jquery-ui/jquery.tagify
*= require jquery.ui.aristo
*= require chosen
*= require_self
*= require main

View file

@ -735,3 +735,11 @@ li.note {
font-size: 12px;
}
}
.error_message {
@extend .cred;
border-bottom: 1px solid #D21;
padding-bottom:20px;
text-align:center;
margin-bottom:10px;
}

View file

@ -1,6 +1,16 @@
body {
margin-bottom:20px;
}
pre {
font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
&.dark {
background: #333;
color:#f5f5f5;
}
}
a {
outline: none;
color: $link_color;
@ -325,16 +335,20 @@ img.avatar {
float:left;
margin-right:15px;
width:40px;
border:2px solid #ddd;
border:1px solid #ddd;
padding:1px;
&.s16 {
width:16px;
height:16px;
}
&.s24 {
width:24px;
height:24px;
}
&.s32 {
width:32px;
height:32px;
}
}

View file

@ -1,33 +0,0 @@
/**
* JQUERY UI datepicker
*
*/
.ui-datepicker {
border-color:#eee;
padding:20px;
.ui-state-default {
background:#f1f1f1;
padding:5px;
}
.ui-state-active {
background:#fff;
}
}
/**
* JQUERY UI progressbar
*
*/
.ui-progressbar {
border:1px solid #ddd;
height:6px;
margin:0;
padding:0;
.ui-progressbar-value {
background-color: #62C462;//$blue_link;
margin:0;
}
}

View file

@ -23,6 +23,8 @@ $blue_link: #2fa0bb;
$style_color: #474D57;
$hover: #FDF5D9;
/** GITLAB Fonts **/
@font-face { font-family: Korolev; src: url('korolev-medium-compressed.otf'); }
/** MIXINS **/
@mixin shade {
@ -165,9 +167,3 @@ $hover: #FDF5D9;
*
*/
@import "highlight/dark.scss";
/**
* JQUERY UI ext
*
*/
@import "jquery_ui.scss";

View file

@ -26,23 +26,25 @@ header {
float:left;
position:relative;
top:-5px;
a {
float:left;
h1 {
text-indent:-9999px;
padding-top: 5px;
width:102px;
background: url('logo_text.png') no-repeat 0px -3px;
background: url('logo_dark.png') no-repeat 0px -3px;
float:left;
margin-left:5px;
font-size:20px;
font-size:36px;
line-height:36px;
font-weight:bold;
color:#aaa;
font-weight:normal;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
padding-left:50px;
height:40px;
font-family: 'Korolev', sans-serif;
}
}
.separator {
margin-left:20px;
@ -68,14 +70,16 @@ header {
*
*/
.project_name {
position:relative;
float:left;
margin:0;
margin-right:30px;
font-size:24px;
font-size:36px;
line-height:36px;
font-weight:500;
font-weight:normal;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
font-family: 'Korolev', sans-serif;
}
.fbtn {

View file

@ -27,6 +27,7 @@ body.login-page{
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
margin-bottom:0px;
}
.login-box input.text.bottom{

View file

@ -94,3 +94,8 @@ li.merge_request {
padding-bottom: 2px;
}
}
.merge_in_progress {
@extend .padded;
@extend .append-bottom-10;
}

View file

@ -48,7 +48,7 @@
p { color:$style_color; }
.note-author { color: $style_color;}
.note-title { margin-left:50px; padding-top: 5px;}
.note-title { margin-left:45px; padding-top: 5px;}
.avatar {
margin-top:3px;
}

View file

@ -1,17 +1,18 @@
.projects {
.projects {
@extend .row;
.activities {
}
.side {
.side {
@extend .span4;
@extend .right;
.projects_box {
h5 {
.projects_box {
h5 {
color:$style_color;
font-size:16px;
text-shadow: 0 1px 1px #fff;
padding: 2px 10px;
}
@extend .leftbar;
@extend .ui-box;
@ -19,21 +20,22 @@
}
}
.new_project,
.edit_project {
.project_name_holder {
.new_project,
.edit_project {
.project_name_holder {
input,
label {
label {
font-size:16px;
line-height:20px;
padding:8px;
}
label {
label {
color:#888;
}
.btn {
.btn {
padding:6px;
margin-left:10px;
margin-bottom:8px;
}
}
}

View file

@ -15,4 +15,36 @@
color: $blue_link;
}
}
header {
.fbtn {
.btn {
background-color: #F8F8F8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC));
background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: linear-gradient(top,#F8F8F8,#ECECEC);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec');
border-color: #C6C6C6;
margin-left:7px;
@include border-radius(3px);
box-shadow:none;
color:#666;
}
}
.search {
.search-input {
@include border-radius(3px);
border-color: #C6C6C6;
box-shadow:none;
}
}
.pic {
img {
@include border-radius(3px);
}
}
}
}

View file

@ -20,6 +20,10 @@
.fbtn {
.btn {
i {
position: relative;
top: 1px;
}
margin-left:8px;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#31363E));
background-image: -webkit-linear-gradient(#595D63 6.6%, #31363E);
@ -32,6 +36,10 @@
background-image: -moz-linear-gradient(#595D63 6.6%, #202227);
background-image: -o-linear-gradient(#595D63 6.6%, #202227);
background-position:0 0;
color:#fff;
i {
@extend .icon-white;
}
}
border: 1px solid #31363E;
@ -59,14 +67,9 @@
.app_logo {
a {
h1 {
background: url('images.png') no-repeat -3px -6px;
width: 65px;
height: 26px;
margin: 6px 0;
padding: 0;
float: left;
text-indent: -1000em;
float:left;
background: url('logo_white.png') no-repeat 0px -3px;
color:#fff;
text-shadow: 0 1px 1px #111;
}
}
.separator {
@ -75,7 +78,6 @@
}
.project_name {
line-height:38px;
color:#fff;
text-shadow: 0 1px 1px #111;
}

View file

@ -37,26 +37,20 @@
*
*/
.app_logo {
width:160px;
a {
h1 {
opacity: 0.7;
background: url('images.png') no-repeat -3px -6px;
width: 65px;
height: 26px;
margin: 6px 0;
padding: 0;
float: left;
text-indent: -1000em;
float:left;
&:hover {
opacity: 1.0;
}
background: none;
color:#DDD;
font-size:30px;
text-shadow: 0 1px 1px #111;
padding-left: 0;
}
}
.separator {
width: 1px;
height: 40px;
margin: 0 9px;
margin: 0 10px;
overflow: hidden;
background: #222;
border-left: 1px solid #333;
@ -66,7 +60,6 @@
.fbtn {
.btn {
i {
@extend .icon-white;
position: relative;
top: 2px;
}
@ -77,10 +70,14 @@
color:#ccc;
&:hover {
color:#fff;
i {
@extend .icon-white;
}
}
border: none;
box-shadow:none;
text-shadow: 0 -1px 0 #000000;
border-left: 1px solid #333;
}
}
@ -113,9 +110,9 @@
*
*/
.project_name {
line-height:34px;
font-size:22px;
color:#fff;
line-height:36px;
font-size:30px;
color:#DDD;
text-shadow: 0 1px 1px #111;
}

View file

@ -0,0 +1,25 @@
class LabelsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :module_enabled
layout "project"
# Authorize
before_filter :add_project_abilities
# Allow read any issue
before_filter :authorize_read_issue!
respond_to :js, :html
def index
@labels = Issue.tag_counts_on(:labels)
end
protected
def module_enabled
return render_404 unless @project.issues_enabled
end
end

View file

@ -12,8 +12,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def ldap
# We only find ourselves here if the authentication to LDAP was successful.
info = request.env["omniauth.auth"]["info"]
@user = User.find_for_ldap_auth(info)
@user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
if @user.persisted?
@user.remember_me = true
end
@ -39,7 +38,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
current_user.save
redirect_to profile_path
else
@user = User.find_by_provider_and_uid(provider, uid)
@user = User.find_by_provider_and_extern_uid(provider, uid)
if @user
sign_in_and_redirect @user

View file

@ -1,4 +1,4 @@
require File.join(Rails.root, 'lib', 'graph_commit')
require Rails.root.join('lib', 'gitlab', 'graph_commit')
class ProjectsController < ApplicationController
before_filter :project, except: [:index, :new, :create]
@ -78,7 +78,7 @@ class ProjectsController < ApplicationController
end
def graph
@days_json, @commits_json = GraphCommit.to_graph(project)
@days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
end
def destroy

View file

@ -9,6 +9,7 @@ class TeamMembersController < ApplicationController
def show
@team_member = project.users_projects.find(params[:id])
@events = @team_member.user.recent_events.where(:project_id => @project.id).limit(7)
end
def new

View file

@ -1,4 +1,4 @@
class ApplicationDecorator < Drapper::Base
class ApplicationDecorator < Draper::Base
# Lazy Helpers
# PRO: Call Rails helpers without the h. proxy
# ex: number_to_currency(model.price)

View file

@ -2,10 +2,13 @@ require 'digest/md5'
module ApplicationHelper
def gravatar_icon(user_email = '', size = 40)
return unless user_email
gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com"
user_email.strip!
"#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
if Gitlab.config.disable_gravatar? || user_email.blank?
'no_avatar.png'
else
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
user_email.strip!
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
end
end
def request_protocol

View file

@ -1,9 +1,18 @@
module GitlabMarkdownHelper
# Replaces references (i.e. @abc, #123, !456, ...) in the text with links to
# the appropriate items in Gitlab.
#
# text - the source text
# html_options - extra options for the reference links as given to link_to
#
# note: reference links will only be generated if @project is set
#
# see Gitlab::Markdown for details on the supported syntax
def gfm(text, html_options = {})
return text if text.nil?
return text if @project.nil?
# Extract pre blocks
# Extract pre blocks so they are not altered
# from http://github.github.com/github-flavored-markdown/
extractions = {}
text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match|
@ -25,7 +34,15 @@ module GitlabMarkdownHelper
text.html_safe
end
# circumvents nesting links, which will behave bad in browsers
# Use this in places where you would normally use link_to(gfm(...), ...).
#
# It solves a problem occurring with nested links (i.e.
# "<a>outer text <a>gfm ref</a> more outer text</a>"). This will not be
# interpreted as intended. Browsers will parse something like
# "<a>outer text </a><a>gfm ref</a> more outer text" (notice the last part is
# not linked any more). link_to_gfm corrects that. It wraps all parts to
# explicitly produce the correct linking behavior (i.e.
# "<a>outer text </a><a>gfm ref</a><a> more outer text</a>").
def link_to_gfm(body, url, html_options = {})
gfm_body = gfm(body, html_options)

View file

@ -12,74 +12,102 @@ class Notify < ActionMailer::Base
def new_user_email(user_id, password)
@user = User.find(user_id)
@password = password
mail(to: @user.email, subject: "gitlab | Account was created for you")
mail(to: @user.email, subject: subject("Account was created for you"))
end
def new_issue_email(issue_id)
@issue = Issue.find(issue_id)
@project = @issue.project
mail(to: @issue.assignee_email, subject: "gitlab | new issue ##{@issue.id} | #{@issue.title} | #{@project.name}")
mail(to: @issue.assignee_email, subject: subject("new issue ##{@issue.id}", @issue.title))
end
def note_wall_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@project = @note.project
mail(to: recipient.email, subject: "gitlab | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject)
end
def note_commit_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@commit = @note.target
@commit = CommitDecorator.decorate(@commit)
@project = @note.project
mail(to: recipient.email, subject: "gitlab | note for commit #{@commit.short_id} | #{@commit.title} | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
end
def note_merge_request_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@merge_request = @note.noteable
@project = @note.project
mail(to: recipient.email, subject: "gitlab | note for merge request !#{@merge_request.id} | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("note for merge request !#{@merge_request.id}"))
end
def note_issue_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@issue = @note.noteable
@project = @note.project
mail(to: recipient.email, subject: "gitlab | note for issue ##{@issue.id} | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("note for issue ##{@issue.id}"))
end
def note_wiki_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@wiki = @note.noteable
@project = @note.project
mail(to: recipient.email, subject: "gitlab | note for wiki | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("note for wiki"))
end
def new_merge_request_email(merge_request_id)
@merge_request = MergeRequest.find(merge_request_id)
@project = @merge_request.project
mail(to: @merge_request.assignee_email, subject: "gitlab | new merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}")
mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
end
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
recipient = User.find(recipient_id)
@merge_request = MergeRequest.find(merge_request_id)
@previous_assignee ||= User.find(previous_assignee_id)
@project = @merge_request.project
mail(to: recipient.email, subject: "gitlab | changed merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title))
end
def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
recipient = User.find(recipient_id)
@issue = Issue.find(issue_id)
@previous_assignee ||= User.find(previous_assignee_id)
@project = @issue.project
mail(to: recipient.email, subject: "gitlab | changed issue ##{@issue.id} | #{@issue.title} | #{@project.name}")
mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title))
end
private
# Look up a User by their ID and return their email address
#
# recipient_id - User ID
#
# Returns a String containing the User's email address.
def recipient(recipient_id)
if recipient = User.find(recipient_id)
recipient.email
end
end
# Formats arguments into a String suitable for use as an email subject
#
# extra - Extra Strings to be inserted into the subject
#
# Examples
#
# >> subject('Lorem ipsum')
# => "gitlab | Lorem ipsum"
#
# # Automatically inserts Project name when @project is set
# >> @project = Project.last
# => #<Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
# >> subject('Lorem ipsum')
# => "gitlab | Lorem ipsum | Ruby on Rails"
#
# # Accepts multiple arguments
# >> subject('Lorem ipsum', 'Dolor sit amet')
# => "gitlab | Lorem ipsum | Dolor sit amet"
def subject(*extra)
"gitlab | " << extra.join(' | ') << (@project ? " | #{@project.name}" : "")
end
end

View file

@ -9,8 +9,6 @@ class Issue < ActiveRecord::Base
validates :description,
length: { within: 0..2000 }
acts_as_list
def self.open_for(user)
opened.assigned(user)
end

View file

@ -88,8 +88,11 @@ class MergeRequest < ActiveRecord::Base
end
def unmerged_diffs
commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
# Only show what is new in the source branch compared to the target branch, not the other way around.
# The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
# From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
diffs = project.repo.diff(common_commit, source_branch)
end
def last_commit

View file

@ -2,7 +2,7 @@ require "grit"
class Project < ActiveRecord::Base
include Repository
include ProjectPush
include PushObserver
include Authority
include Team

View file

@ -7,7 +7,7 @@ class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio,
:name, :projects_limit, :skype, :linkedin, :twitter, :dark_scheme,
:theme_id, :force_random_password
:theme_id, :force_random_password, :extern_uid, :provider
attr_accessor :force_random_password
@ -54,6 +54,8 @@ class User < ActiveRecord::Base
validates :bio, length: { within: 0..255 }
validates :extern_uid, :allow_blank => true, :uniqueness => {:scope => :provider}
before_save :ensure_authentication_token
alias_attribute :private_token, :authentication_token
@ -84,21 +86,31 @@ class User < ActiveRecord::Base
where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
end
def self.find_for_ldap_auth(omniauth_info)
name = omniauth_info.name.force_encoding("utf-8")
email = omniauth_info.email.downcase unless omniauth_info.email.nil?
raise OmniAuth::Error, "LDAP accounts must provide an email address" if email.nil?
def self.find_for_ldap_auth(auth, signed_in_resource=nil)
uid = auth.info.uid
provider = auth.provider
name = auth.info.name.force_encoding("utf-8")
email = auth.info.email.downcase unless auth.info.email.nil?
raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
if @user = User.find_by_email(email)
if @user = User.find_by_extern_uid_and_provider(uid, provider)
@user
# workaround for backward compatibility
elsif @user = User.find_by_email(email)
logger.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
@user.update_attributes(:extern_uid => uid, :provider => provider)
@user
else
logger.info "Creating user from LDAP login {uid => #{uid}, name => #{name}, email => #{email}}"
password = Devise.friendly_token[0, 8].downcase
@user = User.create(
name: name,
email: email,
password: password,
password_confirmation: password,
projects_limit: Gitlab.config.default_projects_limit
:extern_uid => uid,
:provider => provider,
:name => name,
:email => email,
:password => password,
:password_confirmation => password,
:projects_limit => Gitlab.config.default_projects_limit
)
end
end

View file

@ -1,4 +1,4 @@
module ProjectPush
module PushObserver
def observe_push(oldrev, newrev, ref, user)
data = post_receive_data(oldrev, newrev, ref, user)

View file

@ -30,26 +30,10 @@ module Repository
Commit.commits_between(repo, from, to)
end
def write_hooks
%w(post-receive).each do |hook|
write_hook(hook, File.read(File.join(Rails.root, 'lib', "#{hook}-hook")))
end
end
def satellite
@satellite ||= Gitlab::Satellite.new(self)
end
def write_hook(name, content)
hook_file = File.join(path_to_repo, 'hooks', name)
File.open(hook_file, 'w') do |f|
f.write(content)
end
File.chmod(0775, hook_file)
end
def has_post_receive_file?
hook_file = File.join(path_to_repo, 'hooks', 'post-receive')
File.exists?(hook_file)
@ -73,8 +57,6 @@ module Repository
def update_repository
Gitlab::GitHost.system.update_project(path, self)
write_hooks if File.exists?(path_to_repo)
end
def destroy_repository

View file

@ -5,7 +5,7 @@
Read more about system hooks
%strong #{link_to "here", help_system_hooks_path, class: "vlink"}
= form_for @hook, as: :hook, url: admin_hooks_path do |f|
= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f|
-if @hook.errors.any?
.alert-message.block-message.error
- @hook.errors.full_messages.each do |msg|

View file

@ -2,7 +2,7 @@
Projects
= link_to 'New Project', new_admin_project_path, class: "btn small right"
%br
= form_tag admin_projects_path, method: :get do
= form_tag admin_projects_path, method: :get, class: 'form-inline' do
= text_field_tag :name, params[:name], class: "xlarge"
= submit_tag "Search", class: "btn submit primary"

View file

@ -3,7 +3,7 @@
= link_to 'New User', new_admin_user_path, class: "btn small right"
%br
= form_tag admin_users_path, method: :get do
= form_tag admin_users_path, method: :get, class: 'form-inline' do
= text_field_tag :name, params[:name], class: "xlarge"
= submit_tag "Search", class: "btn submit primary"
%ul.nav.nav-pills

View file

@ -5,10 +5,10 @@
%span.btn.disabled.grouped
%i.icon-comment
= @notes_count
= link_to patch_project_commit_path(@project, @commit.id), class: "btn small grouped" do
= link_to patch_project_commit_path(@project, @commit.id), class: "btn small grouped" do
%i.icon-download-alt
Get Patch
= link_to tree_project_ref_path(@project, @commit.id), class: "browse-button primary grouped" do
Get Patch
= link_to tree_project_ref_path(@project, @commit.id), class: "browse-button primary grouped" do
%strong Browse Code »
%h3.commit-title.page_title
= gfm @commit.title

View file

@ -1,14 +1,7 @@
- if @projects.any?
.projects
.activities.span8
- if current_user.require_ssh_key?
.alert.alert-error.padded
%span
You wont be able to pull/push project code unless you
%strong
= link_to new_key_path, class: "vlink" do
add new key
to your profile
= render 'shared/no_ssh'
- if @events.any?
.content_list= render @events
- else
@ -57,5 +50,5 @@
If you will be added to project - it will be displayed here
:javascript
:javascript
$(function(){ Pager.init(20); });

View file

@ -23,5 +23,3 @@
= preserve do
sudo chmod -R 770 /home/git/repositories/
sudo chown -R git:git /home/git/repositories/
sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive

View file

@ -31,3 +31,6 @@
%li
%h5= link_to "Gitlab Markdown", help_markdown_path
%li
%h5= link_to "SSH keys", help_ssh_path

View file

@ -1,6 +1,6 @@
%h3 Permissions
%h3.page_title Permissions
.back_link
= link_to help_path do
= link_to help_path do
&larr; to index
%hr

View file

@ -0,0 +1,25 @@
%h3.page_title SSH Keys
.back_link
= link_to help_path do
&larr; to index
%hr
%p.slead
SSH key allows you to establish a secure connection between your computer and Gitlab
%p.slead
To generate a new SSH key just open your terminal and use code below.
%pre.dark
ssh-keygen -t rsa -C "#{current_user.email}"
\# Creates a new ssh key using the provided email
\# Generating public/private rsa key pair...
%p.slead
Next just use code below to dump your public key and add to GITLAB SSH Keys
%pre.dark
cat ~/.ssh/id_rsa.pub
\# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6eNtGpNGwstc....

View file

@ -1,10 +1,10 @@
%h3 System hooks
.back_link
= link_to :back do
= link_to :back do
&larr; back
%hr
%p.slead
%p.slead
Your Gitlab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member.
%br
System Hooks can be used for logging or change information in LDAP server.

View file

@ -1,11 +1,11 @@
%h3 Web hooks
%h3.page_title Web hooks
.back_link
= link_to help_path do
= link_to help_path do
&larr; to index
%hr
%p.slead
Every Gitlab project can trigger a web server whenever the repo is pushed to.
%p.slead
Every Gitlab project can trigger a web server whenever the repo is pushed to.
%br
Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
%br

View file

@ -1,7 +1,6 @@
- bash_lexer = Pygments::Lexer[:bash]
%h3 Workflow
%h3.page_title Workflow
.back_link
= link_to help_path do
= link_to help_path do
&larr; to index
%hr
@ -9,25 +8,25 @@
%li
%p Clone project
.bash
%pre
%pre.dark
git clone git@example.com:project-name.git
%li
%p Create branch with your feature
.bash
%pre
%pre.dark
git checkout -b $feature_name
%li
%p Write code. Commit changes
.bash
%pre
%pre.dark
git commit -am "My feature is ready"
%li
%p Push your branch to gitlabhq
.bash
%pre
%pre.dark
git push origin $feature_name
%li

View file

@ -8,7 +8,7 @@
Read more about web hooks
%strong #{link_to "here", help_web_hooks_path, class: "vlink"}
= form_for [@project, @hook], as: :hook, url: project_hooks_path(@project) do |f|
= form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f|
-if @hook.errors.any?
.alert-message.block-message.error
- @hook.errors.full_messages.each do |msg|

View file

@ -1,5 +1,5 @@
%div.issue-form-holder
%h3= @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], remote: request.xhr? do |f|
-if @issue.errors.any?
.alert-message.block-message.error
@ -9,26 +9,26 @@
.issue_form_box
.issue_title
.clearfix
= f.label :title do
= f.label :title do
%strong= "Subject *"
.input
= f.text_field :title, maxlength: 255, class: "xxlarge"
.issue_middle_block
.issue_assignee
= f.label :assignee_id do
= f.label :assignee_id do
%i.icon-user
Assign to
.input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" })
.issue_milestone
= f.label :milestone_id do
= f.label :milestone_id do
%i.icon-time
Milestone
.input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" })
.issue_description
.clearfix
= f.label :label_list do
%i.icon-tag
= f.label :label_list do
%i.icon-tag
Labels
.input
= f.text_field :label_list, maxlength: 2000, class: "xxlarge"

View file

@ -5,6 +5,9 @@
%li{class: "#{'active' if current_page?(project_milestones_path(@project))}"}
= link_to project_milestones_path(@project), class: "tab" do
Milestones
%li{class: "#{'active' if current_page?(project_labels_path(@project))}"}
= link_to project_labels_path(@project), class: "tab" do
Labels
%li.right
%span.rss-icon
= link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do

View file

@ -7,6 +7,7 @@
.span5
- if can? current_user, :write_issue, @project
= link_to new_project_issue_path(@project), class: "right btn small", title: "New Issue", remote: true do
%i.icon-plus
New Issue
= form_tag search_project_issues_path(@project), method: :get, remote: true, id: "issue_search_form", class: :right do
= hidden_field_tag :project_id, @project.id, { id: 'project_id' }
@ -21,7 +22,7 @@
.issues_bulk_update.hide
= form_tag bulk_update_project_issues_path(@project), method: :post do
= form_tag bulk_update_project_issues_path(@project), method: :post do
%span.update_issues_text Update selected issues with &nbsp;
.left
= select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status")
@ -53,7 +54,7 @@
= select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
= hidden_field_tag :f, params[:f]
.clearfix
%ul#issues-table.unstyled.issues_table
= render "issues"

View file

@ -11,7 +11,13 @@
.input= f.text_field :title
.clearfix
= f.label :key
.input= f.text_area :key, class: [:xxlarge, :thin_area]
.input
= f.text_area :key, class: [:xxlarge, :thin_area]
%p.hint
Paste your public key here. Read more about how generate it
= link_to "here", help_ssh_path
.actions
= f.submit 'Save', class: "primary btn"
= link_to "Cancel", keys_path, class: "btn"

View file

@ -1,4 +1,4 @@
%h3.page_title New key
%h3.page_title Add an SSH Key
%hr
= render 'form'

View file

@ -0,0 +1,4 @@
%li.wll
%strong= label.name
.right
%span= pluralize label.count, 'issue'

View file

@ -0,0 +1,14 @@
= render "issues/head"
%h3.page_title
Labels
%br
%div.ui-box
%ul.unstyled.labels-table
- @labels.each do |label|
= render 'label', label: label
- unless @labels.present?
%li
%h3.nothing_here_message Nothing to show here

View file

@ -6,7 +6,6 @@
= favicon_link_tag 'favicon.ico'
= stylesheet_link_tag "application"
= javascript_include_tag "application"
-# Atom feed
- if controller_name == 'projects' && action_name == 'index'
= auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"

View file

@ -33,7 +33,8 @@
});
$(".edit_merge_request").live("ajax:beforeSend", function() {
$(this).replaceWith('#{image_tag "ajax_loader.gif"}');
$('.can_be_merged').hide();
$('.merge_in_progress').show();
})
})

View file

@ -3,13 +3,12 @@
%a.close{href: "#"} ×
%h3 How To Merge
.modal-body
%pre
%pre.dark
= preserve do
:erb
git checkout <%= @merge_request.target_branch %>
git fetch origin
git merge origin/<%= @merge_request.source_branch %>
git push origin <%= @merge_request.target_branch %>
git checkout #{@merge_request.target_branch}
git fetch origin
git merge origin/#{@merge_request.source_branch}
git push origin #{@merge_request.target_branch}
:javascript

View file

@ -40,3 +40,6 @@
.alert.alert-info
%strong This merge request already can not be merged. Try to reload page.
.merge_in_progress.hide
%span.cgray Merge is in progress. Please wait. Page will be automatically reloaded. &nbsp;
= image_tag "ajax_loader.gif"

View file

@ -1,4 +1,4 @@
%h3= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
%h3.page_title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
.back_link
= link_to project_milestones_path(@project) do
&larr; To milestones
@ -17,12 +17,12 @@
= f.label :title, "Title", class: "control-label"
.controls
= f.text_field :title, maxlength: 255, class: "input-xlarge"
%p.help-block Required
%p.hint Required
.control-group
= f.label :description, "Description", class: "control-label"
.controls
= f.text_area :description, maxlength: 2000, class: "input-xlarge", rows: 10
%p.help-block Markdown is enabled.
%p.hint Markdown is enabled.
.span6
.control-group
= f.label :due_date, "Due Date", class: "control-label"

View file

@ -1,7 +1,9 @@
- if note.valid?
:plain
$("#new_note .errors").remove();
$("#new_note .error").remove();
$('#new_note textarea').val("");
$('#preview-link').text('Preview');
$('#preview-note').hide(); $('#note_note').show();
NoteList.prepend(#{note.id}, "#{escape_javascript(render partial: "notes/show", locals: {note: note})}");
- else
:plain

View file

@ -1,5 +1,5 @@
%li{id: dom_id(note), class: "note"}
= image_tag gravatar_icon(note.author.email), class: "avatar"
= image_tag gravatar_icon(note.author.email), class: "avatar s32"
%div.note-author
%strong= note.author_name
= link_to "##{dom_id(note)}", name: dom_id(note) do

View file

@ -1,47 +1,30 @@
- if current_user.require_ssh_key?
.alert-message.block-message.error
%ul
%li You have no ssh keys added to your profile.
%li You wont be able to pull/push repository.
%li Visit profile &rarr; keys and add public key of every machine you want to use for work with gitlabhq.
.alert-message.block-message.error
%ul.unstyled.alert_holder
%li You should push repository to proceed.
%li After push you will be able to browse code, commits etc.
- bash_lexer = Pygments::Lexer[:bash]
= render 'shared/no_ssh'
%div.git-empty
%h3 Git global setup:
- setup_str = ["git config --global user.name \"#{current_user.name}\"",
"git config --global user.email \"#{current_user.email}\""].join("\n")
= preserve do
= raw bash_lexer.highlight(setup_str, lexer: 'bash', options: {encoding: 'utf-8'})
%h4 Git global setup:
%pre.dark
= preserve do
git config --global user.name "#{current_user.name}"
git config --global user.email "#{current_user.email}"
%br
%br
%h3 Create Repository
- repo_setup_str = ["mkdir #{@project.path}",
"cd #{@project.path}",
"git init",
"touch README",
"git add README",
"git commit -m 'first commit'",
"git remote add origin #{@project.url_to_repo}",
"git push -u origin master"].join("\n")
%h4.prepend-top-20 Create Repository
%pre.dark
= preserve do
mkdir #{@project.path}
cd #{@project.path}
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin #{@project.url_to_repo}
git push -u origin master
= preserve do
= raw bash_lexer.highlight(repo_setup_str)
%br
%br
%h3 Existing Git Repo?
- exist_repo_setup_str = ["cd existing_git_repo",
"git remote add origin #{@project.url_to_repo}",
"git push -u origin master"].join("\n")
= preserve do
= raw bash_lexer.highlight(exist_repo_setup_str)
%h4.prepend-top-20 Existing Git Repo?
%pre.dark
= preserve do
cd existing_git_repo
git remote add origin #{@project.url_to_repo}
git push -u origin master
- if can? current_user, :admin_project, @project
.alert-message.block-message.error.prepend-top-20
= link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger"
.prepend-top-20
= link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger right"

View file

@ -51,8 +51,6 @@
:javascript
$(function(){
$('select#branch').selectmenu({style:'popup', width:200});
$('select#tag').selectmenu({style:'popup', width:200});
$('.project-refs-select').chosen();
history.pushState({ path: this.path }, '', "#{@history_path}");

View file

@ -1,3 +1,3 @@
- if tm
%strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
= link_to_gfm truncate(content_commit.title, length: tm ? 30 : 50), project_commit_path(@project, content_commit.id), class: "tree-commit-link"

View file

@ -1,4 +1,4 @@
= form_tag search_path, method: :get do |f|
= form_tag search_path, method: :get, class: 'form-inline' do |f|
.padded
= label_tag :search do
%strong Looking for

View file

@ -0,0 +1,8 @@
- if current_user.require_ssh_key?
%h6.error_message
%span
You wont be able to pull/push project code unless you
%strong
= link_to new_key_path, class: "vlink" do
add SSH key
to your profile

View file

@ -9,7 +9,7 @@
%span.label Blocked
= link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
= image_tag gravatar_icon(user.email, 40), class: "avatar"
= image_tag gravatar_icon(user.email, 40), class: "avatar s32"
= link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
%strong= truncate(user.name, lenght: 40)
%br

View file

@ -51,7 +51,7 @@
= form_for(@team_member, as: :team_member, url: project_team_member_path(@project, @team_member)) do |f|
= f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, class: "project-access-select", disabled: !allow_admin
%hr
= render user.recent_events.limit(5)
= render @events
:javascript
$(function(){
$('.repo-access-select, .project-access-select').live("change", function() {