Commit f5e65e2e authored by Vinnie Okada's avatar Vinnie Okada

Merge branch 'master' into markdown-tags

Merge updated CHANGELOG entries
parents cc29ce49 6cf189f0
...@@ -2,6 +2,20 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -2,6 +2,20 @@ Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased) v 7.10.0 (unreleased)
- Allow HTML tags in Markdown input - Allow HTML tags in Markdown input
- Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
- Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
- extend the commit calendar to show the actual commits made on a date (Hannes Rosenögger)
- Add a service to support external wikis (Hannes Rosenögger)
- List new commits for newly pushed branch in activity view.
- Add changelog, license and contribution guide links to project sidebar.
- Improve diff UI
- Fix alignment of navbar toggle button (Cody Mize)
- Identical look of selectboxes in UI
- Move "Import existing repository by URL" option to button.
- Improve error message when save profile has error.
- Passing the name of pushed ref to CI service (requires GitLab CI 7.9+)
- Add location field to user profile
v 7.9.0 (unreleased) v 7.9.0 (unreleased)
- Add HipChat integration documentation (Stan Hu) - Add HipChat integration documentation (Stan Hu)
...@@ -80,6 +94,8 @@ v 7.9.0 (unreleased) ...@@ -80,6 +94,8 @@ v 7.9.0 (unreleased)
- Ability to unsubscribe/subscribe to issue or merge request - Ability to unsubscribe/subscribe to issue or merge request
- Delete deploy key when last connection to a project is destroyed. - Delete deploy key when last connection to a project is destroyed.
- Fix invalid Atom feeds when using emoji, horizontal rules, or images (Christian Walther) - Fix invalid Atom feeds when using emoji, horizontal rules, or images (Christian Walther)
- Backup of repositories with tar instead of git bundle (only now are git-annex files included in the backup)
- Add canceled status for CI
v 7.8.4 v 7.8.4
- Fix issue_tracker_id substitution in custom issue trackers - Fix issue_tracker_id substitution in custom issue trackers
......
...@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth' ...@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth'
gem 'omniauth-kerberos' gem 'omniauth-kerberos'
gem 'omniauth-gitlab' gem 'omniauth-gitlab'
gem 'omniauth-bitbucket' gem 'omniauth-bitbucket'
gem 'doorkeeper', '2.1.0' gem 'doorkeeper', '2.1.3'
gem "rack-oauth2", "~> 1.0.5" gem "rack-oauth2", "~> 1.0.5"
# Browser detection # Browser detection
...@@ -39,7 +39,7 @@ gem "browser" ...@@ -39,7 +39,7 @@ gem "browser"
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem "gitlab_git", '~> 7.1.0' gem "gitlab_git", '~> 7.1.2'
# Ruby/Rack Git Smart-HTTP Server Handler # Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack' gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
...@@ -48,7 +48,7 @@ gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack' ...@@ -48,7 +48,7 @@ gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap" gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
# Git Wiki # Git Wiki
gem 'gollum-lib', '~> 4.0.0' gem 'gollum-lib', '~> 4.0.2'
# Language detection # Language detection
gem "gitlab-linguist", "~> 3.0.1", require: "linguist" gem "gitlab-linguist", "~> 3.0.1", require: "linguist"
...@@ -180,9 +180,6 @@ gem 'mousetrap-rails' ...@@ -180,9 +180,6 @@ gem 'mousetrap-rails'
# Detect and convert string character encoding # Detect and convert string character encoding
gem 'charlock_holmes' gem 'charlock_holmes'
# Shutting down requests that take too long
gem "slowpoke"
gem "sass-rails", '~> 4.0.2' gem "sass-rails", '~> 4.0.2'
gem "coffee-rails" gem "coffee-rails"
gem "uglifier" gem "uglifier"
......
...@@ -136,8 +136,8 @@ GEM ...@@ -136,8 +136,8 @@ GEM
diff-lcs (1.2.5) diff-lcs (1.2.5)
diffy (3.0.3) diffy (3.0.3)
docile (1.1.5) docile (1.1.5)
doorkeeper (2.1.0) doorkeeper (2.1.3)
railties (>= 3.1) railties (>= 3.2)
dotenv (0.9.0) dotenv (0.9.0)
dropzonejs-rails (0.4.14) dropzonejs-rails (0.4.14)
rails (> 3.1) rails (> 3.1)
...@@ -147,7 +147,6 @@ GEM ...@@ -147,7 +147,6 @@ GEM
enumerize (0.7.0) enumerize (0.7.0)
activesupport (>= 3.2) activesupport (>= 3.2)
equalizer (0.0.8) equalizer (0.0.8)
errbase (0.0.2)
erubis (2.7.0) erubis (2.7.0)
escape_utils (0.2.4) escape_utils (0.2.4)
eventmachine (1.0.4) eventmachine (1.0.4)
...@@ -213,7 +212,7 @@ GEM ...@@ -213,7 +212,7 @@ GEM
mime-types (~> 1.19) mime-types (~> 1.19)
gitlab_emoji (0.1.0) gitlab_emoji (0.1.0)
gemojione (~> 2.0) gemojione (~> 2.0)
gitlab_git (7.1.1) gitlab_git (7.1.2)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.6) charlock_holmes (~> 0.6)
gitlab-linguist (~> 3.0) gitlab-linguist (~> 3.0)
...@@ -224,11 +223,11 @@ GEM ...@@ -224,11 +223,11 @@ GEM
omniauth (~> 1.0) omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1) pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.3) rubyntlm (~> 0.3)
gollum-grit_adapter (0.1.0) gollum-grit_adapter (0.1.3)
gitlab-grit (~> 2.7.1) gitlab-grit (~> 2.7, >= 2.7.1)
gollum-lib (4.0.0) gollum-lib (4.0.2)
github-markup (~> 1.3.1) github-markup (~> 1.3.1)
gollum-grit_adapter (~> 0.1.0) gollum-grit_adapter (~> 0.1, >= 0.1.1)
nokogiri (~> 1.6.4) nokogiri (~> 1.6.4)
rouge (~> 1.7.4) rouge (~> 1.7.4)
sanitize (~> 2.1.0) sanitize (~> 2.1.0)
...@@ -429,7 +428,6 @@ GEM ...@@ -429,7 +428,6 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rack-timeout (0.2.0)
rails (4.1.9) rails (4.1.9)
actionmailer (= 4.1.9) actionmailer (= 4.1.9)
actionpack (= 4.1.9) actionpack (= 4.1.9)
...@@ -482,9 +480,7 @@ GEM ...@@ -482,9 +480,7 @@ GEM
rest-client (1.6.7) rest-client (1.6.7)
mime-types (>= 1.16) mime-types (>= 1.16)
rinku (1.7.3) rinku (1.7.3)
robustly (0.0.3) rouge (1.7.7)
errbase
rouge (1.7.4)
rspec (2.99.0) rspec (2.99.0)
rspec-core (~> 2.99.0) rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0) rspec-expectations (~> 2.99.0)
...@@ -519,7 +515,7 @@ GEM ...@@ -519,7 +515,7 @@ GEM
rubyntlm (0.5.0) rubyntlm (0.5.0)
rubypants (0.2.0) rubypants (0.2.0)
rugged (0.21.4) rugged (0.21.4)
rugments (1.0.0.beta4) rugments (1.0.0.beta5)
safe_yaml (0.9.7) safe_yaml (0.9.7)
sanitize (2.1.0) sanitize (2.1.0)
nokogiri (>= 1.4.4) nokogiri (>= 1.4.4)
...@@ -566,9 +562,6 @@ GEM ...@@ -566,9 +562,6 @@ GEM
temple (~> 0.6.6) temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1) tilt (>= 1.3.3, < 2.1)
slop (3.6.0) slop (3.6.0)
slowpoke (0.0.5)
rack-timeout (>= 0.1.0)
robustly
spinach (0.8.7) spinach (0.8.7)
colorize (= 0.5.8) colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1) gherkin-ruby (>= 0.3.1)
...@@ -690,7 +683,7 @@ DEPENDENCIES ...@@ -690,7 +683,7 @@ DEPENDENCIES
devise (= 3.2.4) devise (= 3.2.4)
devise-async (= 0.9.0) devise-async (= 0.9.0)
diffy (~> 3.0.3) diffy (~> 3.0.3)
doorkeeper (= 2.1.0) doorkeeper (= 2.1.3)
dropzonejs-rails dropzonejs-rails
email_spec email_spec
enumerize enumerize
...@@ -705,10 +698,10 @@ DEPENDENCIES ...@@ -705,10 +698,10 @@ DEPENDENCIES
gitlab-grack (~> 2.0.0.rc2) gitlab-grack (~> 2.0.0.rc2)
gitlab-linguist (~> 3.0.1) gitlab-linguist (~> 3.0.1)
gitlab_emoji (~> 0.1) gitlab_emoji (~> 0.1)
gitlab_git (~> 7.1.0) gitlab_git (~> 7.1.2)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1) gitlab_omniauth-ldap (= 1.2.1)
gollum-lib (~> 4.0.0) gollum-lib (~> 4.0.2)
gon (~> 5.0.0) gon (~> 5.0.0)
grape (~> 0.6.1) grape (~> 0.6.1)
grape-entity (~> 0.4.2) grape-entity (~> 0.4.2)
...@@ -776,7 +769,6 @@ DEPENDENCIES ...@@ -776,7 +769,6 @@ DEPENDENCIES
six six
slack-notifier (~> 1.0.0) slack-notifier (~> 1.0.0)
slim slim
slowpoke
spinach-rails spinach-rails
spring (~> 1.3.1) spring (~> 1.3.1)
spring-commands-rspec (= 1.0.4) spring-commands-rspec (= 1.0.4)
......
...@@ -169,9 +169,7 @@ $ -> ...@@ -169,9 +169,7 @@ $ ->
# Show/hide comments on diff # Show/hide comments on diff
$("body").on "click", ".js-toggle-diff-comments", (e) -> $("body").on "click", ".js-toggle-diff-comments", (e) ->
$(@).find('i'). $(@).toggleClass('active')
toggleClass('fa fa-chevron-down').
toggleClass('fa fa-chevron-up')
$(@).closest(".diff-file").find(".notes_holder").toggle() $(@).closest(".diff-file").find(".notes_holder").toggle()
e.preventDefault() e.preventDefault()
......
$ ->
# Toggle line wrapping in diff.
#
# %div.diff-file
# %input.js-toggle-diff-line-wrap
# %td.line_content
#
$("body").on "click", ".js-toggle-diff-line-wrap", (e) ->
diffFile = $(@).closest(".diff-file")
if $(@).is(":checked")
diffFile.addClass("diff-wrap-lines")
else
diffFile.removeClass("diff-wrap-lines")
...@@ -4,7 +4,7 @@ class @calendar ...@@ -4,7 +4,7 @@ class @calendar
day: "numeric" day: "numeric"
year: "numeric" year: "numeric"
constructor: (timestamps, starting_year, starting_month) -> constructor: (timestamps, starting_year, starting_month, calendar_activities_path) ->
cal = new CalHeatMap() cal = new CalHeatMap()
cal.init cal.init
itemName: ["commit"] itemName: ["commit"]
...@@ -26,5 +26,16 @@ class @calendar ...@@ -26,5 +26,16 @@ class @calendar
] ]
legendCellPadding: 3 legendCellPadding: 3
onClick: (date, count) -> onClick: (date, count) ->
return formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()
return $(".calendar_commit_activity").fadeOut 400
$.ajax
url: calendar_activities_path
data:
date: formated_date
cache: false
dataType: "html"
success: (data) ->
$(".user-calendar-activities").html data
$(".calendar_commit_activity").find(".js-toggle-content").hide()
$(".calendar_commit_activity").fadeIn 400
...@@ -19,6 +19,6 @@ class @Issue ...@@ -19,6 +19,6 @@ class @Issue
$('.issue-details').waitForImages -> $('.issue-details').waitForImages ->
$('.issuable-affix').affix offset: $('.issuable-affix').affix offset:
top: -> top: ->
@top = $('.issue-details').outerHeight(true) + 25 @top = ($('.issuable-affix').offset().top - 70)
bottom: -> bottom: ->
@bottom = $('.footer').outerHeight(true) @bottom = $('.footer').outerHeight(true)
...@@ -23,7 +23,7 @@ class @MergeRequest ...@@ -23,7 +23,7 @@ class @MergeRequest
$('.merge-request-details').waitForImages -> $('.merge-request-details').waitForImages ->
$('.issuable-affix').affix offset: $('.issuable-affix').affix offset:
top: -> top: ->
@top = $('.merge-request-details').outerHeight(true) + 91 @top = ($('.issuable-affix').offset().top - 70)
bottom: -> bottom: ->
@bottom = $('.footer').outerHeight(true) @bottom = $('.footer').outerHeight(true)
...@@ -110,7 +110,7 @@ class @MergeRequest ...@@ -110,7 +110,7 @@ class @MergeRequest
showCiState: (state) -> showCiState: (state) ->
$('.ci_widget').hide() $('.ci_widget').hide()
allowed_states = ["failed", "running", "pending", "success"] allowed_states = ["failed", "canceled", "running", "pending", "success"]
if state in allowed_states if state in allowed_states
$('.ci_widget.ci-' + state).show() $('.ci_widget.ci-' + state).show()
else else
......
...@@ -425,7 +425,7 @@ class @Notes ...@@ -425,7 +425,7 @@ class @Notes
@removeDiscussionNoteForm(form) @removeDiscussionNoteForm(form)
updateVotes: -> updateVotes: ->
(new NotesVotes).updateVotes() true
### ###
Called after an attachment file has been selected. Called after an attachment file has been selected.
......
class @NotesVotes
updateVotes: ->
votes = $("#votes .votes")
notes = $("#notes-list .note .vote")
# only update if there is a vote display
if votes.size()
upvotes = notes.filter(".upvote").size()
downvotes = notes.filter(".downvote").size()
votesCount = upvotes + downvotes
upvotesPercent = (if votesCount then (100.0 / votesCount * upvotes) else 0)
downvotesPercent = (if votesCount then (100.0 - upvotesPercent) else 0)
# change vote bar lengths
votes.find(".bar-success").css "width", upvotesPercent + "%"
votes.find(".bar-danger").css "width", downvotesPercent + "%"
# replace vote numbers
votes.find(".upvotes").text votes.find(".upvotes").text().replace(/\d+/, upvotes)
votes.find(".downvotes").text votes.find(".downvotes").text().replace(/\d+/, downvotes)
// Override Bootstrap variables here (defaults from bootstrap-sass v3.3.3): // Override Bootstrap variables here (defaults from bootstrap-sass v3.3.3):
// For all variables see https://github.com/twbs/bootstrap-sass/blob/master/templates/project/_bootstrap-variables.sass
// //
// Variables // Variables
// -------------------------------------------------- // --------------------------------------------------
...@@ -15,12 +15,6 @@ ...@@ -15,12 +15,6 @@
// $gray: lighten($gray-base, 33.5%) // #555 // $gray: lighten($gray-base, 33.5%) // #555
// $gray-light: lighten($gray-base, 46.7%) // #777 // $gray-light: lighten($gray-base, 46.7%) // #777
// $gray-lighter: lighten($gray-base, 93.5%) // #eee // $gray-lighter: lighten($gray-base, 93.5%) // #eee
$gray-base: #000;
$gray-darker: lighten($gray-base, 13.5%); // #222
$gray-dark: #7b8a8b; // #333
$gray: #95a5a6; // #555
$gray-light: #b4bcc2; // #999
$gray-lighter: #ecf0f1; // #eee
$brand-primary: $gl-primary; $brand-primary: $gl-primary;
$brand-success: $gl-success; $brand-success: $gl-success;
...@@ -31,68 +25,17 @@ $brand-danger: $gl-danger; ...@@ -31,68 +25,17 @@ $brand-danger: $gl-danger;
//== Scaffolding //== Scaffolding
// //
//## Settings for some of the most global styles. $text-color: $gl-text-color;
//** Background color for `<body>`.
// $body-bg: #fff
//** Global text color on `<body>`.
$text-color: $brand-primary;
//** Global textual link color.
$link-color: $gl-link-color; $link-color: $gl-link-color;
//** Link hover color set via `darken()` function.
// $link-hover-color: darken($link-color, 15%)
//** Link hover decoration.
// $link-hover-decoration: underline
//== Typography //== Typography
// //
//## Font, line-height, and color for body text, headings, and more. //## Font, line-height, and color for body text, headings, and more.
// $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif $font-family-sans-serif: $regular_font;
// $font-family-serif: Georgia, "Times New Roman", Times, serif $font-family-monospace: $monospace_font;
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`. $font-size-base: $gl-font-size;
// $font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace
// $font-family-base: $font-family-sans-serif
$font-size-base: $gl-font-size;
// $font-size-large: ceil(($font-size-base * 1.25)) // ~18px
// $font-size-small: ceil(($font-size-base * 0.85)) // ~12px
// $font-size-h1: floor(($font-size-base * 2.6)) // ~36px
// $font-size-h2: floor(($font-size-base * 2.15)) // ~30px
// $font-size-h3: ceil(($font-size-base * 1.7)) // ~24px
// $font-size-h4: ceil(($font-size-base * 1.25)) // ~18px
// $font-size-h5: $font-size-base
// $font-size-h6: ceil(($font-size-base * 0.85)) // ~12px
//** Unit-less `line-height` for use in components like buttons.
// $line-height-base: 1.428571429 // 20/14
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
// $line-height-computed: floor(($font-size-base * $line-height-base)) // ~20px
//** By default, this inherits from the `<body>`.
// $headings-font-family: inherit
// $headings-font-weight: 500
// $headings-line-height: 1.1
// $headings-color: inherit
//== Iconography
//
//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
//** Load fonts from this directory.
// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
// $icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/")
//** File name for all font files.
// $icon-font-name: "glyphicons-halflings-regular"
//** Element ID within SVG icon file.
// $icon-font-svg-id: "glyphicons_halflingsregular"
//== Components //== Components
...@@ -102,348 +45,15 @@ $font-size-base: $gl-font-size; ...@@ -102,348 +45,15 @@ $font-size-base: $gl-font-size;
$padding-base-vertical: 6px; $padding-base-vertical: 6px;
$padding-base-horizontal: 14px; $padding-base-horizontal: 14px;
// $padding-large-vertical: 10px
// $padding-large-horizontal: 16px
// $padding-small-vertical: 5px
// $padding-small-horizontal: 10px
// $padding-xs-vertical: 1px
// $padding-xs-horizontal: 5px
// $line-height-large: 1.3333333 // extra decimals for Win 8.1 Chrome
// $line-height-small: 1.5
// $border-radius-base: 4px
// $border-radius-large: 6px
// $border-radius-small: 3px
//** Global color for active items (e.g., navs or dropdowns).
// $component-active-color: #fff
//** Global background color for active items (e.g., navs or dropdowns).
// $component-active-bg: $brand-primary
//** Width of the `border` for generating carets that indicator dropdowns.
// $caret-width-base: 4px
//** Carets increase slightly in size for larger components.
// $caret-width-large: 5px
//== Tables
//
//## Customizes the `.table` component with basic values, each used across all table variations.
//** Padding for `<th>`s and `<td>`s.
// $table-cell-padding: 8px
//** Padding for cells in `.table-condensed`.
// $table-condensed-cell-padding: 5px
//** Default background color used for all tables.
// $table-bg: transparent
//** Background color used for `.table-striped`.
// $table-bg-accent: #f9f9f9
//** Background color used for `.table-hover`.
// $table-bg-hover: #f5f5f5
// $table-bg-active: $table-bg-hover
//** Border color for table and cell borders.
// $table-border-color: #ddd
//== Buttons
//
//## For each of Bootstrap's buttons, define text, background and border color.
// $btn-font-weight: normal
// $btn-default-color: #333
// $btn-default-bg: #fff
// $btn-default-border: #ccc
// $btn-primary-color: #fff
// $btn-primary-bg: $brand-primary
// $btn-primary-border: darken($btn-primary-bg, 5%)
// $btn-success-color: #fff
// $btn-success-bg: $brand-success
// $btn-success-border: darken($btn-success-bg, 5%)
// $btn-info-color: #fff
// $btn-info-bg: $brand-info
// $btn-info-border: darken($btn-info-bg, 5%)
// $btn-warning-color: #fff
// $btn-warning-bg: $brand-warning
// $btn-warning-border: darken($btn-warning-bg, 5%)
// $btn-danger-color: #fff
// $btn-danger-bg: $brand-danger
// $btn-danger-border: darken($btn-danger-bg, 5%)
// $btn-link-disabled-color: $gray-light
//== Forms //== Forms
// //
//## //##
//** `<input>` background color
// $input-bg: #fff
//** `<input disabled>` background color
// $input-bg-disabled: $gray-lighter
//** Text color for `<input>`s
$input-color: $text-color; $input-color: $text-color;
//** `<input>` border color $input-border: #DDD;
$input-border: #dce4ec;
// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
//** Default `.form-control` border radius
// This has no effect on `<select>`s in some browsers, due to the limited stylability of `<select>`s in CSS.
// $input-border-radius: $border-radius-base
//** Large `.form-control` border radius
// $input-border-radius-large: $border-radius-large
//** Small `.form-control` border radius
// $input-border-radius-small: $border-radius-small
//** Border color for inputs on focus
$input-border-focus: $brand-info; $input-border-focus: $brand-info;
//** Placeholder text color
// $input-color-placeholder: #999
//** Default `.form-control` height
// $input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2)
//** Large `.form-control` height
// $input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2)
//** Small `.form-control` height
// $input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2)
$legend-color: $text-color; $legend-color: $text-color;
// $legend-border-color: #e5e5e5
//** Background color for textual input addons
// $input-group-addon-bg: $gray-lighter
//** Border color for textual input addons
// $input-group-addon-border-color: $input-border
//** Disabled cursor for form controls and buttons.
// $cursor-disabled: not-allowed
//== Dropdowns
//
//## Dropdown menu container and contents.
//** Background for the dropdown menu.
// $dropdown-bg: #fff
//** Dropdown menu `border-color`.
// $dropdown-border: rgba(0,0,0,.15)
//** Dropdown menu `border-color` **for IE8**.
// $dropdown-fallback-border: #ccc
//** Divider color for between dropdown items.
// $dropdown-divider-bg: #e5e5e5
//** Dropdown link text color.
// $dropdown-link-color: $gray-dark
//** Hover color for dropdown links.
// $dropdown-link-hover-color: darken($gray-dark, 5%)
//** Hover background for dropdown links.
// $dropdown-link-hover-bg: #f5f5f5
//** Active dropdown menu item text color.
// $dropdown-link-active-color: $component-active-color
//** Active dropdown menu item background color.
// $dropdown-link-active-bg: $component-active-bg
//** Disabled dropdown menu item background color.
// $dropdown-link-disabled-color: $gray-light
//** Text color for headers within dropdown menus.
// $dropdown-header-color: $gray-light
//** Deprecated `$dropdown-caret-color` as of v3.1.0
// $dropdown-caret-color: #000
//-- Z-index master list
//
// Warning: Avoid customizing these values. They're used for a bird's eye view
// of components dependent on the z-axis and are designed to all work together.
//
// Note: These variables are not generated into the Customizer.
// $zindex-navbar: 1000
// $zindex-dropdown: 1000
// $zindex-popover: 1060
// $zindex-tooltip: 1070
// $zindex-navbar-fixed: 1030
// $zindex-modal: 1040
//== Media queries breakpoints
//
//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
// Extra small screen / phone
//** Deprecated `$screen-xs` as of v3.0.1
// $screen-xs: 480px
//** Deprecated `$screen-xs-min` as of v3.2.0
// $screen-xs-min: $screen-xs
//** Deprecated `$screen-phone` as of v3.0.1
// $screen-phone: $screen-xs-min
// Small screen / tablet
//** Deprecated `$screen-sm` as of v3.0.1
// $screen-sm: 768px
// $screen-sm-min: $screen-sm
//** Deprecated `$screen-tablet` as of v3.0.1
// $screen-tablet: $screen-sm-min
// Medium screen / desktop
//** Deprecated `$screen-md` as of v3.0.1
// $screen-md: 992px
// $screen-md-min: $screen-md
//** Deprecated `$screen-desktop` as of v3.0.1
// $screen-desktop: $screen-md-min
// Large screen / wide desktop
//** Deprecated `$screen-lg` as of v3.0.1
// $screen-lg: 1200px
// $screen-lg-min: $screen-lg
//** Deprecated `$screen-lg-desktop` as of v3.0.1
// $screen-lg-desktop: $screen-lg-min
// So media queries don't overlap when required, provide a maximum
// $screen-xs-max: ($screen-sm-min - 1)
// $screen-sm-max: ($screen-md-min - 1)
// $screen-md-max: ($screen-lg-min - 1)
//== Grid system
//
//## Define your custom responsive grid.
//** Number of columns in the grid.
// $grid-columns: 12
//** Padding between columns. Gets divided in half for the left and right.
// $grid-gutter-width: 30px
// Navbar collapse
//** Point at which the navbar becomes uncollapsed.
// $grid-float-breakpoint: $screen-sm-min
//** Point at which the navbar begins collapsing.
// $grid-float-breakpoint-max: ($grid-float-breakpoint - 1)
//== Container sizes
//
//## Define the maximum width of `.container` for different screen sizes.
// Small screen / tablet
// $container-tablet: (720px + $grid-gutter-width)
//** For `$screen-sm-min` and up.
// $container-sm: $container-tablet
// Medium screen / desktop
// $container-desktop: (940px + $grid-gutter-width)
//** For `$screen-md-min` and up.
// $container-md: $container-desktop
// Large screen / wide desktop
// $container-large-desktop: (1140px + $grid-gutter-width)
//** For `$screen-lg-min` and up.
// $container-lg: $container-large-desktop
//== Navbar
//
//##
// Basics of a navbar
// $navbar-height: 50px
// $navbar-margin-bottom: $line-height-computed
// $navbar-border-radius: $border-radius-base
// $navbar-padding-horizontal: floor(($grid-gutter-width / 2))
// $navbar-padding-vertical: (($navbar-height - $line-height-computed) / 2)
// $navbar-collapse-max-height: 340px
// $navbar-default-color: #777
// $navbar-default-bg: #f8f8f8
// $navbar-default-border: darken($navbar-default-bg, 6.5%)
// Navbar links
// $navbar-default-link-color: #777
// $navbar-default-link-hover-color: #333
// $navbar-default-link-hover-bg: transparent
// $navbar-default-link-active-color: #555
// $navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%)
// $navbar-default-link-disabled-color: #ccc
// $navbar-default-link-disabled-bg: transparent
// Navbar brand label
// $navbar-default-brand-color: $navbar-default-link-color
// $navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%)
// $navbar-default-brand-hover-bg: transparent
// Navbar toggle
// $navbar-default-toggle-hover-bg: #ddd
// $navbar-default-toggle-icon-bar-bg: #888
// $navbar-default-toggle-border-color: #ddd
// Inverted navbar
// Reset inverted navbar basics
// $navbar-inverse-color: lighten($gray-light, 15%)
// $navbar-inverse-bg: #222
// $navbar-inverse-border: darken($navbar-inverse-bg, 10%)
// Inverted navbar links
// $navbar-inverse-link-color: lighten($gray-light, 15%)
// $navbar-inverse-link-hover-color: #fff
// $navbar-inverse-link-hover-bg: transparent
// $navbar-inverse-link-active-color: $navbar-inverse-link-hover-color
// $navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%)
// $navbar-inverse-link-disabled-color: #444
// $navbar-inverse-link-disabled-bg: transparent
// Inverted navbar brand label
// $navbar-inverse-brand-color: $navbar-inverse-link-color
// $navbar-inverse-brand-hover-color: #fff
// $navbar-inverse-brand-hover-bg: transparent
// Inverted navbar toggle
// $navbar-inverse-toggle-hover-bg: #333
// $navbar-inverse-toggle-icon-bar-bg: #fff
// $navbar-inverse-toggle-border-color: #333
//== Navs
//
//##
//=== Shared nav styles
// $nav-link-padding: 10px 15px
// $nav-link-hover-bg: $gray-lighter
// $nav-disabled-link-color: $gray-light
// $nav-disabled-link-hover-color: $gray-light
//== Tabs
// $nav-tabs-border-color: #ddd
// $nav-tabs-link-hover-border-color: $gray-lighter
// $nav-tabs-active-link-hover-bg: $body-bg
// $nav-tabs-active-link-hover-color: $gray
// $nav-tabs-active-link-hover-border-color: #ddd
// $nav-tabs-justified-link-border-color: #ddd
// $nav-tabs-justified-active-link-border-color: $body-bg
//== Pills
// $nav-pills-border-radius: $border-radius-base
// $nav-pills-active-link-hover-bg: $component-active-bg
// $nav-pills-active-link-hover-color: $component-active-color
//== Pagination //== Pagination
...@@ -467,38 +77,10 @@ $pagination-disabled-bg: lighten($brand-success, 15%); ...@@ -467,38 +77,10 @@ $pagination-disabled-bg: lighten($brand-success, 15%);
$pagination-disabled-border: transparent; $pagination-disabled-border: transparent;
//== Pager
//
//##
// $pager-bg: $pagination-bg
// $pager-border: $pagination-border
// $pager-border-radius: 15px
// $pager-hover-bg: $pagination-hover-bg
// $pager-active-bg: $pagination-active-bg
// $pager-active-color: $pagination-active-color
// $pager-disabled-color: $pagination-disabled-color
//== Jumbotron
//
//##
// $jumbotron-padding: 30px
// $jumbotron-color: inherit
// $jumbotron-bg: $gray-lighter
// $jumbotron-heading-color: inherit
// $jumbotron-font-size: ceil(($font-size-base * 1.5))
//== Form states and alerts //== Form states and alerts
// //
//## Define colors for form feedback states and, by default, alerts. //## Define colors for form feedback states and, by default, alerts.
$state-success-text: #fff; $state-success-text: #fff;
$state-success-bg: $brand-success; $state-success-bg: $brand-success;
$state-success-border: $brand-success; $state-success-border: $brand-success;
...@@ -516,316 +98,22 @@ $state-danger-bg: $brand-danger; ...@@ -516,316 +98,22 @@ $state-danger-bg: $brand-danger;
$state-danger-border: $brand-danger; $state-danger-border: $brand-danger;
//== Tooltips
//
//##
//** Tooltip max width
// $tooltip-max-width: 200px
//** Tooltip text color
// $tooltip-color: #fff
//** Tooltip background color
// $tooltip-bg: #000
// $tooltip-opacity: .9
//** Tooltip arrow width
// $tooltip-arrow-width: 5px
//** Tooltip arrow color
// $tooltip-arrow-color: $tooltip-bg
//== Popovers
//
//##
//** Popover body background color
// $popover-bg: #fff
//** Popover maximum width
// $popover-max-width: 276px
//** Popover border color
// $popover-border-color: rgba(0,0,0,.2)
//** Popover fallback border color
// $popover-fallback-border-color: #ccc
//** Popover title background color
// $popover-title-bg: darken($popover-bg, 3%)
//** Popover arrow width
// $popover-arrow-width: 10px
//** Popover arrow color
// $popover-arrow-color: $popover-bg
//** Popover outer arrow width
// $popover-arrow-outer-width: ($popover-arrow-width + 1)
//** Popover outer arrow color
// $popover-arrow-outer-color: fade_in($popover-border-color, 0.05)
//** Popover outer arrow fallback color
// $popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%)
//== Labels
//
//##
//** Default label background color
// $label-default-bg: $gray-light
//** Primary label background color
// $label-primary-bg: $brand-primary
//** Success label background color
// $label-success-bg: $brand-success
//** Info label background color
// $label-info-bg: $brand-info
//** Warning label background color
// $label-warning-bg: $brand-warning
//** Danger label background color
// $label-danger-bg: $brand-danger
//** Default label text color
// $label-color: #fff
//** Default text color of a linked label
// $label-link-hover-color: #fff
//== Modals
//
//##
//** Padding applied to the modal body
// $modal-inner-padding: 15px
//** Padding applied to the modal title
// $modal-title-padding: 15px
//** Modal title line-height
// $modal-title-line-height: $line-height-base
//** Background color of modal content area
// $modal-content-bg: #fff
//** Modal content border color
// $modal-content-border-color: rgba(0,0,0,.2)
//** Modal content border color **for IE8**
// $modal-content-fallback-border-color: #999
//** Modal backdrop background color
// $modal-backdrop-bg: #000
//** Modal backdrop opacity
// $modal-backdrop-opacity: .5
//** Modal header border color
// $modal-header-border-color: #e5e5e5
//** Modal footer border color
// $modal-footer-border-color: $modal-header-border-color
// $modal-lg: 900px
// $modal-md: 600px
// $modal-sm: 300px
//== Alerts //== Alerts
// //
//## Define alert colors, border radius, and padding. //## Define alert colors, border radius, and padding.
// $alert-padding: 15px
$alert-border-radius: 0; $alert-border-radius: 0;
// $alert-link-font-weight: bold
// $alert-success-bg: $state-success-bg
// $alert-success-text: $state-success-text
// $alert-success-border: $state-success-border
// $alert-info-bg: $state-info-bg
// $alert-info-text: $state-info-text
// $alert-info-border: $state-info-border
// $alert-warning-bg: $state-warning-bg
// $alert-warning-text: $state-warning-text
// $alert-warning-border: $state-warning-border
// $alert-danger-bg: $state-danger-bg
// $alert-danger-text: $state-danger-text
// $alert-danger-border: $state-danger-border
//== Progress bars
//
//##
//** Background color of the whole progress component
// $progress-bg: #f5f5f5
//** Progress bar text color
// $progress-bar-color: #fff
//** Variable for setting rounded corners on progress bar.
// $progress-border-radius: $border-radius-base
//** Default progress bar color
// $progress-bar-bg: $brand-primary
//** Success progress bar color
// $progress-bar-success-bg: $brand-success
//** Warning progress bar color
// $progress-bar-warning-bg: $brand-warning
//** Danger progress bar color
// $progress-bar-danger-bg: $brand-danger
//** Info progress bar color
// $progress-bar-info-bg: $brand-info
//== List group
//
//##
//** Background color on `.list-group-item`
// $list-group-bg: #fff
//** `.list-group-item` border color
// $list-group-border: #ddd
//** List group border radius
// $list-group-border-radius: $border-radius-base
//** Background color of single list items on hover
// $list-group-hover-bg: #f5f5f5
//** Text color of active list items
// $list-group-active-color: $component-active-color
//** Background color of active list items
// $list-group-active-bg: $component-active-bg
//** Border color of active list elements
// $list-group-active-border: $list-group-active-bg
//** Text color for content within active list items
// $list-group-active-text-color: lighten($list-group-active-bg, 40%)
//** Text color of disabled list items
// $list-group-disabled-color: $gray-light
//** Background color of disabled list items
// $list-group-disabled-bg: $gray-lighter
//** Text color for content within disabled list items
// $list-group-disabled-text-color: $list-group-disabled-color
// $list-group-link-color: #555
// $list-group-link-hover-color: $list-group-link-color
// $list-group-link-heading-color: #333
//== Panels //== Panels
// //
//## //##
// $panel-bg: #fff
// $panel-body-padding: 15px
// $panel-heading-padding: 10px 15px
// $panel-footer-padding: $panel-heading-padding
$panel-border-radius: 0; $panel-border-radius: 0;
//** Border color for elements within panels
// $panel-inner-border: #ddd
// $panel-footer-bg: #f5f5f5
$panel-default-text: $text-color; $panel-default-text: $text-color;
$panel-default-border: $border-color; $panel-default-border: $border-color;
$panel-default-heading-bg: $background-color; $panel-default-heading-bg: $background-color;
// $panel-primary-text: #fff
// $panel-primary-border: $brand-primary
// $panel-primary-heading-bg: $brand-primary
// $panel-success-text: $state-success-text
// $panel-success-border: $state-success-border
// $panel-success-heading-bg: $state-success-bg
// $panel-info-text: $state-info-text
// $panel-info-border: $state-info-border
// $panel-info-heading-bg: $state-info-bg
// $panel-warning-text: $state-warning-text
// $panel-warning-border: $state-warning-border
// $panel-warning-heading-bg: $state-warning-bg
// $panel-danger-text: $state-danger-text
// $panel-danger-border: $state-danger-border
// $panel-danger-heading-bg: $state-danger-bg
//== Thumbnails
//
//##
//** Padding around the thumbnail image
// $thumbnail-padding: 4px
//** Thumbnail background color
// $thumbnail-bg: $body-bg
//** Thumbnail border color
// $thumbnail-border: #ddd
//** Thumbnail border radius
// $thumbnail-border-radius: $border-radius-base
//** Custom text color for thumbnail captions
// $thumbnail-caption-color: $text-color
//** Padding around the thumbnail caption
// $thumbnail-caption-padding: 9px
//== Wells
//
//##
$well-bg: $gray-lighter;
$well-border: transparent;
//== Badges
//
//##
// $badge-color: #fff
//** Linked badge text color on hover
// $badge-link-hover-color: #fff
// $badge-bg: $gray-light
//** Badge text color in active nav link
// $badge-active-color: $link-color
//** Badge background color in active nav link
// $badge-active-bg: #fff
// $badge-font-weight: bold
// $badge-line-height: 1
// $badge-border-radius: 10px
//== Breadcrumbs
//
//##
// $breadcrumb-padding-vertical: 8px
// $breadcrumb-padding-horizontal: 15px
//** Breadcrumb background color
// $breadcrumb-bg: #f5f5f5
//** Breadcrumb text color
// $breadcrumb-color: #ccc
//** Text color of current page in the breadcrumb
// $breadcrumb-active-color: $gray-light
//** Textual separator for between breadcrumb elements
// $breadcrumb-separator: "/"
//== Carousel
//
//##
// $carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6)
// $carousel-control-color: #fff
// $carousel-control-width: 15%
// $carousel-control-opacity: .5
// $carousel-control-font-size: 20px
// $carousel-indicator-active-bg: #fff
// $carousel-indicator-border-color: #fff
// $carousel-caption-color: #fff
//== Close
//
//##
// $close-font-weight: bold
// $close-color: #000
// $close-text-shadow: 0 1px 0 #fff
//== Code //== Code
...@@ -837,34 +125,3 @@ $code-bg: #f9f2f4; ...@@ -837,34 +125,3 @@ $code-bg: #f9f2f4;
$kbd-color: #fff; $kbd-color: #fff;
$kbd-bg: #333; $kbd-bg: #333;
$pre-bg: $gray-lighter;
$pre-color: $text-color;
$pre-border-color: #ccc;
// $pre-scrollable-max-height: 340px
//== Type
//
//##
//** Horizontal offset for forms and lists.
// $component-offset-horizontal: 180px
//** Text muted color
// $text-muted: $gray-light
//** Abbreviations and acronyms border color
// $abbr-border-color: $gray-light
//** Headings small color
$headings-small-color: $gray-dark;
//** Blockquote small color
// $blockquote-small-color: $gray-light
//** Blockquote font size
// $blockquote-font-size: ($font-size-base * 1.25)
//** Blockquote border color
// $blockquote-border-color: $gray-lighter
//** Page header border color
// $page-header-border-color: $gray-lighter
//** Width of horizontal description list titles
// $dl-horizontal-offset: $component-offset-horizontal
//** Horizontal line color.
// $hr-border: $gray-lighter
$style_color: #474D57; $style_color: #474D57;
$hover: #FFF3EB; $hover: #FFF3EB;
$gl-text-color: #222222;
$gl-link-color: #446e9b; $gl-link-color: #446e9b;
$nprogress-color: #c0392b; $nprogress-color: #c0392b;
$gl-font-size: 14px; $gl-font-size: 14px;
...@@ -8,23 +9,18 @@ $sidebar_width: 230px; ...@@ -8,23 +9,18 @@ $sidebar_width: 230px;
$avatar_radius: 50%; $avatar_radius: 50%;
$code_font_size: 13px; $code_font_size: 13px;
$code_line_height: 1.5; $code_line_height: 1.5;
$border-color: #dce4ec; $border-color: #E5E5E5;
$background-color: #ECF0F1; $background-color: #f5f5f5;
/* /*
* State colors: * State colors:
*/ */
$gl-success: #019875;
$gl-danger: #d9534f;
$gl-primary: #446e9b; $gl-primary: #446e9b;
$gl-success: #019875;
$gl-info: #029ACF; $gl-info: #029ACF;
$gl-warning: #EB9532; $gl-warning: #EB9532;
$gl-danger: #d9534f;
$gl-primary: #2C3E50;
$gl-success: #18BC9C;
$gl-info: #3498DB;
$gl-warning: #F39C12;
$gl-danger: #E74C3C;
/* /*
* Commit Diff Colors * Commit Diff Colors
*/ */
......
.calendar_onclick_placeholder { .user-calendar-activities {
padding: 0 0 2px 0;
} .calendar_commit_activity {
padding: 5px 0 0;
.calendar_commit_activity { }
padding: 5px 0 0;
} .calendar_onclick_hr {
padding: 0;
.calendar_onclick_second { margin: 10px 0;
font-size: 14px; }
display: block;
} .calendar_commit_date {
color: #999;
.calendar_onclick_hr { }
padding: 0;
margin: 10px 0; .calendar_activity_summary {
} font-size: 14px;
}
.calendar_commit_date { .str-truncated {
color: #999; max-width: 70%;
} }
.calendar_activity_summary { .text-expander {
font-size: 14px; background: #eee;
color: #555;
padding: 0 5px;
cursor: pointer;
margin-left: 4px;
&:hover {
background-color: #ddd;
}
}
.commit-row-message {
color: #333;
&:hover {
color: #444;
text-decoration: underline;
}
}
} }
/** /**
* This overwrites the default values of the cal-heatmap gem * This overwrites the default values of the cal-heatmap gem
*/ */
......
...@@ -355,3 +355,22 @@ table { ...@@ -355,3 +355,22 @@ table {
bottom: 20px !important; bottom: 20px !important;
left: 20px !important; left: 20px !important;
} }
.header-with-avatar {
h3 {
margin: 0;
font-weight: bold;
}
.username {
font-size: 18px;
color: #666;
margin-top: 8px;
}
.description {
font-size: 16px;
color: #666;
margin-top: 8px;
}
}
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
} }
.author, .author,
.blame_commit { .blame_commit {
background: #f5f5f5; background: $background-color;
vertical-align: top; vertical-align: top;
} }
.lines { .lines {
......
...@@ -29,8 +29,8 @@ fieldset legend { ...@@ -29,8 +29,8 @@ fieldset legend {
padding: 17px 20px 18px; padding: 17px 20px 18px;
margin-top: 18px; margin-top: 18px;
margin-bottom: 18px; margin-bottom: 18px;
background-color: #ecf0f1; background-color: $background-color;
border-top: 1px solid #e5e5e5; border-top: 1px solid $border-color;
} }
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
color: #8a6d3b; color: #8a6d3b;
} }
&.smoke { background-color: #f5f5f5; } &.smoke { background-color: $background-color; }
&:hover { &:hover {
background: $hover; background: $hover;
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
border-bottom: none; border-bottom: none;
&.bottom { &.bottom {
background: #f5f5f5; background: $background-color;
} }
} }
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
p { p {
padding-top: 1px; padding-top: 1px;
margin: 0; margin: 0;
color: #222; color: $gray-dark;
img { img {
position: relative; position: relative;
top: 3px; top: 3px;
...@@ -74,9 +74,10 @@ ...@@ -74,9 +74,10 @@
} }
.row_title { .row_title {
color: #444; color: $gray-dark;
&:hover { &:hover {
color: #444; color: $text-color;
text-decoration: underline; text-decoration: underline;
} }
} }
......
.page-with-sidebar { .page-with-sidebar {
background: #F5F5F5; background: $background-color;
.sidebar-wrapper { .sidebar-wrapper {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
height: 100%; height: 100%;
border-right: 1px solid #EAEAEA; border-right: 1px solid $border-color;
} }
} }
.sidebar-wrapper { .sidebar-wrapper {
z-index: 99; z-index: 99;
background: #F5F5F5; background: $background-color;
} }
.content-wrapper { .content-wrapper {
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
.nav-sidebar li { .nav-sidebar li {
&.active a { &.active a {
color: #333; color: $text-color;
background: #FFF !important; background: #FFF !important;
font-weight: bold; font-weight: bold;
border: 1px solid #EEE; border: 1px solid #EEE;
...@@ -52,32 +52,31 @@ ...@@ -52,32 +52,31 @@
} }
i { i {
color: #444; color: $text-color;
} }
} }
} }
.nav-sidebar li { .nav-sidebar li {
&.separate-item { &.separate-item {
border-top: 1px solid #ddd; border-top: 1px solid $border-color;
padding-top: 10px; padding-top: 10px;
margin-top: 10px; margin-top: 10px;
} }
a { a {
color: #555; color: $gray;
display: block; display: block;
text-decoration: none; text-decoration: none;
padding: 8px 15px; padding: 8px 15px;
font-size: 13px; font-size: 13px;
line-height: 20px; line-height: 20px;
text-shadow: 0 1px 2px #FFF;
padding-left: 20px; padding-left: 20px;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
color: #333; color: $text-color;
background: #EEE; background: $border-color;
} }
&:active, &:focus { &:active, &:focus {
...@@ -86,7 +85,7 @@ ...@@ -86,7 +85,7 @@
i { i {
width: 20px; width: 20px;
color: #888; color: $gray-light;
margin-right: 23px; margin-right: 23px;
} }
} }
...@@ -156,18 +155,17 @@ ...@@ -156,18 +155,17 @@
position: fixed; position: fixed;
top: 46px; top: 46px;
padding: 5px 13px 5px 13px; padding: 5px 13px 5px 13px;
left: 197px; left: 198px;
font-size: 13px; font-size: 13px;
background: #EEE; background: transparent;
color: black; color: black;
border-left: 1px solid rgba(0,0,0,0.035); border-left: 1px solid $border-color;
border-right: 1px solid rgba(0,0,0,0.035); border-bottom: 1px solid $border-color;
} }
.collapse-nav a:hover { .collapse-nav a:hover {
text-decoration: none; text-decoration: none;
color: #333; background: #f2f6f7;
background: #eaeaea;
} }
@media (max-width: $screen-md-max) { @media (max-width: $screen-md-max) {
......
...@@ -46,55 +46,13 @@ ...@@ -46,55 +46,13 @@
} }
} }
select { .select2-container {
&.select2 { width: 100% !important;
width: 100px;
}
&.select2-sm {
width: 100px;
}
}
@media (min-width: $screen-sm-min) {
select {
&.select2 {
width: 150px;
}
&.select2-sm {
width: 120px;
}
}
} }
/* Medium devices (desktops, 992px and up) */
@media (min-width: $screen-md-min) {
select {
&.select2 {
width: 170px;
}
&.select2-sm {
width: 140px;
}
}
}
/* Large devices (large desktops, 1200px and up) */
@media (min-width: $screen-lg-min) {
select {
&.select2 {
width: 200px;
}
&.select2-sm {
width: 150px;
}
}
}
/** Branch/tag selector **/ /** Branch/tag selector **/
.project-refs-form .select2-container { .project-refs-form .select2-container {
margin-right: 10px; width: 160px !important;
} }
.ajax-users-dropdown, .ajax-project-users-dropdown { .ajax-users-dropdown, .ajax-project-users-dropdown {
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
.timeline-content { .timeline-content {
position: relative; position: relative;
background: #f5f5f6; background: $background-color;
padding: 10px 15px; padding: 10px 15px;
margin-left: 60px; margin-left: 60px;
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
height: 0; height: 0;
border-style: solid; border-style: solid;
border-width: 9px 9px 9px 0; border-width: 9px 9px 9px 0;
border-color: transparent #f5f5f6 transparent transparent; border-color: transparent $background-color transparent transparent;
left: 0; left: 0;
top: 10px; top: 10px;
margin-left: -9px; margin-left: -9px;
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
*/ */
.page-title { .page-title {
margin-top: 0px; margin-top: 0px;
color: #333;
line-height: 1.5; line-height: 1.5;
font-weight: normal; font-weight: normal;
margin-bottom: 5px; margin-bottom: 5px;
...@@ -16,7 +15,7 @@ pre { ...@@ -16,7 +15,7 @@ pre {
&.dark { &.dark {
background: #333; background: #333;
color: #f5f5f5; color: $background-color;
} }
} }
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
font-size: 14px; font-size: 14px;
line-height: 24px; line-height: 24px;
.str-truncated {
max-width: 72%;
}
a { a {
display: block; display: block;
padding: 8px 15px; padding: 8px 15px;
...@@ -87,16 +91,3 @@ ...@@ -87,16 +91,3 @@
margin-right: 5px; margin-right: 5px;
width: 16px; width: 16px;
} }
.dash-new-project {
background: $gl-success;
border: 1px solid $gl-success;
a {
color: #FFF;
}
}
.dash-list .str-truncated {
max-width: 72%;
}
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
z-index: 10; z-index: 10;
> span { > span {
@include str-truncated(65%);
font-family: $monospace_font; font-family: $monospace_font;
word-break: break-all;
margin-right: 200px;
display: block;
} }
.diff-btn-group { .diff-btn-group {
...@@ -89,7 +91,7 @@ ...@@ -89,7 +91,7 @@
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: none; border: none;
background: #F5F5F5; background: $background-color;
color: rgba(0,0,0,0.3); color: rgba(0,0,0,0.3);
padding: 0px 5px; padding: 0px 5px;
border-right: 1px solid $border-color; border-right: 1px solid $border-color;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
} }
.editor-ref { .editor-ref {
background: #f5f5f5; background: $background-color;
padding: 11px 15px; padding: 11px 15px;
border-right: 1px solid #CCC; border-right: 1px solid #CCC;
display: inline-block; display: inline-block;
......
...@@ -154,10 +154,12 @@ ...@@ -154,10 +154,12 @@
overflow: auto; overflow: auto;
.event-last-push-text { .event-last-push-text {
@include str-truncated(100%); @include str-truncated(100%);
padding: 5px 0;
font-size: 13px;
float:left; float:left;
margin-right: -150px; margin-right: -150px;
padding-right: 150px; padding-right: 150px;
line-height: 24px; line-height: 20px;
} }
} }
...@@ -188,7 +190,7 @@ ...@@ -188,7 +190,7 @@
li a { li a {
font-size: 13px; font-size: 13px;
padding: 5px 10px; padding: 5px 10px;
background: rgba(0,0,0,0.045); background: $background-color;
margin-left: 4px; margin-left: 4px;
} }
} }
.new-group-member-holder { .new-group-member-holder {
margin-top: 50px; margin-top: 50px;
background: #f9f9f9;
padding-top: 20px; padding-top: 20px;
} }
......
...@@ -31,7 +31,7 @@ header { ...@@ -31,7 +31,7 @@ header {
.navbar-toggle { .navbar-toggle {
color: $style_color; color: $style_color;
margin: 0 -15px 0 0; margin: 0;
padding: 10px; padding: 10px;
border-radius: 0; border-radius: 0;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
} }
.issuable-context-title { .issuable-context-title {
font-size: 15px; font-size: 14px;
line-height: 1.4; line-height: 1.4;
margin-bottom: 5px; margin-bottom: 5px;
...@@ -39,3 +39,9 @@ ...@@ -39,3 +39,9 @@
margin-right: 4px; margin-right: 4px;
} }
} }
.issuable-affix .context {
font-size: 13px;
.btn { font-size: 13px; }
}
...@@ -59,33 +59,34 @@ ...@@ -59,33 +59,34 @@
} }
} }
@media (min-width: 800px) { .issues_filters select { width: 160px; } } @media (min-width: 800px) {
@media (min-width: 1200px) { .issues_filters select { width: 220px; } } .issues_bulk_update {
select, .select2-container {
width: 120px !important;
display: inline-block;
}
}
}
@media (min-width: 800px) { .issues_bulk_update .select2-container { min-width: 120px; } } @media (min-width: 1200px) {
@media (min-width: 1200px) { .issues_bulk_update .select2-container { min-width: 160px; } } .issues_bulk_update {
select, .select2-container {
width: 160px !important;
display: inline-block;
}
}
}
.issues_bulk_update { .issues_bulk_update {
.select2-container .select2-choice { .select2-container .select2-choice {
color: #444 !important; color: #444 !important;
font-weight: 500;
} }
} }
#update_status {
width: 100px;
}
.participants { .participants {
margin-bottom: 20px; margin-bottom: 20px;
} }
.issues_bulk_update {
.select2-container {
text-shadow: none;
}
}
.issue-search-form { .issue-search-form {
margin: 0; margin: 0;
height: 24px; height: 24px;
...@@ -177,6 +178,6 @@ h2.issue-title { ...@@ -177,6 +178,6 @@ h2.issue-title {
font-weight: bold; font-weight: bold;
} }
.context .select2-container { .issue-form .select2-container {
width: 100% !important; width: 250px !important;
} }
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
font-size: 15px; font-size: 15px;
border-bottom: 1px solid #BBB; border-bottom: 1px solid #BBB;
color: #777; color: #777;
background-color: #F5F5F5; background-color: $background-color;
&.ci-success { &.ci-success {
color: $gl-success; color: $gl-success;
...@@ -155,6 +155,12 @@ ...@@ -155,6 +155,12 @@
background-color: #FAF1F1; background-color: #FAF1F1;
} }
&.ci-canceled {
color: $gl-warning;
border-color: $gl-danger;
background-color: #FAF5F1;
}
&.ci-error { &.ci-error {
color: $gl-danger; color: $gl-danger;
border-color: $gl-danger; border-color: $gl-danger;
...@@ -194,3 +200,7 @@ ...@@ -194,3 +200,7 @@
} }
} }
} }
.merge-request-form .select2-container {
width: 250px !important;
}
...@@ -41,11 +41,6 @@ ...@@ -41,11 +41,6 @@
} }
} }
.user-show-username {
font-weight: 200;
color: #666;
}
/* /*
* Appearance settings * Appearance settings
* *
......
...@@ -49,16 +49,20 @@ ...@@ -49,16 +49,20 @@
@extend .clearfix; @extend .clearfix;
margin-bottom: 15px; margin-bottom: 15px;
.project-home-desc,
.star-fork-buttons {
font-size: 16px;
line-height: 1.3;
}
.project-home-desc { .project-home-desc {
float: left; float: left;
color: #666; color: #666;
font-size: 16px;
} }
.star-fork-buttons { .star-fork-buttons {
float: right; float: right;
min-width: 200px; min-width: 200px;
font-size: 14px;
font-weight: bold; font-weight: bold;
.star-buttons, .fork-buttons { .star-buttons, .fork-buttons {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
} }
&.selected { &.selected {
td { td {
background: #f5f5f5; background: $background-color;
border-top: 1px solid #EEE; border-top: 1px solid #EEE;
border-bottom: 1px solid #EEE; border-bottom: 1px solid #EEE;
} }
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
.tree-ref-holder { .tree-ref-holder {
float: left; float: left;
margin-right: 6px; margin-right: 15px;
.select2-container .select2-choice, .select2-container.select2-drop-above .select2-choice { .select2-container .select2-choice, .select2-container.select2-drop-above .select2-choice {
padding: 4px 12px; padding: 4px 12px;
......
.votes {
font-size: 13px;
line-height: 15px;
.progress {
height: 4px;
margin: 0;
.bar {
float: left;
height: 100%;
}
.bar-success {
@include linear-gradient(#62C462, #51A351);
background-color: #468847;
}
.bar-danger {
@include linear-gradient(#EE5F5B, #BD362F);
background-color: #B94A48;
}
}
.upvotes {
display: inline-block;
color: #468847;
}
.downvotes {
display: inline-block;
color: #B94A48;
}
}
.votes-block {
margin: 6px;
.downvotes {
float: right;
}
}
.votes-inline { .votes-inline {
display: inline-block; display: inline-block;
margin: 0 8px; margin: 0 8px;
} }
...@@ -25,7 +25,8 @@ class ProfilesController < ApplicationController ...@@ -25,7 +25,8 @@ class ProfilesController < ApplicationController
if @user.update_attributes(user_params) if @user.update_attributes(user_params)
flash[:notice] = "Profile was successfully updated" flash[:notice] = "Profile was successfully updated"
else else
flash[:alert] = "Failed to update profile" messages = @user.errors.full_messages.uniq.join('. ')
flash[:alert] = "Failed to update profile. #{messages}"
end end
respond_to do |format| respond_to do |format|
...@@ -68,7 +69,7 @@ class ProfilesController < ApplicationController ...@@ -68,7 +69,7 @@ class ProfilesController < ApplicationController
params.require(:user).permit( params.require(:user).permit(
:email, :password, :password_confirmation, :bio, :name, :username, :email, :password, :password_confirmation, :bio, :name, :username,
:skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id,
:avatar, :hide_no_ssh_key, :hide_no_password :avatar, :hide_no_ssh_key, :hide_no_password, :location
) )
end end
end end
...@@ -160,10 +160,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -160,10 +160,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def ci_status def ci_status
ci_service = @merge_request.source_project.ci_service ci_service = @merge_request.source_project.ci_service
status = ci_service.commit_status(merge_request.last_commit.sha) status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch)
if ci_service.respond_to?(:commit_coverage) if ci_service.respond_to?(:commit_coverage)
coverage = ci_service.commit_coverage(merge_request.last_commit.sha) coverage = ci_service.commit_coverage(merge_request.last_commit.sha, merge_request.source_branch)
end end
response = { response = {
......
...@@ -53,7 +53,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -53,7 +53,7 @@ class Projects::ServicesController < Projects::ApplicationController
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel, :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels, :colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events, :push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :send_from_committer_email, :disable_diffs :note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url
) )
end end
end end
...@@ -2,34 +2,34 @@ class SearchController < ApplicationController ...@@ -2,34 +2,34 @@ class SearchController < ApplicationController
include SearchHelper include SearchHelper
def show def show
return if params[:search].nil? || params[:search].blank?
@project = Project.find_by(id: params[:project_id]) if params[:project_id].present? @project = Project.find_by(id: params[:project_id]) if params[:project_id].present?
@group = Group.find_by(id: params[:group_id]) if params[:group_id].present? @group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
@scope = params[:scope] @scope = params[:scope]
@show_snippets = params[:snippets].eql? 'true' @show_snippets = params[:snippets].eql? 'true'
@search_results = if @project @search_results =
return access_denied! unless can?(current_user, :download_code, @project) if @project
return access_denied! unless can?(current_user, :download_code, @project)
unless %w(blobs notes issues merge_requests wiki_blobs).
include?(@scope) unless %w(blobs notes issues merge_requests wiki_blobs).
@scope = 'blobs' include?(@scope)
end @scope = 'blobs'
end
Search::ProjectService.new(@project, current_user, params).execute
elsif @show_snippets Search::ProjectService.new(@project, current_user, params).execute
unless %w(snippet_blobs snippet_titles).include?(@scope) elsif @show_snippets
@scope = 'snippet_blobs' unless %w(snippet_blobs snippet_titles).include?(@scope)
end @scope = 'snippet_blobs'
end
Search::SnippetService.new(current_user, params).execute
else Search::SnippetService.new(current_user, params).execute
unless %w(projects issues merge_requests).include?(@scope) else
@scope = 'projects' unless %w(projects issues merge_requests).include?(@scope)
end @scope = 'projects'
end
Search::GlobalService.new(current_user, params).execute Search::GlobalService.new(current_user, params).execute
end end
@objects = @search_results.objects(@scope, params[:page]) @objects = @search_results.objects(@scope, params[:page])
end end
......
...@@ -32,6 +32,7 @@ class UsersController < ApplicationController ...@@ -32,6 +32,7 @@ class UsersController < ApplicationController
def calendar def calendar
projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids) projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
calendar = Gitlab::CommitsCalendar.new(projects, @user) calendar = Gitlab::CommitsCalendar.new(projects, @user)
@timestamps = calendar.timestamps @timestamps = calendar.timestamps
@starting_year = calendar.starting_year @starting_year = calendar.starting_year
...@@ -40,6 +41,24 @@ class UsersController < ApplicationController ...@@ -40,6 +41,24 @@ class UsersController < ApplicationController
render 'calendar', layout: false render 'calendar', layout: false
end end
def calendar_activities
projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
date = Date.parse(params[:date]) rescue nil
if date
@calendar_activities = Gitlab::CommitsCalendar.get_commits_for_date(projects, @user, date)
else
@calendar_activities = {}
end
# get the total number of unique commits
@commit_count = @calendar_activities.values.flatten.map(&:id).uniq.count
@calendar_date = date
render 'calendar_activities', layout: false
end
def determine_layout def determine_layout
if current_user if current_user
'navless' 'navless'
......
...@@ -96,7 +96,7 @@ module EventsHelper ...@@ -96,7 +96,7 @@ module EventsHelper
end end
end end
elsif event.push? elsif event.push?
if event.push_with_commits? if event.push_with_commits? && event.md_ref?
if event.commits_count > 1 if event.commits_count > 1
namespace_project_compare_url(event.project.namespace, event.project, namespace_project_compare_url(event.project.namespace, event.project,
from: event.commit_from, to: from: event.commit_from, to:
......
module ExternalWikiHelper
def get_project_wiki_path(project)
external_wiki_service = project.services.
select { |service| service.to_param == 'external_wiki' }.first
if external_wiki_service.present? && external_wiki_service.active?
external_wiki_service.properties['external_wiki_url']
else
namespace_project_wiki_path(project.namespace, project, :home)
end
end
end
...@@ -47,6 +47,5 @@ module GitlabRoutingHelper ...@@ -47,6 +47,5 @@ module GitlabRoutingHelper
def project_snippet_url(entity, *args) def project_snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args) namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
end end
end end
...@@ -35,7 +35,7 @@ module MergeRequestsHelper ...@@ -35,7 +35,7 @@ module MergeRequestsHelper
end end
def ci_build_details_path(merge_request) def ci_build_details_path(merge_request)
merge_request.source_project.ci_service.build_page(merge_request.last_commit.sha) merge_request.source_project.ci_service.build_page(merge_request.last_commit.sha, merge_request.source_branch)
end end
def merge_path_description(merge_request, separator) def merge_path_description(merge_request, separator)
......
...@@ -232,12 +232,45 @@ module ProjectsHelper ...@@ -232,12 +232,45 @@ module ProjectsHelper
end end
def contribution_guide_url(project) def contribution_guide_url(project)
if project && project.repository.contribution_guide if project && contribution_guide = project.repository.contribution_guide
namespace_project_blob_path( namespace_project_blob_path(
project.namespace, project.namespace,
project, project,
tree_join(project.default_branch, tree_join(project.default_branch,
project.repository.contribution_guide.name) contribution_guide.name)
)
end
end
def changelog_url(project)
if project && changelog = project.repository.changelog
namespace_project_blob_path(
project.namespace,
project,
tree_join(project.default_branch,
changelog.name)
)
end
end
def license_url(project)
if project && license = project.repository.license
namespace_project_blob_path(
project.namespace,
project,
tree_join(project.default_branch,
license.name)
)
end
end
def version_url(project)
if project && version = project.repository.version
namespace_project_blob_path(
project.namespace,
project,
tree_join(project.default_branch,
version.name)
) )
end end
end end
......
...@@ -247,7 +247,7 @@ class Event < ActiveRecord::Base ...@@ -247,7 +247,7 @@ class Event < ActiveRecord::Base
end end
def push_with_commits? def push_with_commits?
md_ref? && commits.any? && commit_from && commit_to !commits.empty? && commit_from && commit_to
end end
def last_push_to_non_root? def last_push_to_non_root?
......
...@@ -95,11 +95,11 @@ class MergeRequest < ActiveRecord::Base ...@@ -95,11 +95,11 @@ class MergeRequest < ActiveRecord::Base
end end
event :mark_as_mergeable do event :mark_as_mergeable do
transition unchecked: :can_be_merged transition [:unchecked, :cannot_be_merged] => :can_be_merged
end end
event :mark_as_unmergeable do event :mark_as_unmergeable do
transition unchecked: :cannot_be_merged transition [:unchecked, :can_be_merged] => :cannot_be_merged
end end
state :unchecked state :unchecked
......
...@@ -59,7 +59,7 @@ class Note < ActiveRecord::Base ...@@ -59,7 +59,7 @@ class Note < ActiveRecord::Base
class << self class << self
def create_status_change_note(noteable, project, author, status, source) def create_status_change_note(noteable, project, author, status, source)
body = "_Status changed to #{status}#{' by ' + source.gfm_reference if source}_" body = "Status changed to #{status}#{' by ' + source.gfm_reference if source}"
create( create(
noteable: noteable, noteable: noteable,
...@@ -95,9 +95,9 @@ class Note < ActiveRecord::Base ...@@ -95,9 +95,9 @@ class Note < ActiveRecord::Base
def create_milestone_change_note(noteable, project, author, milestone) def create_milestone_change_note(noteable, project, author, milestone)
body = if milestone.nil? body = if milestone.nil?
'_Milestone removed_' 'Milestone removed'
else else
"_Milestone changed to #{milestone.title}_" "Milestone changed to #{milestone.title}"
end end
create( create(
...@@ -110,7 +110,7 @@ class Note < ActiveRecord::Base ...@@ -110,7 +110,7 @@ class Note < ActiveRecord::Base
end end
def create_assignee_change_note(noteable, project, author, assignee) def create_assignee_change_note(noteable, project, author, assignee)
body = assignee.nil? ? '_Assignee removed_' : "_Reassigned to @#{assignee.username}_" body = assignee.nil? ? 'Assignee removed' : "Reassigned to @#{assignee.username}"
create({ create({
noteable: noteable, noteable: noteable,
...@@ -140,7 +140,7 @@ class Note < ActiveRecord::Base ...@@ -140,7 +140,7 @@ class Note < ActiveRecord::Base
end end
message << ' ' << 'label'.pluralize(labels_count) message << ' ' << 'label'.pluralize(labels_count)
body = "_#{message.capitalize}_" body = "#{message.capitalize}"
create( create(
noteable: noteable, noteable: noteable,
...@@ -151,7 +151,7 @@ class Note < ActiveRecord::Base ...@@ -151,7 +151,7 @@ class Note < ActiveRecord::Base
) )
end end
def create_new_commits_note(merge_request, project, author, new_commits, existing_commits = []) def create_new_commits_note(merge_request, project, author, new_commits, existing_commits = [], oldrev = nil)
total_count = new_commits.length + existing_commits.length total_count = new_commits.length + existing_commits.length
commits_text = ActionController::Base.helpers.pluralize(total_count, 'commit') commits_text = ActionController::Base.helpers.pluralize(total_count, 'commit')
body = "Added #{commits_text}:\n\n" body = "Added #{commits_text}:\n\n"
...@@ -161,19 +161,23 @@ class Note < ActiveRecord::Base ...@@ -161,19 +161,23 @@ class Note < ActiveRecord::Base
if existing_commits.length == 1 if existing_commits.length == 1
existing_commits.first.short_id existing_commits.first.short_id
else else
"#{existing_commits.first.short_id}..#{existing_commits.last.short_id}" if oldrev
"#{Commit.truncate_sha(oldrev)}...#{existing_commits.last.short_id}"
else
"#{existing_commits.first.short_id}..#{existing_commits.last.short_id}"
end
end end
commits_text = ActionController::Base.helpers.pluralize(existing_commits.length, 'commit') commits_text = ActionController::Base.helpers.pluralize(existing_commits.length, 'commit')
branch = branch =
if merge_request.for_fork? if merge_request.for_fork?
"#{merge_request.target_project_namespace}:#{merge_request.target_branch}" "#{merge_request.target_project_namespace}:#{merge_request.target_branch}"
else else
merge_request.target_branch merge_request.target_branch
end end
message = "* #{commit_ids} - _#{commits_text} from branch `#{branch}`_" message = "* #{commit_ids} - #{commits_text} from branch `#{branch}`"
body << message body << message
body << "\n" body << "\n"
end end
...@@ -236,7 +240,7 @@ class Note < ActiveRecord::Base ...@@ -236,7 +240,7 @@ class Note < ActiveRecord::Base
where(noteable_id: noteable.id) where(noteable_id: noteable.id)
end end
notes.where('note like ?', cross_reference_note_content(gfm_reference)). notes.where('note like ?', cross_reference_note_pattern(gfm_reference)).
system.any? system.any?
end end
...@@ -245,13 +249,18 @@ class Note < ActiveRecord::Base ...@@ -245,13 +249,18 @@ class Note < ActiveRecord::Base
end end
def cross_reference_note_prefix def cross_reference_note_prefix
'_mentioned in ' 'mentioned in '
end end
private private
def cross_reference_note_content(gfm_reference) def cross_reference_note_content(gfm_reference)
cross_reference_note_prefix + "#{gfm_reference}_" cross_reference_note_prefix + "#{gfm_reference}"
end
def cross_reference_note_pattern(gfm_reference)
# Older cross reference notes contained underscores for emphasis
"%" + cross_reference_note_content(gfm_reference) + "%"
end end
# Prepend the mentioner's namespaced project path to the GFM reference for # Prepend the mentioner's namespaced project path to the GFM reference for
......
...@@ -89,6 +89,7 @@ class Project < ActiveRecord::Base ...@@ -89,6 +89,7 @@ class Project < ActiveRecord::Base
has_one :redmine_service, dependent: :destroy has_one :redmine_service, dependent: :destroy
has_one :custom_issue_tracker_service, dependent: :destroy has_one :custom_issue_tracker_service, dependent: :destroy
has_one :gitlab_issue_tracker_service, dependent: :destroy has_one :gitlab_issue_tracker_service, dependent: :destroy
has_one :external_wiki_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
......
...@@ -17,6 +17,15 @@ class ProjectContributions ...@@ -17,6 +17,15 @@ class ProjectContributions
end end
end end
def user_commits_on_date(date)
repository = @project.repository
if !repository.exists? || repository.empty?
return []
end
commits = repository.commits_by_user_on_date_log(@user, date)
end
def cache_key def cache_key
"#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}" "#{Date.today.to_s}-commits-log-#{project.id}-#{user.email}"
end end
......
...@@ -93,7 +93,7 @@ class BambooService < CiService ...@@ -93,7 +93,7 @@ class BambooService < CiService
end end
end end
def build_page(sha) def build_page(sha, ref)
build_info(sha) if @response.nil? || !@response.code build_info(sha) if @response.nil? || !@response.code
if @response.code != 200 || @response['results']['results']['size'] == '0' if @response.code != 200 || @response['results']['results']['size'] == '0'
...@@ -106,7 +106,7 @@ class BambooService < CiService ...@@ -106,7 +106,7 @@ class BambooService < CiService
end end
end end
def commit_status(sha) def commit_status(sha, ref)
build_info(sha) if @response.nil? || !@response.code build_info(sha) if @response.nil? || !@response.code
return :error unless @response.code == 200 || @response.code == 404 return :error unless @response.code == 200 || @response.code == 404
......
...@@ -48,7 +48,7 @@ class BuildboxService < CiService ...@@ -48,7 +48,7 @@ class BuildboxService < CiService
service_hook.execute(data) service_hook.execute(data)
end end
def commit_status(sha) def commit_status(sha, ref)
response = HTTParty.get(commit_status_path(sha), verify: false) response = HTTParty.get(commit_status_path(sha), verify: false)
if response.code == 200 && response['status'] if response.code == 200 && response['status']
...@@ -62,7 +62,7 @@ class BuildboxService < CiService ...@@ -62,7 +62,7 @@ class BuildboxService < CiService
"#{buildbox_endpoint('gitlab')}/status/#{status_token}.json?commit=#{sha}" "#{buildbox_endpoint('gitlab')}/status/#{status_token}.json?commit=#{sha}"
end end
def build_page(sha) def build_page(sha, ref)
"#{project_url}/builds?commit=#{sha}" "#{project_url}/builds?commit=#{sha}"
end end
......
...@@ -34,7 +34,7 @@ class CiService < Service ...@@ -34,7 +34,7 @@ class CiService < Service
# Ex. # Ex.
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c # http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
# #
def build_page(sha) def build_page(sha, ref)
# implement inside child # implement inside child
end end
...@@ -51,7 +51,7 @@ class CiService < Service ...@@ -51,7 +51,7 @@ class CiService < Service
# # => 'running' # # => 'running'
# #
# #
def commit_status(sha) def commit_status(sha, ref)
# implement inside child # implement inside child
end end
end end
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
#
class ExternalWikiService < Service
include HTTParty
prop_accessor :external_wiki_url
validates :external_wiki_url,
presence: true,
format: { with: URI::regexp },
if: :activated?
def title
'External Wiki'
end
def description
'Replaces the link to the internal wiki with a link to an external wiki.'
end
def to_param
'external_wiki'
end
def fields
[
{ type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki' },
]
end
def execute(_data)
@response = HTTParty.get(properties['external_wiki_url'], verify: true) rescue nil
if @response !=200
nil
end
end
end
...@@ -40,17 +40,17 @@ class GitlabCiService < CiService ...@@ -40,17 +40,17 @@ class GitlabCiService < CiService
service_hook.execute(data) service_hook.execute(data)
end end
def commit_status_path(sha) def commit_status_path(sha, ref)
project_url + "/commits/#{sha}/status.json?token=#{token}" project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}"
end end
def get_ci_build(sha) def get_ci_build(sha, ref)
@ci_builds ||= {} @ci_builds ||= {}
@ci_builds[sha] ||= HTTParty.get(commit_status_path(sha), verify: false) @ci_builds[sha] ||= HTTParty.get(commit_status_path(sha, ref), verify: false)
end end
def commit_status(sha) def commit_status(sha, ref)
response = get_ci_build(sha) response = get_ci_build(sha, ref)
if response.code == 200 and response["status"] if response.code == 200 and response["status"]
response["status"] response["status"]
...@@ -59,16 +59,16 @@ class GitlabCiService < CiService ...@@ -59,16 +59,16 @@ class GitlabCiService < CiService
end end
end end
def commit_coverage(sha) def commit_coverage(sha, ref)
response = get_ci_build(sha) response = get_ci_build(sha, ref)
if response.code == 200 and response["coverage"] if response.code == 200 and response["coverage"]
response["coverage"] response["coverage"]
end end
end end
def build_page(sha) def build_page(sha, ref)
project_url + "/commits/#{sha}" project_url + "/refs/#{ref}/commits/#{sha}"
end end
def builds_path def builds_path
......
...@@ -88,7 +88,7 @@ class TeamcityService < CiService ...@@ -88,7 +88,7 @@ class TeamcityService < CiService
@response = HTTParty.get("#{url}", verify: false, basic_auth: auth) @response = HTTParty.get("#{url}", verify: false, basic_auth: auth)
end end
def build_page(sha) def build_page(sha, ref)
build_info(sha) if @response.nil? || !@response.code build_info(sha) if @response.nil? || !@response.code
if @response.code != 200 if @response.code != 200
...@@ -103,7 +103,7 @@ class TeamcityService < CiService ...@@ -103,7 +103,7 @@ class TeamcityService < CiService
end end
end end
def commit_status(sha) def commit_status(sha, ref)
build_info(sha) if @response.nil? || !@response.code build_info(sha) if @response.nil? || !@response.code
return :error unless @response.code == 200 || @response.code == 404 return :error unless @response.code == 200 || @response.code == 404
......
...@@ -122,7 +122,7 @@ class Repository ...@@ -122,7 +122,7 @@ class Repository
def expire_cache def expire_cache
%i(size branch_names tag_names commit_count graph_log %i(size branch_names tag_names commit_count graph_log
readme version contribution_guide).each do |key| readme version contribution_guide changelog license).each do |key|
cache.expire(key) cache.expire(key)
end end
end end
...@@ -157,6 +157,20 @@ class Repository ...@@ -157,6 +157,20 @@ class Repository
end end
end end
def commits_by_user_on_date_log(user, date)
# format the date string for git
start_date = date.strftime("%Y-%m-%d 00:00:00")
end_date = date.strftime("%Y-%m-%d 23:59:59")
author_emails = '(' + user.all_emails.map{ |e| Regexp.escape(e) }.join('|') + ')'
args = %W(git log -E --author=#{author_emails} --after=#{start_date.to_s} --until=#{end_date.to_s} --branches --pretty=format:%h)
commits = Gitlab::Popen.popen(args, path_to_repo).first.split("\n")
commits.map! do |commit_id|
commit(commit_id)
end
end
def commits_per_day_for_user(user) def commits_per_day_for_user(user)
timestamps_by_user_log(user). timestamps_by_user_log(user).
group_by { |commit_date| commit_date }. group_by { |commit_date| commit_date }.
...@@ -197,7 +211,27 @@ class Repository ...@@ -197,7 +211,27 @@ class Repository
end end
def contribution_guide def contribution_guide
cache.fetch(:contribution_guide) { tree(:head).contribution_guide } cache.fetch(:contribution_guide) do
tree(:head).blobs.find do |file|
file.contributing?
end
end
end
def changelog
cache.fetch(:changelog) do
tree(:head).blobs.find do |file|
file.name =~ /^(changelog|history)/i
end
end
end
def license
cache.fetch(:license) do
tree(:head).blobs.find do |file|
file.name =~ /^license/i
end
end
end end
def head_commit def head_commit
......
...@@ -112,7 +112,7 @@ class Service < ActiveRecord::Base ...@@ -112,7 +112,7 @@ class Service < ActiveRecord::Base
def async_execute(data) def async_execute(data)
return unless supported_events.include?(data[:object_kind]) return unless supported_events.include?(data[:object_kind])
Sidekiq::Client.enqueue(ProjectServiceWorker, id, data) Sidekiq::Client.enqueue(ProjectServiceWorker, id, data)
end end
...@@ -121,9 +121,27 @@ class Service < ActiveRecord::Base ...@@ -121,9 +121,27 @@ class Service < ActiveRecord::Base
end end
def self.available_services_names def self.available_services_names
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana %w(
emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira gitlab_ci
redmine custom_issue_tracker irker) campfire
hipchat
pivotaltracker
flowdock
assembla
asana
emails_on_push
gemnasium
slack
pushover
buildbox
bamboo
teamcity
jira
redmine
custom_issue_tracker
irker
external_wiki
)
end end
def self.create_from_template(project_id, template) def self.create_from_template(project_id, template)
......
class Tree class Tree
include Gitlab::MarkdownHelper include Gitlab::MarkdownHelper
attr_accessor :entries, :readme, :contribution_guide attr_accessor :repository, :sha, :path, :entries
def initialize(repository, sha, path = '/') def initialize(repository, sha, path = '/')
path = '/' if path.blank? path = '/' if path.blank?
git_repo = repository.raw_repository
@entries = Gitlab::Git::Tree.where(git_repo, sha, path) @repository = repository
@sha = sha
available_readmes = @entries.select(&:readme?) @path = path
if available_readmes.count > 0 git_repo = @repository.raw_repository
# If there is more than 1 readme in tree, find readme which is supported @entries = Gitlab::Git::Tree.where(git_repo, @sha, @path)
# by markup renderer. end
if available_readmes.length > 1
supported_readmes = available_readmes.select do |readme| def readme
previewable?(readme.name) return @readme if defined?(@readme)
end
# Take the first supported readme, or the first available readme, if we
# don't support any of them
readme_tree = supported_readmes.first || available_readmes.first
else
readme_tree = available_readmes.first
end
readme_path = path == '/' ? readme_tree.name : File.join(path, readme_tree.name)
@readme = Gitlab::Git::Blob.find(git_repo, sha, readme_path)
end
if contribution_tree = @entries.find(&:contributing?) available_readmes = blobs.select(&:readme?)
contribution_path = path == '/' ? contribution_tree.name : File.join(path, contribution_tree.name)
@contribution_guide = Gitlab::Git::Blob.find(git_repo, sha, contribution_path) if available_readmes.count == 0
return @readme = nil
end end
# Take the first previewable readme, or the first available readme, if we
# can't preview any of them
readme_tree = available_readmes.find do |readme|
previewable?(readme.name)
end || available_readmes.first
readme_path = path == '/' ? readme_tree.name : File.join(path, readme_tree.name)
git_repo = repository.raw_repository
@readme = Gitlab::Git::Blob.find(git_repo, sha, readme_path)
end end
def trees def trees
......
...@@ -109,7 +109,7 @@ class GitPushService ...@@ -109,7 +109,7 @@ class GitPushService
def push_to_existing_branch?(ref, oldrev) def push_to_existing_branch?(ref, oldrev)
# Return if this is not a push to a branch (e.g. new commits) # Return if this is not a push to a branch (e.g. new commits)
Gitlab::Git.branch_ref?(ref) && oldrev != Gitlab::Git::BLANK_SHA Gitlab::Git.branch_ref?(ref) && !Gitlab::Git.blank_ref?(oldrev)
end end
def push_to_new_branch?(ref, oldrev) def push_to_new_branch?(ref, oldrev)
......
...@@ -89,7 +89,7 @@ module MergeRequests ...@@ -89,7 +89,7 @@ module MergeRequests
end end
Note.create_new_commits_note(merge_request, merge_request.project, Note.create_new_commits_note(merge_request, merge_request.project,
@current_user, new_commits, existing_commits) @current_user, new_commits, existing_commits, @oldrev)
end end
end end
......
...@@ -120,7 +120,7 @@ class NotificationService ...@@ -120,7 +120,7 @@ class NotificationService
return true unless note.noteable_type.present? return true unless note.noteable_type.present?
# ignore gitlab service messages # ignore gitlab service messages
return true if note.note.start_with?('_Status changed to closed_') return true if note.note.start_with?('Status changed to closed')
return true if note.cross_reference? && note.system == true return true if note.cross_reference? && note.system == true
opts = { noteable_type: note.noteable_type, project_id: note.project_id } opts = { noteable_type: note.noteable_type, project_id: note.project_id }
......
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
.checkbox .checkbox
= f.label :signup_enabled do = f.label :signup_enabled do
= f.check_box :signup_enabled = f.check_box :signup_enabled
Signin enabled Signup enabled
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
= f.label :signin_enabled do = f.label :signin_enabled do
= f.check_box :signin_enabled = f.check_box :signin_enabled
Signup enabled Signin enabled
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.checkbox .checkbox
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if current_user.can_create_project? - if current_user.can_create_project?
.input-group-addon.dash-new-project %span.input-group-btn
= link_to new_project_path do = link_to new_project_path, class: 'btn btn-success' do
%strong New project New project
= render 'shared/projects_list', projects: @projects, projects_limit: 20 = render 'shared/projects_list', projects: @projects, projects_limit: 20
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if current_user.can_create_project? - if current_user.can_create_project?
.input-group-addon.dash-new-project %span.input-group-btn
= link_to new_project_path do = link_to new_project_path, class: 'btn btn-success' do
%strong New project New project
= render 'shared/projects_list', projects: @projects, = render 'shared/projects_list', projects: @projects,
projects_limit: 20, stars: true, avatar: false projects_limit: 20, stars: true, avatar: false
......
...@@ -21,5 +21,11 @@ ...@@ -21,5 +21,11 @@
%li.commits-stat %li.commits-stat
- if event.commits_count > 2 - if event.commits_count > 2
%span ... and #{event.commits_count - 2} more commits. %span ... and #{event.commits_count - 2} more commits.
= link_to namespace_project_compare_path(event.project.namespace, event.project, from: event.commit_from, to: event.commit_to) do - if event.md_ref?
%strong Compare &rarr; #{truncate_sha(event.commit_from)}...#{truncate_sha(event.commit_to)} - from = event.commit_from
- from_label = truncate_sha(from)
- else
- from = event.project.default_branch
- from_label = from
= link_to namespace_project_compare_path(event.project.namespace, event.project, from: from, to: event.commit_to) do
%strong Compare &rarr; #{from_label}...#{truncate_sha(event.commit_to)}
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
.input-group .input-group
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control'
- if can? current_user, :create_projects, @group - if can? current_user, :create_projects, @group
.input-group-addon.dash-new-project %span.input-group-btn
= link_to new_project_path(namespace_id: @group.id) do = link_to new_project_path(namespace_id: @group.id), class: 'btn btn-success' do
%strong New project New project
= render 'shared/projects_list', projects: @projects, projects_limit: 20 = render 'shared/projects_list', projects: @projects, projects_limit: 20
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
%i.fa.fa-minus.fa-inverse %i.fa.fa-minus.fa-inverse
.edit-member.hide.js-toggle-content .edit-member.hide.js-toggle-content
%br
= form_for [@group, member], remote: true do |f| = form_for [@group, member], remote: true do |f|
.alert.prepend-top-20 .prepend-top-10
= f.select :access_level, options_for_select(GroupMember.access_level_roles, member.access_level) = f.select :access_level, options_for_select(GroupMember.access_level_roles, member.access_level), {}, class: 'form-control'
.prepend-top-10
= f.submit 'Save', class: 'btn btn-save btn-sm' = f.submit 'Save', class: 'btn btn-save btn-sm'
.dashboard .dashboard
%div .header-with-avatar.clearfix
= image_tag group_icon(@group), class: "avatar group-avatar s90" = image_tag group_icon(@group), class: "avatar group-avatar s90"
.clearfix %h3
%h2 = @group.name
= @group.name .username
- if @group.description.present? @#{@group.path}
%p - if @group.description.present?
= escaped_autolink(@group.description) .description
= escaped_autolink(@group.description)
%hr %hr
.row .row
%section.activities.col-md-8 %section.activities.col-md-8
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
- if project_nav_tab? :wiki - if project_nav_tab? :wiki
= nav_link(controller: :wikis) do = nav_link(controller: :wikis) do
= link_to namespace_project_wiki_path(@project.namespace, @project, :home), title: 'Wiki', class: 'shortcuts-wiki' do = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do
%i.fa.fa-book %i.fa.fa-book
%span %span
Wiki Wiki
......
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
= @project.name_with_namespace = @project.name_with_namespace
%p %p
To update the remote url in your local repository run (for ssh): To update the remote url in your local repository run (for ssh):
%p{ style: "background:#f5f5f5; padding:10px; border:1px solid #ddd" } %p{ style: "background: #f5f5f5; padding:10px; border:1px solid #ddd" }
git remote set-url origin #{@project.ssh_url_to_repo} git remote set-url origin #{@project.ssh_url_to_repo}
%p %p
or for http(s): or for http(s):
%p{ style: "background:#f5f5f5; padding:10px; border:1px solid #ddd" } %p{ style: "background: #f5f5f5; padding:10px; border:1px solid #ddd" }
git remote set-url origin #{@project.http_url_to_repo} git remote set-url origin #{@project.http_url_to_repo}
%br %br
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
.form-group .form-group
= f.label :website_url, 'Website', class: "control-label" = f.label :website_url, 'Website', class: "control-label"
.col-sm-10= f.text_field :website_url, class: "form-control" .col-sm-10= f.text_field :website_url, class: "form-control"
.form-group
= f.label :location, 'Location', class: "control-label"
.col-sm-10= f.text_field :location, class: "form-control"
.form-group .form-group
= f.label :bio, class: "control-label" = f.label :bio, class: "control-label"
.col-sm-10 .col-sm-10
......
...@@ -2,8 +2,5 @@ ...@@ -2,8 +2,5 @@
.commit-button-annotation .commit-button-annotation
= button_tag 'Commit Changes', = button_tag 'Commit Changes',
class: 'btn commit-btn js-commit-button btn-create' class: 'btn commit-btn js-commit-button btn-create'
.message
to branch
%strong= ref
= link_to 'Cancel', cancel_path, = link_to 'Cancel', cancel_path,
class: 'btn btn-cancel', data: {confirm: leave_edit_message} class: 'btn btn-cancel', data: {confirm: leave_edit_message}
...@@ -71,10 +71,10 @@ ...@@ -71,10 +71,10 @@
= link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank
.form-actions .form-actions
- if !issuable.project.empty_repo? && contribution_guide_url(issuable.project) && !issuable.persisted? - if !issuable.project.empty_repo? && (guide_url = contribution_guide_url(issuable.project)) && !issuable.persisted?
%p %p
Please review the Please review the
%strong #{link_to 'guidelines for contribution', contribution_guide_url(issuable.project)} %strong #{link_to 'guidelines for contribution', guide_url}
to this repository. to this repository.
- if issuable.new_record? - if issuable.new_record?
= f.submit "Submit new #{issuable.class.model_name.human.downcase}", class: 'btn btn-create' = f.submit "Submit new #{issuable.class.model_name.human.downcase}", class: 'btn btn-create'
......
.row .row.prepend-top-20.append-bottom-10
.col-md-8 .col-md-8
= render 'projects/diffs/stats', diffs: diffs = render 'projects/diffs/stats', diffs: diffs
.col-md-4 .col-md-4
......
...@@ -22,14 +22,8 @@ ...@@ -22,14 +22,8 @@
.diff-btn-group .diff-btn-group
- if blob.text? - if blob.text?
- unless params[:view] == 'parallel' = link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do
%label %i.fa.fa-comments
= check_box_tag nil, 1, false, class: 'js-toggle-diff-line-wrap'
Wrap text
&nbsp;
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm' do
%i.fa.fa-chevron-down
Show/Hide comments
&nbsp; &nbsp;
- if @merge_request && @merge_request.source_project - if @merge_request && @merge_request.source_project
...@@ -39,7 +33,7 @@ ...@@ -39,7 +33,7 @@
= view_file_btn(@commit.id, diff_file, project) = view_file_btn(@commit.id, diff_file, project)
.diff-content .diff-content.diff-wrap-lines
-# Skipp all non non-supported blobs -# Skipp all non non-supported blobs
- return unless blob.respond_to?('text?') - return unless blob.respond_to?('text?')
- if blob.text? - if blob.text?
......
.js-toggle-container .js-toggle-container
.commit-stat-summary .commit-stat-summary
Showing Showing
%strong.cdark #{pluralize(diffs.count, "changed file")} = link_to '#', class: 'js-toggle-button' do
%strong #{pluralize(diffs.count, "changed file")}
- if current_controller?(:commit) - if current_controller?(:commit)
- unless @commit.has_zero_stats? - unless @commit.has_zero_stats?
with with
%strong.cgreen #{@commit.stats.additions} additions %strong.cgreen #{@commit.stats.additions} additions
and and
%strong.cred #{@commit.stats.deletions} deletions %strong.cred #{@commit.stats.deletions} deletions
&nbsp;
= link_to '#', class: 'btn btn-sm js-toggle-button' do
Show diff stats
%i.fa.fa-chevron-down
.file-stats.js-toggle-content.hide .file-stats.js-toggle-content.hide
%ul.bordered-list %ul.bordered-list
- diffs.each_with_index do |diff, i| - diffs.each_with_index do |diff, i|
......
...@@ -6,11 +6,12 @@ ...@@ -6,11 +6,12 @@
= link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close js-note-target-close", title: "Close Issue" = link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close js-note-target-close", title: "Close Issue"
.row .row
%section.col-md-9 %section.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @issue
.participants .participants
%span= pluralize(@issue.participants.count, 'participant') %span= pluralize(@issue.participants.count, 'participant')
- @issue.participants.each do |participant| - @issue.participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24)
.voting_notes#notes= render "projects/notes/notes_with_form" .voting_notes#notes= render "projects/notes/notes_with_form"
%aside.col-md-3 %aside.col-md-3
.issuable-affix .issuable-affix
...@@ -20,15 +21,10 @@ ...@@ -20,15 +21,10 @@
%hr %hr
.context .context
= render partial: 'issue_context', locals: { issue: @issue } = render partial: 'issue_context', locals: { issue: @issue }
%hr
.clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any? - if @issue.labels.any?
%hr .issuable-context-title
%h6 Labels %label Labels
.issue-show-labels .issue-show-labels
- @issue.labels.each do |label| - @issue.labels.each do |label|
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do = link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
= issue.notes.count = issue.notes.count
.issue-info .issue-info
%span.light= "##{issue.iid}" = link_to "##{issue.iid}", issue_path(issue), class: "light"
- if issue.assignee - if issue.assignee
assigned to #{link_to_member(@project, issue.assignee)} assigned to #{link_to_member(@project, issue.assignee)}
- if issue.votes_count > 0 - if issue.votes_count > 0
......
...@@ -27,22 +27,23 @@ ...@@ -27,22 +27,23 @@
= hidden_field_tag :issue_context = hidden_field_tag :issue_context
= f.submit class: 'btn' = f.submit class: 'btn'
%div.prepend-top-20.clearfix - if current_user
.issuable-context-title %div.prepend-top-20.clearfix
%label .issuable-context-title
Subscription: %label
%button.btn.btn-block.subscribe-button Subscription:
%i.fa.fa-eye %button.btn.btn-block.subscribe-button
%span= @issue.subscribed?(current_user) ? "Unsubscribe" : "Subscribe" %i.fa.fa-eye
- subscribtion_status = @issue.subscribed?(current_user) ? "subscribed" : "unsubscribed" %span= @issue.subscribed?(current_user) ? "Unsubscribe" : "Subscribe"
.subscription-status{"data-status" => subscribtion_status} - subscribtion_status = @issue.subscribed?(current_user) ? "subscribed" : "unsubscribed"
.description-block.unsubscribed{class: ( "hidden" if @issue.subscribed?(current_user) )} .subscription-status{"data-status" => subscribtion_status}
You're not receiving notifications from this thread. .description-block.unsubscribed{class: ( "hidden" if @issue.subscribed?(current_user) )}
.description-block.subscribed{class: ( "hidden" unless @issue.subscribed?(current_user) )} You're not receiving notifications from this thread.
You're receiving notifications because you're subscribed to this thread. .description-block.subscribed{class: ( "hidden" unless @issue.subscribed?(current_user) )}
You're receiving notifications because you're subscribed to this thread.
:coffeescript :coffeescript
$ -> $ ->
new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}") new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}")
\ No newline at end of file
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
.clearfix .clearfix
.issues_bulk_update.hide .issues_bulk_update.hide
= form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do = form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do
= select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), prompt: "Status") = select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), prompt: "Status", class: 'form-control')
= project_users_select_tag('update[assignee_id]', placeholder: 'Assignee') = project_users_select_tag('update[assignee_id]', placeholder: 'Assignee')
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") = select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag 'update[issues_ids]', []
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
.row .row
%section.col-md-9 %section.col-md-9
.votes-holder.pull-right
#votes= render 'votes/votes_block', votable: @merge_request
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
%aside.col-md-3 %aside.col-md-3
...@@ -17,14 +19,10 @@ ...@@ -17,14 +19,10 @@
%hr %hr
.context .context
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request } = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
%hr
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request
- if @merge_request.labels.any? - if @merge_request.labels.any?
%hr .issuable-context-title
%h6 Labels %label Labels
.merge-request-show-labels .merge-request-show-labels
- @merge_request.labels.each do |label| - @merge_request.labels.each do |label|
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do = link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
%i.fa.fa-comments %i.fa.fa-comments
= merge_request.mr_and_commit_notes.count = merge_request.mr_and_commit_notes.count
.merge-request-info .merge-request-info
%span.light= "##{merge_request.iid}" = link_to "##{merge_request.iid}", merge_request_path(merge_request), class: "light"
- if merge_request.assignee - if merge_request.assignee
assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)} assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)}
- else - else
......
...@@ -69,10 +69,10 @@ ...@@ -69,10 +69,10 @@
= link_to 'Create new label', new_namespace_project_label_path(@merge_request.target_project.namespace, @merge_request.target_project), target: :blank = link_to 'Create new label', new_namespace_project_label_path(@merge_request.target_project.namespace, @merge_request.target_project), target: :blank
.form-actions .form-actions
- if contribution_guide_url(@target_project) - if guide_url = contribution_guide_url(@target_project)
%p %p
Please review the Please review the
%strong #{link_to 'guidelines for contribution', contribution_guide_url(@target_project)} %strong #{link_to 'guidelines for contribution', guide_url}
to this repository. to this repository.
= f.hidden_field :source_project_id = f.hidden_field :source_project_id
= f.hidden_field :source_branch = f.hidden_field :source_branch
......
...@@ -29,19 +29,20 @@ ...@@ -29,19 +29,20 @@
= hidden_field_tag :merge_request_context = hidden_field_tag :merge_request_context
= f.submit class: 'btn' = f.submit class: 'btn'
%div.prepend-top-20.clearfix - if current_user
.issuable-context-title %div.prepend-top-20.clearfix
%label .issuable-context-title
Subscription: %label
%button.btn.btn-block.subscribe-button Subscription:
%i.fa.fa-eye %button.btn.btn-block.subscribe-button
%span= @merge_request.subscribed?(current_user) ? "Unsubscribe" : "Subscribe" %i.fa.fa-eye
- subscribtion_status = @merge_request.subscribed?(current_user) ? "subscribed" : "unsubscribed" %span= @merge_request.subscribed?(current_user) ? "Unsubscribe" : "Subscribe"
.subscription-status{"data-status" => subscribtion_status} - subscribtion_status = @merge_request.subscribed?(current_user) ? "subscribed" : "unsubscribed"
.description-block.unsubscribed{class: ( "hidden" if @merge_request.subscribed?(current_user) )} .subscription-status{"data-status" => subscribtion_status}
You're not receiving notifications from this thread. .description-block.unsubscribed{class: ( "hidden" if @merge_request.subscribed?(current_user) )}
.description-block.subscribed{class: ( "hidden" unless @merge_request.subscribed?(current_user) )} You're not receiving notifications from this thread.
You're receiving notifications because you're subscribed to this thread. .description-block.subscribed{class: ( "hidden" unless @merge_request.subscribed?(current_user) )}
You're receiving notifications because you're subscribed to this thread.
:coffeescript :coffeescript
$ -> $ ->
......
...@@ -23,6 +23,12 @@ ...@@ -23,6 +23,12 @@
%i.fa.fa-spinner %i.fa.fa-spinner
Checking for CI status for #{@merge_request.last_commit_short_sha} Checking for CI status for #{@merge_request.last_commit_short_sha}
.ci_widget.ci-canceled{style: "display:none"}
%i.fa.fa-times
%span CI build canceled
for #{@merge_request.last_commit_short_sha}.
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-error{style: "display:none"} .ci_widget.ci-error{style: "display:none"}
%i.fa.fa-times %i.fa.fa-times
%span Cannot connect to the CI server. Please check your settings and try again. %span Cannot connect to the CI server. Please check your settings and try again.
...@@ -21,64 +21,65 @@ ...@@ -21,64 +21,65 @@
= f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2}
%hr %hr
.js-toggle-container
.project-import.js-toggle-container
.form-group .form-group
.col-sm-2 %label.control-label Import project from
.col-sm-10 .col-sm-10
= link_to "#", class: 'js-toggle-button' do - if github_import_enabled?
%i.fa.fa-upload = link_to status_import_github_path, class: 'btn' do
%span Import existing repository by URL %i.fa.fa-github
.js-toggle-content.hide GitHub
.form-group.import-url-data - else
= f.label :import_url, class: 'control-label' do = link_to '#', class: 'how_to_import_link light btn' do
%span Import existing git repo %i.fa.fa-github
.col-sm-10 GitHub
= f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' = render 'github_import_modal'
.alert.alert-info.prepend-top-10
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
%br
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}
.project-import.form-group - if bitbucket_import_enabled?
%label.control-label Import projects from = link_to status_import_bitbucket_path, class: 'btn' do
.col-sm-10 %i.fa.fa-bitbucket
- if github_import_enabled? Bitbucket
= link_to status_import_github_path, class: 'btn' do
%i.fa.fa-github
GitHub
- else
= link_to '#', class: 'how_to_import_link light btn' do
%i.fa.fa-github
GitHub
= render 'github_import_modal'
- if bitbucket_import_enabled?
= link_to status_import_bitbucket_path, class: 'btn' do
%i.fa.fa-bitbucket
Bitbucket
- else
= link_to '#', class: 'how_to_import_link light btn' do
%i.fa.fa-bitbucket
Bitbucket
= render 'bitbucket_import_modal'
- unless request.host == 'gitlab.com'
- if gitlab_import_enabled?
= link_to status_import_gitlab_path, class: 'btn' do
%i.fa.fa-heart
GitLab.com
- else - else
= link_to '#', class: 'how_to_import_link light btn' do = link_to '#', class: 'how_to_import_link light btn' do
%i.fa.fa-heart %i.fa.fa-bitbucket
GitLab.com Bitbucket
= render 'gitlab_import_modal' = render 'bitbucket_import_modal'
= link_to new_import_gitorious_path, class: 'btn' do - unless request.host == 'gitlab.com'
%i.icon-gitorious.icon-gitorious-small - if gitlab_import_enabled?
Gitorious.org = link_to status_import_gitlab_path, class: 'btn' do
%i.fa.fa-heart
GitLab.com
- else
= link_to '#', class: 'how_to_import_link light btn' do
%i.fa.fa-heart
GitLab.com
= render 'gitlab_import_modal'
= link_to new_import_gitorious_path, class: 'btn' do
%i.icon-gitorious.icon-gitorious-small
Gitorious.org
= link_to "#", class: 'btn js-toggle-button' do
%i.fa.fa-git
%span Any repo by URL
.js-toggle-content.hide
.form-group.import-url-data
= f.label :import_url, class: 'control-label' do
%span Git repository URL
.col-sm-10
= f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git'
.alert.alert-info.prepend-top-10
%ul
%li
The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>.
%li
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
%li
To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}.
%hr.prepend-botton-10 %hr.prepend-botton-10
......
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
%i.fa.fa-minus.fa-inverse %i.fa.fa-minus.fa-inverse
.edit-member.hide.js-toggle-content .edit-member.hide.js-toggle-content
%br
= form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f| = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member.user), remote: true do |f|
.alert.prepend-top-20 .prepend-top-10
= f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level) = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: 'form-control'
= f.submit 'Save', class: 'btn btn-save btn-sm' .prepend-top-10
= f.submit 'Save', class: 'btn btn-save'
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
.col-sm-10 .col-sm-10
= f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2"}) = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2"})
.form-group .form-group
= f.label :developers_can_push, class: 'control-label' do .col-sm-offset-2.col-sm-10
Developers can push
.col-sm-10
.checkbox .checkbox
= f.check_box :developers_can_push = f.label :developers_can_push do
%span.descr Allow developers to push to this branch = f.check_box :developers_can_push
%strong Developers can push
.help-block Allow developers to push to this branch
.form-actions .form-actions
= f.submit 'Protect', class: "btn-create btn" = f.submit 'Protect', class: "btn-create btn"
= render 'branches_list' = render 'branches_list'
......
...@@ -101,5 +101,6 @@ ...@@ -101,5 +101,6 @@
.form-actions .form-actions
= f.submit 'Save', class: 'btn btn-save' = f.submit 'Save', class: 'btn btn-save'
&nbsp; &nbsp;
- if @service.valid? && @service.activated? && @service.can_test? - if @service.valid? && @service.activated?
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: 'btn' - disabled = @service.can_test? ? '':'disabled'
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}"
...@@ -44,25 +44,36 @@ ...@@ -44,25 +44,36 @@
%i.fa.fa-code-fork.project-fork-icon %i.fa.fa-code-fork.project-fork-icon
Forked from: Forked from:
%br %br
= link_to @project.forked_from_project.name_with_namespace, namespace_project_path(@project.namespace, @project.forked_from_project) = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project)
- unless @project.empty_repo? - unless @project.empty_repo?
= link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref), class: 'btn btn-block' do = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref), class: 'btn btn-block' do
Compare code Compare code
- if @repository.version - if version = @repository.version
- version = @repository.version - detail_url = changelog_url(@project) || version_url(@project)
= link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, version.name)), class: 'btn btn-block' do = link_to detail_url, class: 'btn btn-block' do
Version: Version:
%span.count %span.count
= @repository.blob_by_oid(version.id).data = @repository.blob_by_oid(version.id).data
- elsif @repository.changelog
= link_to changelog_url(@project), class: 'btn btn-block' do
View changelog
- if @repository.contribution_guide
= link_to contribution_guide_url(@project), class: 'btn btn-block' do
View contribution guide
- if @repository.license
= link_to license_url(@project), class: 'btn btn-block' do
View license
.prepend-top-10 .prepend-top-10
%p %p
%span.light Created on %span.light Created on
#{@project.created_at.stamp('Aug 22, 2013')} #{@project.created_at.stamp('Aug 22, 2013')}
%p %p
%span.light Owned by %span.light Owned by #{@project.group ? "the" : nil}
- if @project.group - if @project.group
#{link_to @project.group.name, @project.group} group #{link_to @project.group.name, @project.group} group
- else - else
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
= f.text_field :path, placeholder: 'open-source', class: 'form-control', = f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false autofocus: local_assigns[:autofocus] || false
- if @group.persisted? - if @group.persisted?
.alert.alert-danger .alert.alert-warning.prepend-top-10
%ul %ul
%li Changing group path can have unintended side effects. %li Changing group path can have unintended side effects.
%li Renaming group path will rename directory for all related projects %li Renaming group path will rename directory for all related projects
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
%li %li
%span.light Website: %span.light Website:
%strong= link_to user.short_website_url, user.full_website_url %strong= link_to user.short_website_url, user.full_website_url
- unless user.bio.blank? - unless user.location.blank?
%li %li
%span.light Bio: %span.light Location:
%span= user.bio %strong= user.location
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
new calendar( new calendar(
#{@timestamps.to_json}, #{@timestamps.to_json},
#{@starting_year}, #{@starting_year},
#{@starting_month} #{@starting_month},
'#{user_calendar_activities_path}'
); );
.calendar_commit_activity
%hr
%h4
Commit Activity
%strong
- if @commit_count == 0
no
- else
= @commit_count
%span.calendar_commit_date
unique
= 'commit'.pluralize(@commit_count)
on
= @calendar_date.strftime("%b %d, %Y") rescue ''
-unless @commit_count == 0
%hr
- @calendar_activities.each do |project, commits|
- next if commits.empty?
%div.js-toggle-container
%strong
= pluralize(commits.count, 'commit')
in project
= link_to project.name_with_namespace, project_path(project)
%a.text-expander.js-toggle-button &hellip;
%hr
%div.js-toggle-content
- commits.each do |commit|
%span.monospace
= commit.committed_date.strftime("%H:%M")
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
= link_to commit.message, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message str-truncated"
%br
%hr
...@@ -2,29 +2,34 @@ ...@@ -2,29 +2,34 @@
= link_to '#aside', class: 'show-aside' do = link_to '#aside', class: 'show-aside' do
%i.fa.fa-angle-left %i.fa.fa-angle-left
%section.col-md-8 %section.col-md-8
%h3.page-title .header-with-avatar
= image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: '' = image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
= @user.name %h3
- if @user == current_user = @user.name
.pull-right - if @user == current_user
= link_to profile_path, class: 'btn' do .pull-right
%i.fa.fa-pencil-square-o = link_to profile_path, class: 'btn btn-sm' do
Edit Profile settings %i.fa.fa-pencil-square-o
%br Edit Profile settings
%span.user-show-username #{@user.username} .username
%br @#{@user.username}
%small member since #{@user.created_at.stamp("Nov 12, 2031")} .description
- if @user.bio.present?
= @user.bio
.clearfix .clearfix
- if @groups.any? - if @groups.any?
%h4 Groups .prepend-top-20
= render 'groups', groups: @groups %h4 Groups
%hr = render 'groups', groups: @groups
%hr
.hidden-xs .hidden-xs
.user-calendar .user-calendar
%h4.center.light %h4.center.light
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
.user-calendar-activities
%hr %hr
%h4 %h4
User Activity User Activity
......
.votes.votes-block .votes.votes-block
.progress .btn-group
.progress-bar.progress-bar-success{style: "width: #{votable.upvotes_in_percent}%;"} - unless votable.upvotes.zero?
.progress-bar.progress-bar-danger{style: "width: #{votable.downvotes_in_percent}%;"} .btn.btn-sm.disabled.cgreen
.upvotes= "#{votable.upvotes} up" %i.fa.fa-thumbs-up
.downvotes= "#{votable.downvotes} down" = votable.upvotes
- unless votable.downvotes.zero?
.btn.btn-sm.disabled.cred
%i.fa.fa-thumbs-down
= votable.downvotes
.votes.votes-inline .votes.votes-inline
- unless votable.upvotes.zero? - unless votable.upvotes.zero?
.upvotes %span.upvotes.cgreen
+ #{votable.upvotes} + #{votable.upvotes}
- unless votable.downvotes.zero? - unless votable.downvotes.zero?
\/ \/
- unless votable.downvotes.zero? - unless votable.downvotes.zero?
.downvotes %span.downvotes.cred
\- #{votable.downvotes} \- #{votable.downvotes}
...@@ -57,9 +57,9 @@ class IrkerWorker ...@@ -57,9 +57,9 @@ class IrkerWorker
end end
def send_branch_updates(push_data, project, repo_name, committer, branch) def send_branch_updates(push_data, project, repo_name, committer, branch)
if push_data['before'] == Gitlab::Git::BLANK_SHA if Gitlab::Git.blank_ref?(push_data['before'])
send_new_branch project, repo_name, committer, branch send_new_branch project, repo_name, committer, branch
elsif push_data['after'] == Gitlab::Git::BLANK_SHA elsif Gitlab::Git.blank_ref?(push_data['after'])
send_del_branch repo_name, committer, branch send_del_branch repo_name, committer, branch
end end
end end
...@@ -83,7 +83,7 @@ class IrkerWorker ...@@ -83,7 +83,7 @@ class IrkerWorker
return if push_data['total_commits_count'] == 0 return if push_data['total_commits_count'] == 0
# Next message is for number of commit pushed, if any # Next message is for number of commit pushed, if any
if push_data['before'] == Gitlab::Git::BLANK_SHA if Gitlab::Git.blank_ref?(push_data['before'])
# Tweak on push_data["before"] in order to have a nice compare URL # Tweak on push_data["before"] in order to have a nice compare URL
push_data['before'] = before_on_new_branch push_data, project push_data['before'] = before_on_new_branch push_data, project
end end
......
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'guard' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('guard', 'guard')
path = File.expand_path("~/.ssh/id_rsa.pub") path = File.expand_path("~/.ssh/bitbucket_rsa.pub")
Gitlab::BitbucketImport.public_key = File.read(path) if File.exist?(path) Gitlab::BitbucketImport.public_key = File.read(path) if File.exist?(path)
# Slowpoke extends Rack::Timeout to gracefully kill Unicorn workers so they can clean up state.
Slowpoke.timeout = 60
# The `Rack::Timeout` middleware kills requests after 60 seconds (as set above).
# We're replacing it with our `Gitlab::Middleware::Timeout` that does the same,
# except ignoring Git-over-HTTP requests, letting those take as long as they need.
Rails.application.config.middleware.swap(Rack::Timeout, Gitlab::Middleware::Timeout)
...@@ -23,8 +23,8 @@ en: ...@@ -23,8 +23,8 @@ en:
timeout: 'Your session expired, please sign in again to continue.' timeout: 'Your session expired, please sign in again to continue.'
inactive: 'Your account was not activated yet.' inactive: 'Your account was not activated yet.'
sessions: sessions:
signed_in: 'Signed in successfully.' signed_in: ''
signed_out: 'Signed out successfully.' signed_out: ''
users_sessions: users_sessions:
user: user:
signed_in: 'Signed in successfully.' signed_in: 'Signed in successfully.'
...@@ -57,4 +57,4 @@ en: ...@@ -57,4 +57,4 @@ en:
reset_password_instructions: reset_password_instructions:
subject: 'Reset password instructions' subject: 'Reset password instructions'
unlock_instructions: unlock_instructions:
subject: 'Unlock Instructions' subject: 'Unlock Instructions'
\ No newline at end of file
...@@ -198,7 +198,10 @@ Gitlab::Application.routes.draw do ...@@ -198,7 +198,10 @@ Gitlab::Application.routes.draw do
end end
get 'u/:username/calendar' => 'users#calendar', as: :user_calendar, get 'u/:username/calendar' => 'users#calendar', as: :user_calendar,
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } constraints: { username: /.*/ }
get 'u/:username/calendar_activities' => 'users#calendar_activities', as: :user_calendar_activities,
constraints: { username: /.*/ }
get '/u/:username' => 'users#show', as: :user, get '/u/:username' => 'users#show', as: :user,
constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ } constraints: { username: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
...@@ -239,7 +242,7 @@ Gitlab::Application.routes.draw do ...@@ -239,7 +242,7 @@ Gitlab::Application.routes.draw do
resources :group_members, only: [:index, :create, :update, :destroy] do resources :group_members, only: [:index, :create, :update, :destroy] do
delete :leave, on: :collection delete :leave, on: :collection
end end
resource :avatar, only: [:destroy] resource :avatar, only: [:destroy]
resources :milestones, only: [:index, :show, :update] resources :milestones, only: [:index, :show, :update]
end end
...@@ -315,14 +318,6 @@ Gitlab::Application.routes.draw do ...@@ -315,14 +318,6 @@ Gitlab::Application.routes.draw do
as: :tree as: :tree
) )
end end
resource :avatar, only: [:show, :destroy]
resources :commit, only: [:show], constraints: { id: /[[:alnum:]]{6,40}/ } do
get :branches, on: :member
end
resources :commits, only: [:show], constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ }
resources :compare, only: [:index, :create]
scope do scope do
get( get(
...@@ -333,8 +328,24 @@ Gitlab::Application.routes.draw do ...@@ -333,8 +328,24 @@ Gitlab::Application.routes.draw do
) )
end end
resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } scope do
resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do get(
'/commits/*id',
to: 'commits#show',
constraints: { id: /(?:[^.]|\.(?!atom$))+/, format: /atom/ },
as: :commits
)
end
resource :avatar, only: [:show, :destroy]
resources :commit, only: [:show], constraints: { id: /[[:alnum:]]{6,40}/ } do
get :branches, on: :member
end
resources :compare, only: [:index, :create]
resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }
resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do
member do member do
get :commits get :commits
end end
......
...@@ -35,10 +35,22 @@ working_directory "/home/git/gitlab" # available in 0.94.0+ ...@@ -35,10 +35,22 @@ working_directory "/home/git/gitlab" # available in 0.94.0+
listen "/home/git/gitlab/tmp/sockets/gitlab.socket", :backlog => 1024 listen "/home/git/gitlab/tmp/sockets/gitlab.socket", :backlog => 1024
listen "127.0.0.1:8080", :tcp_nopush => true listen "127.0.0.1:8080", :tcp_nopush => true
# Kill workers after 1 hour. # nuke workers after 30 seconds instead of 60 seconds (the default)
# A shorter timeout of 60 seconds is enforced by rack-timeout for web requests. #
# Git-over-HTTP only has the below timeout since large pulls/pushes can take a long time. # NOTICE: git push over http depends on this value.
timeout 60 * 60 # If you want be able to push huge amount of data to git repository over http
# you will have to increase this value too.
#
# Example of output if you try to push 1GB repo to GitLab over http.
# -> git push http://gitlab.... master
#
# error: RPC failed; result=18, HTTP code = 200
# fatal: The remote end hung up unexpectedly
# fatal: The remote end hung up unexpectedly
#
# For more information see http://stackoverflow.com/a/21682112/752049
#
timeout 60
# feel free to point this anywhere accessible on the filesystem # feel free to point this anywhere accessible on the filesystem
pid "/home/git/gitlab/tmp/pids/unicorn.pid" pid "/home/git/gitlab/tmp/pids/unicorn.pid"
......
class AddLocationToUser < ActiveRecord::Migration
def change
add_column :users, :location, :string
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: 20150313012111) do ActiveRecord::Schema.define(version: 20150320234437) 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"
...@@ -458,7 +458,6 @@ ActiveRecord::Schema.define(version: 20150313012111) do ...@@ -458,7 +458,6 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.integer "notification_level", default: 1, null: false t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at" t.datetime "password_expires_at"
t.integer "created_by_id" t.integer "created_by_id"
t.datetime "last_credential_check_at"
t.string "avatar" t.string "avatar"
t.string "confirmation_token" t.string "confirmation_token"
t.datetime "confirmed_at" t.datetime "confirmed_at"
...@@ -466,6 +465,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do ...@@ -466,6 +465,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.string "unconfirmed_email" t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false t.string "website_url", default: "", null: false
t.datetime "last_credential_check_at"
t.string "github_access_token" t.string "github_access_token"
t.string "gitlab_access_token" t.string "gitlab_access_token"
t.string "notification_email" t.string "notification_email"
...@@ -473,6 +473,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do ...@@ -473,6 +473,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.boolean "password_automatically_set", default: false t.boolean "password_automatically_set", default: false
t.string "bitbucket_access_token" t.string "bitbucket_access_token"
t.string "bitbucket_access_token_secret" t.string "bitbucket_access_token_secret"
t.string "location"
end end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
......
...@@ -375,7 +375,7 @@ Parameters: ...@@ -375,7 +375,7 @@ Parameters:
} }
}, },
{ {
"note": "_Status changed to closed_", "note": "Status changed to closed",
"author": { "author": {
"id": 11, "id": 11,
"username": "admin", "username": "admin",
......
...@@ -21,7 +21,7 @@ Parameters: ...@@ -21,7 +21,7 @@ Parameters:
[ [
{ {
"id": 302, "id": 302,
"body": "_Status changed to closed_", "body": "Status changed to closed",
"attachment": null, "attachment": null,
"author": { "author": {
"id": 1, "id": 1,
......
...@@ -54,7 +54,7 @@ To serve repositories over SSH there's an add-on application called gitlab-shell ...@@ -54,7 +54,7 @@ To serve repositories over SSH there's an add-on application called gitlab-shell
![GitLab Diagram Overview](gitlab_diagram_overview.png) ![GitLab Diagram Overview](gitlab_diagram_overview.png)
A typical install of GitLab will be on Ubuntu Linux or RHEL/CentOS. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs. A typical install of GitLab will be on GNU/Linux. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs.
The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository. `/home/git/gitlab-satellites` keeps checked out repositories when performing actions such as a merge request, editing files in the web interface, etc. The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository. `/home/git/gitlab-satellites` keeps checked out repositories when performing actions such as a merge request, editing files in the web interface, etc.
......
...@@ -76,7 +76,7 @@ Notice: The 25 workers of Sidekiq will show up as separate processes in your pro ...@@ -76,7 +76,7 @@ Notice: The 25 workers of Sidekiq will show up as separate processes in your pro
## Unicorn Workers ## Unicorn Workers
It's possible to increase the amount of unicorn workers and tis will usually help for to reduce the response time of the applications and increase the ability to handle parallel requests. It's possible to increase the amount of unicorn workers and this will usually help for to reduce the response time of the applications and increase the ability to handle parallel requests.
For most instances we recommend using: CPU cores + 1 = unicorn workers. For most instances we recommend using: CPU cores + 1 = unicorn workers.
So for a machine with 2 cores, 3 unicorn workers is ideal. So for a machine with 2 cores, 3 unicorn workers is ideal.
...@@ -106,4 +106,4 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o ...@@ -106,4 +106,4 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
- Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/)) - Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/))
- Safari 7+ (known problem: required fields in html5 do not work) - Safari 7+ (known problem: required fields in html5 do not work)
- Opera (Latest released version) - Opera (Latest released version)
- IE 10+ - IE 10+
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Import projects from Bitbucket and login to your GitLab instance with your Bitbucket account. Import projects from Bitbucket and login to your GitLab instance with your Bitbucket account.
To enable the Bitbucket OmniAuth provider you must register your application with Bitbucket. To enable the Bitbucket OmniAuth provider you must register your application with Bitbucket.
Bitbucket will generate an application ID and secret key for you to use. Bitbucket will generate an application ID and secret key for you to use.
1. Sign in to Bitbucket. 1. Sign in to Bitbucket.
...@@ -19,8 +19,8 @@ Bitbucket will generate an application ID and secret key for you to use. ...@@ -19,8 +19,8 @@ Bitbucket will generate an application ID and secret key for you to use.
- URL: The URL to your GitLab installation. 'https://gitlab.company.com' - URL: The URL to your GitLab installation. 'https://gitlab.company.com'
1. Select "Save". 1. Select "Save".
1. You should now see a Key and Secret in the list of OAuth customers. 1. You should now see a Key and Secret in the list of OAuth customers.
Keep this page open as you continue configuration. Keep this page open as you continue configuration.
1. On your GitLab server, open the configuration file. 1. On your GitLab server, open the configuration file.
...@@ -70,13 +70,13 @@ Bitbucket will generate an application ID and secret key for you to use. ...@@ -70,13 +70,13 @@ Bitbucket will generate an application ID and secret key for you to use.
1. Restart GitLab for the changes to take effect. 1. Restart GitLab for the changes to take effect.
On the sign in page there should now be a Bitbucket icon below the regular sign in form. On the sign in page there should now be a Bitbucket icon below the regular sign in form.
Click the icon to begin the authentication process. Bitbucket will ask the user to sign in and authorize the GitLab application. Click the icon to begin the authentication process. Bitbucket will ask the user to sign in and authorize the GitLab application.
If everything goes well the user will be returned to GitLab and will be signed in. If everything goes well the user will be returned to GitLab and will be signed in.
## Bitbucket project import ## Bitbucket project import
To allow projects to be imported directly into GitLab, Bitbucket requires two extra setup steps compared to GitHub and GitLab.com. To allow projects to be imported directly into GitLab, Bitbucket requires two extra setup steps compared to GitHub and GitLab.com.
Bitbucket doesn't allow OAuth applications to clone repositories over HTTPS, and instead requires GitLab to use SSH and identify itself using your GitLab server's SSH key. Bitbucket doesn't allow OAuth applications to clone repositories over HTTPS, and instead requires GitLab to use SSH and identify itself using your GitLab server's SSH key.
...@@ -95,7 +95,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org ...@@ -95,7 +95,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org
```sh ```sh
The authenticity of host 'bitbucket.org (207.223.240.182)' can't be established. The authenticity of host 'bitbucket.org (207.223.240.182)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40. RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)? Are you sure you want to continue connecting (yes/no)?
``` ```
1. If the fingerprint matches, type `yes` to continue connecting and have 'bitbucket.org' be added to your known hosts. 1. If the fingerprint matches, type `yes` to continue connecting and have 'bitbucket.org' be added to your known hosts.
...@@ -104,7 +104,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org ...@@ -104,7 +104,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org
### Step 2: Public key ### Step 2: Public key
To be able to access repositories on Bitbucket, GitLab will automatically register your public key with Bitbucket as a deploy key for the repositories to be imported. Your public key needs to be at `~/.ssh/id_rsa.pub`, which will expand to `/home/git/.ssh/id_rsa.pub` in most configurations. To be able to access repositories on Bitbucket, GitLab will automatically register your public key with Bitbucket as a deploy key for the repositories to be imported. Your public key needs to be at `~/.ssh/bitbucket_rsa.pub`, which will expand to `/home/git/.ssh/bitbucket_rsa.pub` in most configurations.
If you have that file in place, you're all set and should see the "Import projects from Bitbucket" option enabled. If you don't, do the following: If you have that file in place, you're all set and should see the "Import projects from Bitbucket" option enabled. If you don't, do the following:
...@@ -114,6 +114,7 @@ If you have that file in place, you're all set and should see the "Import projec ...@@ -114,6 +114,7 @@ If you have that file in place, you're all set and should see the "Import projec
sudo -u git -H ssh-keygen sudo -u git -H ssh-keygen
``` ```
When asked `Enter file in which to save the key` specify the correct path, eg. `/home/git/.ssh/bitbucket_rsa`.
Make sure to use an **empty passphrase**. Make sure to use an **empty passphrase**.
2. Restart GitLab to allow it to find the new public key. 2. Restart GitLab to allow it to find the new public key.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* [Newlines](#newlines) * [Newlines](#newlines)
* [Multiple underscores in words](#multiple-underscores-in-words) * [Multiple underscores in words](#multiple-underscores-in-words)
* [URL auto-linking](#url-autolinking) * [URL auto-linking](#url-auto-linking)
* [Code and Syntax Highlighting](#code-and-syntax-highlighting) * [Code and Syntax Highlighting](#code-and-syntax-highlighting)
* [Emoji](#emoji) * [Emoji](#emoji)
* [Special GitLab references](#special-gitlab-references) * [Special GitLab references](#special-gitlab-references)
......
...@@ -45,7 +45,7 @@ clip < ~/.ssh/id_rsa.pub ...@@ -45,7 +45,7 @@ clip < ~/.ssh/id_rsa.pub
pbcopy < ~/.ssh/id_rsa.pub pbcopy < ~/.ssh/id_rsa.pub
``` ```
**Linux (requires xclip):** **GNU/Linux (requires xclip):**
```bash ```bash
xclip -sel clip < ~/.ssh/id_rsa.pub xclip -sel clip < ~/.ssh/id_rsa.pub
``` ```
......
...@@ -11,6 +11,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps ...@@ -11,6 +11,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
fill_in "user_linkedin", with: "testlinkedin" fill_in "user_linkedin", with: "testlinkedin"
fill_in "user_twitter", with: "testtwitter" fill_in "user_twitter", with: "testtwitter"
fill_in "user_website_url", with: "testurl" fill_in "user_website_url", with: "testurl"
fill_in "user_location", with: "Ukraine"
click_button "Save changes" click_button "Save changes"
@user.reload @user.reload
end end
...@@ -20,6 +21,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps ...@@ -20,6 +21,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
@user.linkedin.should == 'testlinkedin' @user.linkedin.should == 'testlinkedin'
@user.twitter.should == 'testtwitter' @user.twitter.should == 'testtwitter'
@user.website_url.should == 'testurl' @user.website_url.should == 'testurl'
find("#user_location").value.should == "Ukraine"
end end
step 'I change my avatar' do step 'I change my avatar' do
......
...@@ -209,13 +209,13 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -209,13 +209,13 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
step 'I click link "Hide inline discussion" of the second file' do step 'I click link "Hide inline discussion" of the second file' do
within '.files [id^=diff]:nth-child(2)' do within '.files [id^=diff]:nth-child(2)' do
click_link 'Show/Hide comments' find('.js-toggle-diff-comments').click
end end
end end
step 'I click link "Show inline discussion" of the second file' do step 'I click link "Show inline discussion" of the second file' do
within '.files [id^=diff]:nth-child(2)' do within '.files [id^=diff]:nth-child(2)' do
click_link 'Show/Hide comments' find('.js-toggle-diff-comments').click
end end
end end
......
...@@ -16,7 +16,7 @@ module Backup ...@@ -16,7 +16,7 @@ module Backup
if project.empty_repo? if project.empty_repo?
$progress.puts "[SKIPPED]".cyan $progress.puts "[SKIPPED]".cyan
else else
cmd = %W(git --git-dir=#{path_to_repo(project)} bundle create #{path_to_bundle(project)} --all) cmd = %W(tar -cf #{path_to_bundle(project)} -C #{path_to_repo(project)} .)
output, status = Gitlab::Popen.popen(cmd) output, status = Gitlab::Popen.popen(cmd)
if status.zero? if status.zero?
$progress.puts "[DONE]".green $progress.puts "[DONE]".green
...@@ -64,7 +64,8 @@ module Backup ...@@ -64,7 +64,8 @@ module Backup
project.namespace.ensure_dir_exist if project.namespace project.namespace.ensure_dir_exist if project.namespace
if File.exists?(path_to_bundle(project)) if File.exists?(path_to_bundle(project))
cmd = %W(git clone --bare #{path_to_bundle(project)} #{path_to_repo(project)}) FileUtils.mkdir_p(path_to_repo(project))
cmd = %W(tar -xf #{path_to_bundle(project)} -C #{path_to_repo(project)})
else else
cmd = %W(git init --bare #{path_to_repo(project)}) cmd = %W(git init --bare #{path_to_repo(project)})
end end
......
...@@ -22,6 +22,14 @@ module Gitlab ...@@ -22,6 +22,14 @@ module Gitlab
end end
end end
def self.get_commits_for_date(projects, user, date)
user_commits = {}
projects.reject(&:forked?).each do |project|
user_commits[project] = ProjectContributions.new(project, user).user_commits_on_date(date)
end
user_commits
end
def starting_year def starting_year
(Time.now - 1.year).strftime("%Y") (Time.now - 1.year).strftime("%Y")
end end
......
...@@ -3,11 +3,12 @@ module Gitlab ...@@ -3,11 +3,12 @@ module Gitlab
def self.force_push?(project, oldrev, newrev) def self.force_push?(project, oldrev, newrev)
return false if project.empty_repo? return false if project.empty_repo?
if oldrev != Gitlab::Git::BLANK_SHA && newrev != Gitlab::Git::BLANK_SHA # Created or deleted branch
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false
else
missed_refs, _ = Gitlab::Popen.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})) missed_refs, _ = Gitlab::Popen.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev}))
missed_refs.split("\n").size > 0 missed_refs.split("\n").size > 0
else
false
end end
end end
end end
......
module Gitlab
module Middleware
class Timeout < Rack::Timeout
GRACK_REGEX = /[-\/\w\.]+\.git\//.freeze
def call(env)
return @app.call(env) if env['PATH_INFO'] =~ GRACK_REGEX
super
end
end
end
end
...@@ -27,6 +27,12 @@ module Gitlab ...@@ -27,6 +27,12 @@ module Gitlab
# Get latest 20 commits ASC # Get latest 20 commits ASC
commits_limited = commits.last(20) commits_limited = commits.last(20)
# For performance purposes maximum 20 latest commits
# will be passed as post receive hook data.
commit_attrs = commits_limited.map do |commit|
commit.hook_attrs(project)
end
type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push" type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push"
# Hash to be passed as post_receive_data # Hash to be passed as post_receive_data
...@@ -49,17 +55,10 @@ module Gitlab ...@@ -49,17 +55,10 @@ module Gitlab
git_ssh_url: project.ssh_url_to_repo, git_ssh_url: project.ssh_url_to_repo,
visibility_level: project.visibility_level visibility_level: project.visibility_level
}, },
commits: [], commits: commit_attrs,
total_commits_count: commits_count total_commits_count: commits_count
} }
# For performance purposes maximum 20 latest commits
# will be passed as post receive hook data.
commits_limited.each do |commit|
data[:commits] << commit.hook_attrs(project)
end
data[:commits] = "" if data[:commits].count == 0
data data
end end
...@@ -72,7 +71,8 @@ module Gitlab ...@@ -72,7 +71,8 @@ module Gitlab
end end
def checkout_sha(repository, newrev, ref) def checkout_sha(repository, newrev, ref)
if newrev != Gitlab::Git::BLANK_SHA && Gitlab::Git.tag_ref?(ref) # Find sha for tag, except when it was deleted.
if Gitlab::Git.tag_ref?(ref) && !Gitlab::Git.blank_ref?(newrev)
tag_name = Gitlab::Git.ref_name(ref) tag_name = Gitlab::Git.ref_name(ref)
tag = repository.find_tag(tag_name) tag = repository.find_tag(tag_name)
......
...@@ -35,7 +35,13 @@ module Gitlab ...@@ -35,7 +35,13 @@ module Gitlab
end end
def non_restricted_level?(level) def non_restricted_level?(level)
! current_application_settings.restricted_visibility_levels.include?(level) restricted_levels = current_application_settings.restricted_visibility_levels
if restricted_levels.nil?
true
else
!restricted_levels.include?(level)
end
end end
def valid_level?(level) def valid_level?(level)
......
desc 'Security check via brakeman' desc 'Security check via brakeman'
task :brakeman do task :brakeman do
if system("brakeman --skip-files lib/backup/repository.rb -w3 -z") if system("brakeman --skip-files lib/backup/repository.rb -w3 -z")
exit 0 puts 'Security check succeed'
else else
puts 'Security check failed' puts 'Security check failed'
exit 1 exit 1
......
...@@ -90,13 +90,14 @@ namespace :gitlab do ...@@ -90,13 +90,14 @@ namespace :gitlab do
warn_user_is_not_gitlab warn_user_is_not_gitlab
block_flag = ENV['BLOCK'] block_flag = ENV['BLOCK']
User.ldap.each do |ldap_user| User.find_each do |user|
print "#{ldap_user.name} (#{ldap_user.extern_uid}) ..." next unless user.ldap_user?
if Gitlab::LDAP::Access.allowed?(ldap_user) print "#{user.name} (#{user.ldap_identity.extern_uid}) ..."
if Gitlab::LDAP::Access.allowed?(user)
puts " [OK]".green puts " [OK]".green
else else
if block_flag if block_flag
ldap_user.block! unless ldap_user.blocked? user.block! unless user.blocked?
puts " [BLOCKED]".red puts " [BLOCKED]".red
else else
puts " [NOT IN LDAP]".yellow puts " [NOT IN LDAP]".yellow
......
<!DOCTYPE html>
<html>
<head>
<title>Page took too long to load (503)</title>
<link href="/static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>503</h1>
<h3>Page took too long to load.</h3>
<hr/>
<p>Please contact your GitLab administrator if this problem persists.</p>
</body>
</html>
require 'spec_helper' require 'spec_helper'
describe UsersController do describe UsersController do
let(:user) { create(:user, username: "user1", name: "User 1", email: "user1@gitlab.com") } let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') }
before do before do
sign_in(user) sign_in(user)
end end
describe "GET #show" do describe 'GET #show' do
render_views render_views
it "renders the show template" do it 'renders the show template' do
get :show, username: user.username get :show, username: user.username
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response).to render_template("show") expect(response).to render_template('show')
end end
end end
describe "GET #calendar" do describe 'GET #calendar' do
it "renders calendar" do it 'renders calendar' do
get :calendar, username: user.username get :calendar, username: user.username
expect(response).to render_template("calendar") expect(response).to render_template('calendar')
end end
end end
end
describe 'GET #calendar_activities' do
include RepoHelpers
let(:project) { create(:project) }
let(:calendar_user) { create(:user, email: sample_commit.author_email) }
let(:commit1) { '0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80' }
let(:commit2) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
before do
allow_any_instance_of(User).to receive(:contributed_projects_ids).and_return([project.id])
project.team << [user, :developer]
end
it 'assigns @commit_count' do
get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
expect(assigns(:commit_count)).to eq(2)
end
it 'assigns @calendar_date' do
get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
expect(assigns(:calendar_date)).to eq(Date.parse('2014-07-31'))
end
it 'assigns @calendar_activities' do
get :calendar_activities, username: calendar_user.username, date: '2014-07-31'
expect(assigns(:calendar_activities).values.flatten.map(&:id)).to eq([commit1, commit2])
end
it 'renders calendar_activities' do
get :calendar_activities, username: calendar_user.username
expect(response).to render_template('calendar_activities')
end
end
end
...@@ -120,4 +120,18 @@ describe Gitlab::ReferenceExtractor do ...@@ -120,4 +120,18 @@ describe Gitlab::ReferenceExtractor do
expect(extracted[0][1].message).to eq(commit.message) expect(extracted[0][1].message).to eq(commit.message)
end end
end end
context 'with a project with an underscore' do
let(:project) { create(:project, path: 'test_project') }
let(:issue) { create(:issue, project: project) }
it 'handles project issue references' do
subject.analyze("this refers issue #{project.path_with_namespace}##{issue.iid}",
project)
extracted = subject.issues_for(project)
expect(extracted.size).to eq(1)
expect(extracted).to eq([issue])
end
end
end end
require 'spec_helper'
describe ExternalWikiService do
include ExternalWikiHelper
describe "Associations" do
it { should belong_to :project }
it { should have_one :service_hook }
end
describe "Validations" do
context "active" do
before do
subject.active = true
end
it { should validate_presence_of :external_wiki_url }
end
end
describe 'External wiki' do
let(:project) { create(:project) }
context 'when it is active' do
before do
properties = { 'external_wiki_url' => 'https://gitlab.com' }
@service = project.create_external_wiki_service(active: true, properties: properties)
end
after do
@service.destroy!
end
it 'should replace the wiki url' do
wiki_path = get_project_wiki_path(project)
wiki_path.should match('https://gitlab.com')
end
end
end
end
...@@ -182,14 +182,14 @@ describe Note do ...@@ -182,14 +182,14 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to match(/Status changed to #{status}/) } it { is_expected.to eq("Status changed to #{status}") }
end end
it 'appends a back-reference if a closing mentionable is supplied' do it 'appends a back-reference if a closing mentionable is supplied' do
commit = double('commit', gfm_reference: 'commit 123456') commit = double('commit', gfm_reference: 'commit 123456')
n = Note.create_status_change_note(thing, project, author, status, commit) n = Note.create_status_change_note(thing, project, author, status, commit)
expect(n.note).to match(/Status changed to #{status} by commit 123456/) expect(n.note).to eq("Status changed to #{status} by commit 123456")
end end
end end
...@@ -197,7 +197,7 @@ describe Note do ...@@ -197,7 +197,7 @@ describe Note do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:thing) { create(:issue, project: project) } let(:thing) { create(:issue, project: project) }
let(:author) { create(:user) } let(:author) { create(:user) }
let(:assignee) { create(:user) } let(:assignee) { create(:user, username: "assigned_user") }
subject { Note.create_assignee_change_note(thing, project, author, assignee) } subject { Note.create_assignee_change_note(thing, project, author, assignee) }
...@@ -227,7 +227,7 @@ describe Note do ...@@ -227,7 +227,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to match(/Reassigned to @#{assignee.username}/) } it { is_expected.to eq('Reassigned to @assigned_user') }
end end
context 'assignee is removed' do context 'assignee is removed' do
...@@ -235,11 +235,95 @@ describe Note do ...@@ -235,11 +235,95 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to match(/Assignee removed/) } it { is_expected.to eq('Assignee removed') }
end end
end end
end end
describe '#create_labels_change_note' do
let(:project) { create(:project) }
let(:thing) { create(:issue, project: project) }
let(:author) { create(:user) }
let(:label1) { create(:label) }
let(:label2) { create(:label) }
let(:added_labels) { [label1, label2] }
let(:removed_labels) { [] }
subject { Note.create_labels_change_note(thing, project, author, added_labels, removed_labels) }
context 'creates and saves a Note' do
it { is_expected.to be_a Note }
describe '#id' do
subject { super().id }
it { is_expected.not_to be_nil }
end
end
describe '#noteable' do
subject { super().noteable }
it { is_expected.to eq(thing) }
end
describe '#project' do
subject { super().project }
it { is_expected.to eq(thing.project) }
end
describe '#author' do
subject { super().author }
it { is_expected.to eq(author) }
end
describe '#note' do
subject { super().note }
it { is_expected.to eq("Added ~#{label1.id} ~#{label2.id} labels") }
end
context 'label is removed' do
let(:added_labels) { [label1] }
let(:removed_labels) { [label2] }
describe '#note' do
subject { super().note }
it { is_expected.to eq("Added ~#{label1.id} and removed ~#{label2.id} labels") }
end
end
end
describe '#create_milestone_change_note' do
let(:project) { create(:project) }
let(:thing) { create(:issue, project: project) }
let(:milestone) { create(:milestone, project: project, title: "first_milestone") }
let(:author) { create(:user) }
subject { Note.create_milestone_change_note(thing, project, author, milestone) }
context 'creates and saves a Note' do
it { is_expected.to be_a Note }
describe '#id' do
subject { super().id }
it { is_expected.not_to be_nil }
end
end
describe '#project' do
subject { super().project }
it { is_expected.to eq(thing.project) }
end
describe '#author' do
subject { super().author }
it { is_expected.to eq(author) }
end
describe '#note' do
subject { super().note }
it { is_expected.to eq("Milestone changed to first_milestone") }
end
end
describe '#create_cross_reference_note' do describe '#create_cross_reference_note' do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:author) { create(:user) } let(:author) { create(:user) }
...@@ -272,7 +356,7 @@ describe Note do ...@@ -272,7 +356,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in merge request !#{mergereq.iid}_") } it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") }
end end
end end
...@@ -288,7 +372,7 @@ describe Note do ...@@ -288,7 +372,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in commit #{commit.sha}_") } it { is_expected.to eq("mentioned in commit #{commit.sha}") }
end end
end end
...@@ -309,7 +393,7 @@ describe Note do ...@@ -309,7 +393,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in issue ##{issue.iid}_") } it { is_expected.to eq("mentioned in issue ##{issue.iid}") }
end end
end end
...@@ -330,7 +414,7 @@ describe Note do ...@@ -330,7 +414,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in merge request !#{mergereq.iid}_") } it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") }
end end
end end
...@@ -362,7 +446,7 @@ describe Note do ...@@ -362,7 +446,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in issue ##{issue.iid}_") } it { is_expected.to eq("mentioned in issue ##{issue.iid}") }
end end
end end
...@@ -389,7 +473,7 @@ describe Note do ...@@ -389,7 +473,7 @@ describe Note do
describe '#note' do describe '#note' do
subject { super().note } subject { super().note }
it { is_expected.to eq("_mentioned in commit #{parent_commit.id}_") } it { is_expected.to eq("mentioned in commit #{parent_commit.id}") }
end end
end end
end end
...@@ -421,6 +505,41 @@ describe Note do ...@@ -421,6 +505,41 @@ describe Note do
it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy } it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy }
it { expect(Note.cross_reference_exists?(commit1, commit0)).to be_falsey } it { expect(Note.cross_reference_exists?(commit1, commit0)).to be_falsey }
end end
context 'legacy note with Markdown emphasis' do
let(:issue2) { create :issue, project: project }
let!(:note) do
create :note, system: true, noteable_id: issue2.id,
noteable_type: "Issue", note: "_mentioned in issue " \
"#{issue.project.path_with_namespace}##{issue.iid}_"
end
it 'detects if a mentionable with emphasis has been mentioned' do
expect(Note.cross_reference_exists?(issue2, issue)).to be_truthy
end
end
end
describe '#cross_references_with_underscores?' do
let(:project) { create :project, path: "first_project" }
let(:second_project) { create :project, path: "second_project" }
let(:author) { create :user }
let(:issue0) { create :issue, project: project }
let(:issue1) { create :issue, project: second_project }
let!(:note) { Note.create_cross_reference_note(issue0, issue1, author, project) }
it 'detects if a mentionable has already been mentioned' do
expect(Note.cross_reference_exists?(issue0, issue1)).to be_truthy
end
it 'detects if a mentionable has not already been mentioned' do
expect(Note.cross_reference_exists?(issue1, issue0)).to be_falsey
end
it 'detects that text has underscores' do
expect(note.note).to eq("mentioned in issue #{second_project.path_with_namespace}##{issue1.iid}")
end
end end
describe '#system?' do describe '#system?' do
...@@ -429,6 +548,8 @@ describe Note do ...@@ -429,6 +548,8 @@ describe Note do
let(:other) { create(:issue, project: project) } let(:other) { create(:issue, project: project) }
let(:author) { create(:user) } let(:author) { create(:user) }
let(:assignee) { create(:user) } let(:assignee) { create(:user) }
let(:label) { create(:label) }
let(:milestone) { create(:milestone) }
it 'should recognize user-supplied notes as non-system' do it 'should recognize user-supplied notes as non-system' do
@note = create(:note_on_issue) @note = create(:note_on_issue)
...@@ -449,6 +570,16 @@ describe Note do ...@@ -449,6 +570,16 @@ describe Note do
@note = Note.create_assignee_change_note(issue, project, author, assignee) @note = Note.create_assignee_change_note(issue, project, author, assignee)
expect(@note).to be_system expect(@note).to be_system
end end
it 'should identify label-change notes as system notes' do
@note = Note.create_labels_change_note(issue, project, author, [label], [])
expect(@note).to be_system
end
it 'should identify milestone-change notes as system notes' do
@note = Note.create_milestone_change_note(issue, project, author, milestone)
expect(@note).to be_system
end
end end
describe :authorization do describe :authorization do
......
...@@ -59,7 +59,7 @@ describe BuildboxService do ...@@ -59,7 +59,7 @@ describe BuildboxService do
describe :build_page do describe :build_page do
it 'returns the correct build page' do it 'returns the correct build page' do
expect(@service.build_page('2ab7834c')).to eq( expect(@service.build_page('2ab7834c', nil)).to eq(
'https://buildbox.io/account-name/example-project/builds?commit=2ab7834c' 'https://buildbox.io/account-name/example-project/builds?commit=2ab7834c'
) )
end end
......
...@@ -39,11 +39,11 @@ describe GitlabCiService do ...@@ -39,11 +39,11 @@ describe GitlabCiService do
end end
describe :commit_status_path do describe :commit_status_path do
it { expect(@service.commit_status_path("2ab7834c")).to eq("http://ci.gitlab.org/projects/2/commits/2ab7834c/status.json?token=verySecret")} it { expect(@service.commit_status_path("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c/status.json?token=verySecret")}
end end
describe :build_page do describe :build_page do
it { expect(@service.build_page("2ab7834c")).to eq("http://ci.gitlab.org/projects/2/commits/2ab7834c")} it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c")}
end end
end end
end end
...@@ -29,7 +29,7 @@ describe Repository do ...@@ -29,7 +29,7 @@ describe Repository do
subject { repository.timestamps_by_user_log(user) } subject { repository.timestamps_by_user_log(user) }
it { is_expected.to eq(["2014-08-06", "2014-07-31", "2014-07-31"]) } it { is_expected.to eq(['2014-08-06', '2014-07-31', '2014-07-31']) }
end end
describe 'multiple emails for user' do describe 'multiple emails for user' do
...@@ -38,7 +38,22 @@ describe Repository do ...@@ -38,7 +38,22 @@ describe Repository do
subject { repository.timestamps_by_user_log(user) } subject { repository.timestamps_by_user_log(user) }
it { is_expected.to eq(["2015-01-10", "2014-08-06", "2014-07-31", "2014-07-31"]) } it { is_expected.to eq(['2015-01-10', '2014-08-06', '2014-07-31', '2014-07-31']) }
end
end
context :commits_by_user_on_date_log do
describe 'single e-mail for user' do
let(:user) { create(:user, email: sample_commit.author_email) }
let(:commit1) { '0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80' }
let(:commit2) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
subject { repository.commits_by_user_on_date_log(user,Date.new(2014, 07, 31)) }
it 'contains the exepected commits' do
expect(subject.flatten.map(&:id)).to eq([commit1, commit2])
end
end end
end end
end end
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