Commit 5f7a3e1b authored by Douwe Maan's avatar Douwe Maan

Merge branch 'master' into extend_markdown_upload

# Conflicts:
#	app/controllers/files_controller.rb
parents 769d1ce6 a30a5663
...@@ -6,6 +6,17 @@ v 7.9.0 (unreleased) ...@@ -6,6 +6,17 @@ v 7.9.0 (unreleased)
- Improve error messages for file edit failures - Improve error messages for file edit failures
- Improve UI for commits, issues and merge request lists - Improve UI for commits, issues and merge request lists
- Fix commit comments on first line of diff not rendering in Merge Request Discussion view. - Fix commit comments on first line of diff not rendering in Merge Request Discussion view.
- Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev)
- Save web edit in new branch
- Fix ordering of imported but unchanged projects (Marco Wessel)
- Mobile UI improvements: make aside content expandable
v 7.8.1
- Fix run of custom post receive hooks
- Fix migration that caused issues when upgrading to version 7.8 from versions prior to 7.3
- Fix the warning for LDAP users about need to set password
- Fix avatars which were not shown for non logged in users
- Fix urls for the issues when relative url was enabled
v 7.8.0 v 7.8.0
- Fix access control and protection against XSS for note attachments and other uploads. - Fix access control and protection against XSS for note attachments and other uploads.
...@@ -39,7 +50,7 @@ v 7.8.0 ...@@ -39,7 +50,7 @@ v 7.8.0
- Allow configuring protection of the default branch upon first push (Marco Wessel) - Allow configuring protection of the default branch upon first push (Marco Wessel)
- Add gitlab.com importer - Add gitlab.com importer
- Add an ability to login with gitlab.com - Add an ability to login with gitlab.com
- Add a commit calendar to the user profile (Hannes Rosenögger) - Add a commit calendar to the user profile (Hannes Rosenögger)
- Submit comment on command-enter - Submit comment on command-enter
- Notify all members of a group when that group is mentioned in a comment, for example: `@gitlab-org` or `@sales`. - Notify all members of a group when that group is mentioned in a comment, for example: `@gitlab-org` or `@sales`.
- Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close" - Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close"
...@@ -54,7 +65,7 @@ v 7.8.0 ...@@ -54,7 +65,7 @@ v 7.8.0
- API: Access groups with their path (Julien Bianchi) - API: Access groups with their path (Julien Bianchi)
- Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard) - Added link to milestone and keeping resource context on smaller viewports for issues and merge requests (Jason Blanchard)
- Allow notification email to be set separately from primary email. - Allow notification email to be set separately from primary email.
- API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger) - API: Add support for editing an existing project (Mika Mäenpää and Hannes Rosenögger)
- Don't have Markdown preview fail for long comments/wiki pages. - Don't have Markdown preview fail for long comments/wiki pages.
- When test web hook - show error message instead of 500 error page if connection to hook url was reset - When test web hook - show error message instead of 500 error page if connection to hook url was reset
- Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov) - Added support for firing system hooks on group create/destroy and adding/removing users to group (Boyan Tabakov)
......
...@@ -41,7 +41,7 @@ gem "browser" ...@@ -41,7 +41,7 @@ gem "browser"
gem "gitlab_git", '7.0.0.rc14' gem "gitlab_git", '7.0.0.rc14'
# Ruby/Rack Git Smart-HTTP Server Handler # Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack' gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
# LDAP Auth # LDAP Auth
gem 'gitlab_omniauth-ldap', '1.2.0', require: "omniauth-ldap" gem 'gitlab_omniauth-ldap', '1.2.0', require: "omniauth-ldap"
...@@ -50,7 +50,7 @@ gem 'gitlab_omniauth-ldap', '1.2.0', require: "omniauth-ldap" ...@@ -50,7 +50,7 @@ gem 'gitlab_omniauth-ldap', '1.2.0', require: "omniauth-ldap"
gem 'gollum-lib', '~> 4.0.0' gem 'gollum-lib', '~> 4.0.0'
# Language detection # Language detection
gem "gitlab-linguist", "~> 3.0.0", require: "linguist" gem "gitlab-linguist", "~> 3.0.1", require: "linguist"
# API # API
gem "grape", "~> 0.6.1" gem "grape", "~> 0.6.1"
......
...@@ -81,7 +81,7 @@ GEM ...@@ -81,7 +81,7 @@ GEM
json (>= 1.7) json (>= 1.7)
celluloid (0.16.0) celluloid (0.16.0)
timers (~> 4.0.0) timers (~> 4.0.0)
charlock_holmes (0.7.3) charlock_holmes (0.6.9.4)
cliver (0.3.2) cliver (0.3.2)
coderay (1.1.0) coderay (1.1.0)
coercible (1.0.0) coercible (1.0.0)
...@@ -188,14 +188,14 @@ GEM ...@@ -188,14 +188,14 @@ GEM
gitlab-flowdock-git-hook (0.4.2.2) gitlab-flowdock-git-hook (0.4.2.2)
gitlab-grit (>= 2.4.1) gitlab-grit (>= 2.4.1)
multi_json multi_json
gitlab-grack (2.0.0.pre) gitlab-grack (2.0.0.rc2)
rack (~> 1.5.1) rack (~> 1.5.1)
gitlab-grit (2.7.2) gitlab-grit (2.7.2)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
diff-lcs (~> 1.1) diff-lcs (~> 1.1)
mime-types (~> 1.15) mime-types (~> 1.15)
posix-spawn (~> 0.3) posix-spawn (~> 0.3)
gitlab-linguist (3.0.0) gitlab-linguist (3.0.1)
charlock_holmes (~> 0.6.6) charlock_holmes (~> 0.6.6)
escape_utils (~> 0.2.4) escape_utils (~> 0.2.4)
mime-types (~> 1.19) mime-types (~> 1.19)
...@@ -674,8 +674,8 @@ DEPENDENCIES ...@@ -674,8 +674,8 @@ DEPENDENCIES
gemnasium-gitlab-service (~> 0.2) gemnasium-gitlab-service (~> 0.2)
github-markup github-markup
gitlab-flowdock-git-hook (~> 0.4.2) gitlab-flowdock-git-hook (~> 0.4.2)
gitlab-grack (~> 2.0.0.pre) gitlab-grack (~> 2.0.0.rc2)
gitlab-linguist (~> 3.0.0) gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.0.1.1) gitlab_emoji (~> 0.0.1.1)
gitlab_git (= 7.0.0.rc14) gitlab_git (= 7.0.0.rc14)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
......
app/assets/images/logo-white.png

7.16 KB | W: | H:

app/assets/images/logo-white.png

7.52 KB | W: | H:

app/assets/images/logo-white.png
app/assets/images/logo-white.png
app/assets/images/logo-white.png
app/assets/images/logo-white.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -69,5 +69,6 @@ ...@@ -69,5 +69,6 @@
background: #EEE; background: #EEE;
font-size: 20px; font-size: 20px;
color: #777; color: #777;
z-index: 100;
@include box-shadow(0 1px 2px #DDD); @include box-shadow(0 1px 2px #DDD);
} }
...@@ -86,7 +86,7 @@ header { ...@@ -86,7 +86,7 @@ header {
.container { .container {
width: 100% !important; width: 100% !important;
padding-left: 0px; padding: 0px;
} }
/** /**
...@@ -100,18 +100,14 @@ header { ...@@ -100,18 +100,14 @@ header {
a { a {
float: left; float: left;
padding: 0px; padding: 5px 0;
margin: 0 6px; height: 46px;
width: 52px;
h1 { text-align: center;
margin: 0;
background: image-url('logo-black.png') no-repeat center center; img {
background-size: 32px; width: 36px;
float: left; height: 36px;
height: 46px;
width: 40px;
@include header-font;
text-indent: -9999px;
} }
} }
&:hover { &:hover {
...@@ -134,14 +130,13 @@ header { ...@@ -134,14 +130,13 @@ header {
} }
.profile-pic { .profile-pic {
position: relative; padding: 0px !important;
top: -1px; width: 46px;
padding-right: 0px !important; height: 46px;
margin-left: 5px;
img { img {
width: 50px; width: 46px;
height: 50px; height: 46px;
margin: -15px;
margin-left: 5px;
} }
} }
...@@ -174,68 +169,6 @@ header { ...@@ -174,68 +169,6 @@ header {
@include transition(all 0.15s ease-in 0s); @include transition(all 0.15s ease-in 0s);
} }
} }
/*
* Dark header
*
*/
&.header-dark {
&.navbar-gitlab {
.navbar-inner {
background: #708090;
border-bottom: 1px solid #AAA;
.navbar-toggle { color: #fff; }
.nav > li > a {
color: #AAA;
&:hover, &:focus, &:active {
background: none;
color: #FFF;
}
}
}
}
.turbolink-spinner {
color: #FFF;
}
.search {
.search-input {
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid #AAA;
&:focus {
background-color: white;
}
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.app_logo {
a {
h1 {
background: image-url('logo-white.png') no-repeat center center;
background-size: 32px;
color: #fff;
}
}
}
.title {
a {
color: #FFF;
&:hover {
text-decoration: underline;
}
}
color: #fff;
}
}
} }
.search .search-input { .search .search-input {
......
i.icon-gitorious {
display: inline-block;
background-position: 0px 0px;
background-size: contain;
background-repeat: no-repeat;
}
i.icon-gitorious-small {
background-image: image-url('gitorious-logo-blue.png');
width: 13px;
height: 13px;
}
i.icon-gitorious-big {
background-image: image-url('gitorious-logo-black.png');
width: 18px;
height: 18px;
}
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
width: $sidebar_width; width: $sidebar_width;
.nav-sidebar { .nav-sidebar {
margin-top: 20px; margin-top: 29px;
position: fixed; position: fixed;
top: 45px; top: 45px;
width: $sidebar_width; width: $sidebar_width;
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
width: 52px; width: 52px;
.nav-sidebar { .nav-sidebar {
margin-top: 20px; margin-top: 29px;
position: fixed; position: fixed;
top: 45px; top: 45px;
width: 52px; width: 52px;
...@@ -144,14 +144,22 @@ ...@@ -144,14 +144,22 @@
} }
} }
} }
.collapse-nav a {
left: 0px;
padding: 5px 23px 3px 22px;
}
} }
} }
.collapse-nav a { .collapse-nav a {
position: fixed; position: fixed;
bottom: 15px; top: 47px;
padding: 10px; padding: 5px 13px 3px 13px;
background: #DDD; left: 197px;
background: #EEE;
color: black;
border: 1px solid rgba(0,0,0,0.035);
} }
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
......
@mixin dark-theme($color-light, $color, $color-darker, $color-dark) {
header {
&.navbar-gitlab {
.navbar-inner {
background: $color;
.navbar-toggle {
color: #FFF;
}
.app_logo, .navbar-toggle {
&:hover {
background-color: $color-darker;
}
}
.app_logo {
background-color: $color-dark;
}
.title {
color: #FFF;
a {
color: #FFF;
&:hover {
text-decoration: underline;
}
}
}
.search {
.search-input {
background-color: $color-light;
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid $color-light;
&:focus {
background-color: white;
}
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.nav > li > a {
color: $color-light;
&:hover, &:focus, &:active {
background: none;
color: #FFF;
}
}
.search-input {
border-color: $color-light;
}
}
}
}
}
...@@ -10,8 +10,15 @@ ...@@ -10,8 +10,15 @@
background: #F1F1F1; background: #F1F1F1;
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
.app_logo { .title {
background-color: #DDD; color: #555;
a {
color: #555;
&:hover {
text-decoration: underline;
}
}
} }
.nav > li > a { .nav > li > a {
......
/** /**
* This file represent some UI that can be changed * Violet GitLab UI theme
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/ */
.ui_color { .ui_color {
/* @include dark-theme(#98C, #548, #436, #325);
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #548;
border-bottom: 1px solid #436;
.app_logo, .navbar-toggle {
&:hover {
background-color: #436;
}
}
.app_logo {
background-color: #325;
}
.nav > li > a {
color: #98C;
}
.search-input {
border-color: #98C;
}
}
}
}
.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
background: #659;
}
} }
/** /**
* This file represent some UI that can be changed * Gray GitLab UI theme
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/ */
.ui_gray { .ui_gray {
/* @include dark-theme(#979797, #373737, #272727, #222222);
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #373737;
border-bottom: 1px solid #272727;
.app_logo, .navbar-toggle {
&:hover {
background-color: #272727;
}
}
.app_logo {
background-color: #222;
}
}
}
}
} }
/** /**
* This file represent some UI that can be changed * Classic GitLab UI theme
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/ */
.ui_mars { .ui_mars {
/* @include dark-theme(#979DA7, #474D57, #373D47, #24272D);
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #474D57;
border-bottom: 1px solid #373D47;
.app_logo, .navbar-toggle {
&:hover {
background-color: #373D47;
}
}
.app_logo {
background-color: #24272D;
}
.nav > li > a {
color: #979DA7;
}
.search-input {
border-color: #979DA7;
}
}
}
}
} }
/** /**
* This file represent some UI that can be changed * Modern GitLab UI theme
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/ */
.ui_modern { .ui_modern {
/* @include dark-theme(#ADC, #019875, #018865, #017855);
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #019875;
border-bottom: 1px solid #019875;
.app_logo, .navbar-toggle {
&:hover {
background-color: #018865;
}
}
.app_logo {
background-color: #017855;
}
.nav > li > a {
color: #ADC;
}
.search-input {
border-color: #8ba;
}
}
}
}
.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
background: #019875;
}
} }
# Controller for viewing a file's blame # Controller for viewing a file's blame
class Projects::BlobController < Projects::ApplicationController class Projects::BlobController < Projects::ApplicationController
include ExtractsPath include ExtractsPath
include ActionView::Helpers::SanitizeHelper
# Raised when given an invalid file path # Raised when given an invalid file path
class InvalidPathError < StandardError; end class InvalidPathError < StandardError; end
...@@ -21,11 +22,18 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -21,11 +22,18 @@ class Projects::BlobController < Projects::ApplicationController
def create def create
file_path = File.join(@path, File.basename(params[:file_name])) file_path = File.join(@path, File.basename(params[:file_name]))
result = Files::CreateService.new(@project, current_user, params, @ref, file_path).execute result = Files::CreateService.new(
@project,
current_user,
params.merge(new_branch: sanitized_new_branch_name),
@ref,
file_path
).execute
if result[:status] == :success if result[:status] == :success
flash[:notice] = "Your changes have been successfully committed" flash[:notice] = "Your changes have been successfully committed"
redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@ref, file_path)) ref = sanitized_new_branch_name.presence || @ref
redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(ref, file_path))
else else
flash[:alert] = result[:message] flash[:alert] = result[:message]
render :new render :new
...@@ -41,7 +49,13 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -41,7 +49,13 @@ class Projects::BlobController < Projects::ApplicationController
def update def update
result = Files::UpdateService. result = Files::UpdateService.
new(@project, current_user, params, @ref, @path).execute new(
@project,
current_user,
params.merge(new_branch: sanitized_new_branch_name),
@ref,
@path
).execute
if result[:status] == :success if result[:status] == :success
flash[:notice] = "Your changes have been successfully committed" flash[:notice] = "Your changes have been successfully committed"
...@@ -131,6 +145,8 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -131,6 +145,8 @@ class Projects::BlobController < Projects::ApplicationController
if from_merge_request if from_merge_request
diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) +
"#file-path-#{hexdigest(@path)}" "#file-path-#{hexdigest(@path)}"
elsif sanitized_new_branch_name.present?
namespace_project_blob_path(@project.namespace, @project, File.join(sanitized_new_branch_name, @path))
else else
namespace_project_blob_path(@project.namespace, @project, @id) namespace_project_blob_path(@project.namespace, @project, @id)
end end
...@@ -140,4 +156,8 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -140,4 +156,8 @@ class Projects::BlobController < Projects::ApplicationController
# If blob edit was initiated from merge request page # If blob edit was initiated from merge request page
@from_merge_request ||= MergeRequest.find_by(id: params[:from_merge_request_id]) @from_merge_request ||= MergeRequest.find_by(id: params[:from_merge_request_id])
end end
def sanitized_new_branch_name
@new_branch ||= sanitize(strip_tags(params[:new_branch]))
end
end end
...@@ -102,7 +102,7 @@ class ProjectsController < ApplicationController ...@@ -102,7 +102,7 @@ class ProjectsController < ApplicationController
flash[:alert] = 'Project deleted.' flash[:alert] = 'Project deleted.'
if request.referer.include?('/admin') if request.referer.include?('/admin')
redirect_to admin_namespace_projects_path redirect_to admin_namespaces_projects_path
else else
redirect_to projects_dashboard_path redirect_to projects_dashboard_path
end end
......
...@@ -6,7 +6,9 @@ class UsersController < ApplicationController ...@@ -6,7 +6,9 @@ class UsersController < ApplicationController
def show def show
@contributed_projects = Project. @contributed_projects = Project.
where(id: authorized_projects_ids & @user.contributed_projects_ids). where(id: authorized_projects_ids & @user.contributed_projects_ids).
in_group_namespace.includes(:namespace) in_group_namespace.
includes(:namespace).
reject(&:forked?)
@projects = @user.personal_projects. @projects = @user.personal_projects.
where(id: authorized_projects_ids).includes(:namespace) where(id: authorized_projects_ids).includes(:namespace)
......
...@@ -14,4 +14,8 @@ module AppearancesHelper ...@@ -14,4 +14,8 @@ module AppearancesHelper
def brand_text def brand_text
nil nil
end end
def brand_header_logo
image_tag 'logo-white.png'
end
end end
...@@ -48,6 +48,12 @@ class Project < ActiveRecord::Base ...@@ -48,6 +48,12 @@ class Project < ActiveRecord::Base
default_value_for :wall_enabled, false default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets default_value_for :snippets_enabled, gitlab_config_features.snippets
# set last_activity_at to the same as created_at
after_create :set_last_activity_at
def set_last_activity_at
update_column(:last_activity_at, self.created_at)
end
ActsAsTaggableOn.strict_case_match = true ActsAsTaggableOn.strict_case_match = true
acts_as_taggable_on :tags acts_as_taggable_on :tags
......
...@@ -623,9 +623,10 @@ class User < ActiveRecord::Base ...@@ -623,9 +623,10 @@ class User < ActiveRecord::Base
def contributed_projects_ids def contributed_projects_ids
Event.where(author_id: self). Event.where(author_id: self).
where("created_at > ?", Time.now - 1.year). where("created_at > ?", Time.now - 1.year).
code_push. where("action = :pushed OR (target_type = 'MergeRequest' AND action = :created)",
pushed: Event::PUSHED, created: Event::CREATED).
reorder(project_id: :desc). reorder(project_id: :desc).
select('DISTINCT(project_id)'). select(:project_id).
map(&:project_id) uniq
end end
end end
...@@ -38,7 +38,8 @@ module Files ...@@ -38,7 +38,8 @@ module Files
created_successfully = new_file_action.commit!( created_successfully = new_file_action.commit!(
params[:content], params[:content],
params[:commit_message], params[:commit_message],
params[:encoding] params[:encoding],
params[:new_branch]
) )
if created_successfully if created_successfully
......
...@@ -23,7 +23,8 @@ module Files ...@@ -23,7 +23,8 @@ module Files
edit_file_action.commit!( edit_file_action.commit!(
params[:content], params[:content],
params[:commit_message], params[:commit_message],
params[:encoding] params[:encoding],
params[:new_branch]
) )
success success
......
.row .row
.col-md-3 = link_to '#aside', class: 'show-aside' do
%i.fa.fa-angle-left
%aside.col-md-3
.admin-filter .admin-filter
= form_tag admin_namespaces_projects_path, method: :get, class: '' do = form_tag admin_namespaces_projects_path, method: :get, class: '' do
.form-group .form-group
...@@ -36,7 +38,7 @@ ...@@ -36,7 +38,7 @@
= button_tag "Search", class: "btn submit btn-primary" = button_tag "Search", class: "btn submit btn-primary"
= link_to "Reset", admin_namespaces_projects_path, class: "btn btn-cancel" = link_to "Reset", admin_namespaces_projects_path, class: "btn btn-cancel"
.col-md-9 %section.col-md-9
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
Projects (#{@projects.total_count}) Projects (#{@projects.total_count})
......
.row .row
.col-md-3 = link_to '#aside', class: 'show-aside' do
%i.fa.fa-angle-left
%aside.col-md-3
.admin-filter .admin-filter
%ul.nav.nav-pills.nav-stacked %ul.nav.nav-pills.nav-stacked
%li{class: "#{'active' unless params[:filter]}"} %li{class: "#{'active' unless params[:filter]}"}
...@@ -27,7 +29,7 @@ ...@@ -27,7 +29,7 @@
%hr %hr
= link_to 'Reset', admin_users_path, class: "btn btn-cancel" = link_to 'Reset', admin_users_path, class: "btn btn-cancel"
.col-md-9 %section.col-md-9
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
Users (#{@users.total_count}) Users (#{@users.total_count})
......
%h3.page-title %h3.page-title
%i.fa.fa-gitorious %i.icon-gitorious.icon-gitorious-big
Import repositories from Gitorious.org Import repositories from Gitorious.org
%p.light %p.light
......
- if nav_menu_collapsed? - if nav_menu_collapsed?
= link_to icon('angle-right'), '#', class: 'toggle-nav-collapse' = link_to icon('angle-right'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
- else - else
= link_to icon('angle-left'), '#', class: 'toggle-nav-collapse' = link_to icon('angle-left'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.container .container
%div.app_logo %div.app_logo
= link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do
%h1 GITLAB = brand_header_logo
%h1.title= title %h1.title= title
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
......
...@@ -2,10 +2,8 @@ ...@@ -2,10 +2,8 @@
.navbar-inner .navbar-inner
.container .container
%div.app_logo %div.app_logo
%span.separator
= link_to explore_root_path, class: "home" do = link_to explore_root_path, class: "home" do
%h1 GITLAB = brand_header_logo
%span.separator
%h1.title= title %h1.title= title
%button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
......
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: "Admin area" = render "layouts/head", title: "Admin area"
%body{class: "#{app_theme} #{theme_type} admin", :'data-page' => body_data_page} %body{class: "#{app_theme} admin", :'data-page' => body_data_page}
= render "layouts/head_panel", title: link_to("Admin area", admin_root_path) = render "layouts/head_panel", title: link_to("Admin area", admin_root_path)
= render 'layouts/page', sidebar: 'layouts/nav/admin' = render 'layouts/page', sidebar: 'layouts/nav/admin'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: "Dashboard" = render "layouts/head", title: "Dashboard"
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page } %body{class: "#{app_theme} application", :'data-page' => body_data_page }
= render "layouts/head_panel", title: link_to("Dashboard", root_path) = render "layouts/head_panel", title: link_to("Dashboard", root_path)
= render 'layouts/page', sidebar: 'layouts/nav/dashboard' = render 'layouts/page', sidebar: 'layouts/nav/dashboard'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: "Error" = render "layouts/head", title: "Error"
%body{class: "#{app_theme} #{theme_type} application"} %body{class: "#{app_theme} application"}
= render "layouts/head_panel", title: "" if current_user = render "layouts/head_panel", title: "" if current_user
.container.navless-container .container.navless-container
= render "layouts/flash" = render "layouts/flash"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: page_title = render "layouts/head", title: page_title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
- if current_user - if current_user
= render "layouts/head_panel", title: link_to(page_title, explore_root_path) = render "layouts/head_panel", title: link_to(page_title, explore_root_path)
......
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: group_head_title = render "layouts/head", title: group_head_title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/head_panel", title: link_to(@group.name, group_path(@group)) = render "layouts/head_panel", title: link_to(@group.name, group_path(@group))
= render 'layouts/page', sidebar: 'layouts/nav/group' = render 'layouts/page', sidebar: 'layouts/nav/group'
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- if @project_settings_nav - if @project_settings_nav
= nav_link do = nav_link do
= link_to namespace_project_path(@project.namespace, @project), title: 'Back to project', class: "" do = link_to namespace_project_path(@project.namespace, @project), title: 'Back to project', class: "" do
%i.fa.fa-angle-left %i.fa.fa-caret-square-o-left
%span %span
Back to project Back to project
......
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: @title = render "layouts/head", title: @title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title = render "layouts/head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title
.container.navless-container .container.navless-container
......
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: "Profile" = render "layouts/head", title: "Profile"
%body{class: "#{app_theme} #{theme_type} profile", :'data-page' => body_data_page} %body{class: "#{app_theme} profile", :'data-page' => body_data_page}
= render "layouts/head_panel", title: link_to("Profile", profile_path) = render "layouts/head_panel", title: link_to("Profile", profile_path)
= render 'layouts/page', sidebar: 'layouts/nav/profile' = render 'layouts/page', sidebar: 'layouts/nav/profile'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: @project.name_with_namespace = render "layouts/head", title: @project.name_with_namespace
%body{class: "#{app_theme} #{theme_type} project", :'data-page' => body_data_page, :'data-project-id' => @project.id } %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id }
= render "layouts/head_panel", title: project_title(@project) = render "layouts/head_panel", title: project_title(@project)
= render "layouts/init_auto_complete" = render "layouts/init_auto_complete"
- @project_settings_nav = true - @project_settings_nav = true
......
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: project_head_title = render "layouts/head", title: project_head_title
%body{class: "#{app_theme} #{theme_type} project", :'data-page' => body_data_page, :'data-project-id' => @project.id } %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id }
= render "layouts/head_panel", title: project_title(@project) = render "layouts/head_panel", title: project_title(@project)
= render "layouts/init_auto_complete" = render "layouts/init_auto_complete"
= render 'layouts/page', sidebar: 'layouts/nav/project' = render 'layouts/page', sidebar: 'layouts/nav/project'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: group_head_title = render "layouts/head", title: group_head_title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/public_head_panel", title: link_to(@group.name, group_path(@group)) = render "layouts/public_head_panel", title: link_to(@group.name, group_path(@group))
= render 'layouts/page', sidebar: 'layouts/nav/group' = render 'layouts/page', sidebar: 'layouts/nav/group'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: @project.name_with_namespace = render "layouts/head", title: @project.name_with_namespace
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/public_head_panel", title: project_title(@project) = render "layouts/public_head_panel", title: project_title(@project)
= render 'layouts/page', sidebar: 'layouts/nav/project' = render 'layouts/page', sidebar: 'layouts/nav/project'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: @title = render "layouts/head", title: @title
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/public_head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title = render "layouts/public_head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title
= render 'layouts/page' = render 'layouts/page'
!!! 5 !!! 5
%html{ lang: "en"} %html{ lang: "en"}
= render "layouts/head", title: "Search" = render "layouts/head", title: "Search"
%body{class: "#{app_theme} #{theme_type} application", :'data-page' => body_data_page} %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/head_panel", title: link_to("Search", search_path) = render "layouts/head_panel", title: link_to("Search", search_path)
.container.navless-container .container.navless-container
......
...@@ -14,6 +14,13 @@ ...@@ -14,6 +14,13 @@
= render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data
= render 'shared/commit_message_container', params: params, = render 'shared/commit_message_container', params: params,
placeholder: "Update #{@blob.name}" placeholder: "Update #{@blob.name}"
.form-group.branch
= label_tag 'branch', class: 'control-label' do
Branch
.col-sm-10
= text_field_tag 'new_branch', @ref, class: "form-control"
= hidden_field_tag 'last_commit', @last_commit = hidden_field_tag 'last_commit', @last_commit
= hidden_field_tag 'content', '', id: "file-content" = hidden_field_tag 'content', '', id: "file-content"
= hidden_field_tag 'from_merge_request_id', params[:from_merge_request_id] = hidden_field_tag 'from_merge_request_id', params[:from_merge_request_id]
......
...@@ -4,6 +4,13 @@ ...@@ -4,6 +4,13 @@
= render 'projects/blob/editor', ref: @ref = render 'projects/blob/editor', ref: @ref
= render 'shared/commit_message_container', params: params, = render 'shared/commit_message_container', params: params,
placeholder: 'Add new file' placeholder: 'Add new file'
.form-group.branch
= label_tag 'branch', class: 'control-label' do
Branch
.col-sm-10
= text_field_tag 'new_branch', @ref, class: "form-control"
= hidden_field_tag 'content', '', id: 'file-content' = hidden_field_tag 'content', '', id: 'file-content'
= render 'projects/commit_button', ref: @ref, = render 'projects/commit_button', ref: @ref,
cancel_path: namespace_project_tree_path(@project.namespace, @project, @id) cancel_path: namespace_project_tree_path(@project.namespace, @project, @id)
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
= link_to new_import_gitorious_path do = link_to new_import_gitorious_path do
%i.fa.fa-heart %i.icon-gitorious.icon-gitorious-small
Import projects from Gitorious.org Import projects from Gitorious.org
%hr.prepend-botton-10 %hr.prepend-botton-10
......
class SetMissingLastActivityAt < ActiveRecord::Migration
def up
execute "UPDATE projects SET last_activity_at = updated_at WHERE last_activity_at IS NULL"
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150213121042) do ActiveRecord::Schema.define(version: 20150223022001) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -334,12 +334,12 @@ ActiveRecord::Schema.define(version: 20150213121042) do ...@@ -334,12 +334,12 @@ ActiveRecord::Schema.define(version: 20150213121042) do
t.string "import_url" t.string "import_url"
t.integer "visibility_level", default: 0, null: false t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false t.boolean "archived", default: false, null: false
t.string "avatar"
t.string "import_status" t.string "import_status"
t.float "repository_size", default: 0.0 t.float "repository_size", default: 0.0
t.integer "star_count", default: 0, null: false t.integer "star_count", default: 0, null: false
t.string "import_type" t.string "import_type"
t.string "import_source" t.string "import_source"
t.string "avatar"
end end
add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree
......
...@@ -179,7 +179,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab ...@@ -179,7 +179,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
### Change Nginx settings ### Change Nginx settings
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab but with your settings. * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab but with your settings.
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stablef/lib/support/nginx/gitlab-ssl but with your settings. * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab-ssl but with your settings.
* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. * A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section.
## 9. Start application ## 9. Start application
......
...@@ -10,7 +10,7 @@ to create the first file and open it in the web editor. ...@@ -10,7 +10,7 @@ to create the first file and open it in the web editor.
![web editor 1](web_editor/empty_project.png) ![web editor 1](web_editor/empty_project.png)
Fill in a file name, some content, a commit message and press the commit button. Fill in a file name, some content, a commit message, branch name and press the commit button.
The file will be saved to the repository. The file will be saved to the repository.
![web editor 2](web_editor/new_file.png) ![web editor 2](web_editor/new_file.png)
...@@ -21,6 +21,6 @@ viewing the file. ...@@ -21,6 +21,6 @@ viewing the file.
![web editor 3](web_editor/show_file.png) ![web editor 3](web_editor/show_file.png)
Editing a file is almost the same as creating a new file, Editing a file is almost the same as creating a new file,
with as addition the ability to preview your changes in a separate tab. with as addition the ability to preview your changes in a separate tab. Also you can save your change to another branch by filling out field `branch`
![web editor 3](web_editor/edit_file.png) ![web editor 3](web_editor/edit_file.png)
doc/workflow/web_editor/new_file.png

98.2 KB | W: | H:

doc/workflow/web_editor/new_file.png

83.5 KB | W: | H:

doc/workflow/web_editor/new_file.png
doc/workflow/web_editor/new_file.png
doc/workflow/web_editor/new_file.png
doc/workflow/web_editor/new_file.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -34,6 +34,17 @@ Feature: Project Source Browse Files ...@@ -34,6 +34,17 @@ Feature: Project Source Browse Files
Then I am redirected to the new file Then I am redirected to the new file
And I should see its new content And I should see its new content
@javascript
Scenario: I can create and commit file and specify new branch
Given I click on "new file" link in repo
And I edit code
And I fill the new file name
And I fill the commit message
And I fill the new branch name
And I click on "Commit Changes"
Then I am redirected to the new file on new branch
And I should see its new content
@javascript @tricky @javascript @tricky
Scenario: I can create file in empty repo Scenario: I can create file in empty repo
Given I own an empty project Given I own an empty project
...@@ -83,6 +94,17 @@ Feature: Project Source Browse Files ...@@ -83,6 +94,17 @@ Feature: Project Source Browse Files
Then I am redirected to the ".gitignore" Then I am redirected to the ".gitignore"
And I should see its new content And I should see its new content
@javascript
Scenario: I can edit and commit file to new branch
Given I click on ".gitignore" file in repo
And I click button "Edit"
And I edit code
And I fill the commit message
And I fill the new branch name
And I click on "Commit Changes"
Then I am redirected to the ".gitignore" on new branch
And I should see its new content
@javascript @wip @javascript @wip
Scenario: If I don't change the content of the file I see an error message Scenario: If I don't change the content of the file I see an error message
Given I click on ".gitignore" file in repo Given I click on ".gitignore" file in repo
......
...@@ -69,6 +69,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps ...@@ -69,6 +69,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
fill_in :file_name, with: new_file_name fill_in :file_name, with: new_file_name
end end
step 'I fill the new branch name' do
fill_in :new_branch, with: 'new_branch_name'
end
step 'I fill the new file name with an illegal name' do step 'I fill the new file name with an illegal name' do
fill_in :file_name, with: '.git' fill_in :file_name, with: '.git'
end end
...@@ -148,6 +152,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps ...@@ -148,6 +152,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'master/.gitignore')) expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'master/.gitignore'))
end end
step 'I am redirected to the ".gitignore" on new branch' do
expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'new_branch_name/.gitignore'))
end
step 'I am redirected to the permalink URL' do step 'I am redirected to the permalink URL' do
expect(current_path).to( expect(current_path).to(
eq(namespace_project_blob_path(@project.namespace, @project, eq(namespace_project_blob_path(@project.namespace, @project,
...@@ -161,6 +169,11 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps ...@@ -161,6 +169,11 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
@project.namespace, @project, 'master/' + new_file_name)) @project.namespace, @project, 'master/' + new_file_name))
end end
step 'I am redirected to the new file on new branch' do
expect(current_path).to eq(namespace_project_blob_path(
@project.namespace, @project, 'new_branch_name/' + new_file_name))
end
step "I don't see the permalink link" do step "I don't see the permalink link" do
expect(page).not_to have_link('permalink') expect(page).not_to have_link('permalink')
end end
...@@ -177,7 +190,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps ...@@ -177,7 +190,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
click_link 'add a file' click_link 'add a file'
# Remove pre-receive hook so we can push without auth # Remove pre-receive hook so we can push without auth
FileUtils.rm(File.join(@project.repository.path, 'hooks', 'pre-receive')) FileUtils.rm_f(File.join(@project.repository.path, 'hooks', 'pre-receive'))
end end
private private
......
...@@ -10,7 +10,7 @@ module Gitlab ...@@ -10,7 +10,7 @@ module Gitlab
# Returns false if committing the change fails # Returns false if committing the change fails
# Returns false if pushing from the satellite to bare repo failed or was rejected # Returns false if pushing from the satellite to bare repo failed or was rejected
# Returns true otherwise # Returns true otherwise
def commit!(content, commit_message, encoding) def commit!(content, commit_message, encoding, new_branch = nil)
in_locked_and_timed_satellite do |repo| in_locked_and_timed_satellite do |repo|
prepare_satellite!(repo) prepare_satellite!(repo)
...@@ -42,10 +42,12 @@ module Gitlab ...@@ -42,10 +42,12 @@ module Gitlab
end end
target_branch = new_branch.present? ? "#{ref}:#{new_branch}" : ref
# push commit back to bare repo # push commit back to bare repo
# will raise CommandFailed when push fails # will raise CommandFailed when push fails
begin begin
repo.git.push({ raise: true, timeout: true }, :origin, ref) repo.git.push({ raise: true, timeout: true }, :origin, target_branch)
rescue Grit::Git::CommandFailed => ex rescue Grit::Git::CommandFailed => ex
log_and_raise(PushFailed, ex.message) log_and_raise(PushFailed, ex.message)
end end
......
...@@ -9,7 +9,7 @@ module Gitlab ...@@ -9,7 +9,7 @@ module Gitlab
# Returns false if committing the change fails # Returns false if committing the change fails
# Returns false if pushing from the satellite to bare repo failed or was rejected # Returns false if pushing from the satellite to bare repo failed or was rejected
# Returns true otherwise # Returns true otherwise
def commit!(content, commit_message, encoding) def commit!(content, commit_message, encoding, new_branch = nil)
in_locked_and_timed_satellite do |repo| in_locked_and_timed_satellite do |repo|
prepare_satellite!(repo) prepare_satellite!(repo)
...@@ -45,9 +45,15 @@ module Gitlab ...@@ -45,9 +45,15 @@ module Gitlab
# will raise CommandFailed when commit fails # will raise CommandFailed when commit fails
repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
target_branch = if new_branch.present? && !@project.empty_repo?
"#{ref}:#{new_branch}"
else
"#{current_ref}:#{ref}"
end
# push commit back to bare repo # push commit back to bare repo
# will raise CommandFailed when push fails # will raise CommandFailed when push fails
repo.git.push({ raise: true, timeout: true }, :origin, "#{current_ref}:#{ref}") repo.git.push({ raise: true, timeout: true }, :origin, target_branch)
# everything worked # everything worked
true true
......
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