summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG19
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock34
-rw-r--r--app/assets/images/authbuttons/bitbucket_32.pngbin2713 -> 0 bytes
-rw-r--r--app/assets/images/authbuttons/github_32.pngbin1822 -> 0 bytes
-rw-r--r--app/assets/images/authbuttons/gitlab_32.pngbin1039 -> 0 bytes
-rw-r--r--app/assets/images/authbuttons/gitlab_64.pngbin3013 -> 6559 bytes
-rw-r--r--app/assets/images/authbuttons/google_32.pngbin1501 -> 0 bytes
-rw-r--r--app/assets/images/authbuttons/twitter_32.pngbin1311 -> 0 bytes
-rw-r--r--app/assets/javascripts/issue.js.coffee2
-rw-r--r--app/assets/javascripts/merge_request.js.coffee4
-rw-r--r--app/assets/javascripts/notes.js.coffee2
-rw-r--r--app/assets/javascripts/notes_votes.js.coffee20
-rw-r--r--app/assets/stylesheets/generic/common.scss19
-rw-r--r--app/assets/stylesheets/generic/forms.scss4
-rw-r--r--app/assets/stylesheets/pages/dashboard.scss2
-rw-r--r--app/assets/stylesheets/pages/diff.scss4
-rw-r--r--app/assets/stylesheets/pages/header.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss8
-rw-r--r--app/assets/stylesheets/pages/login.scss9
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss6
-rw-r--r--app/assets/stylesheets/pages/profile.scss45
-rw-r--r--app/assets/stylesheets/pages/projects.scss8
-rw-r--r--app/assets/stylesheets/pages/votes.scss35
-rw-r--r--app/assets/stylesheets/print.scss4
-rw-r--r--app/controllers/profiles/accounts_controller.rb6
-rw-r--r--app/controllers/profiles_controller.rb5
-rw-r--r--app/controllers/projects/merge_requests_controller.rb4
-rw-r--r--app/controllers/search_controller.rb46
-rw-r--r--app/helpers/application_helper.rb6
-rw-r--r--app/helpers/gitlab_routing_helper.rb1
-rw-r--r--app/helpers/merge_requests_helper.rb2
-rw-r--r--app/helpers/oauth_helper.rb11
-rw-r--r--app/helpers/profile_helper.rb6
-rw-r--r--app/models/merge_request.rb4
-rw-r--r--app/models/note.rb25
-rw-r--r--app/models/project_services/bamboo_service.rb4
-rw-r--r--app/models/project_services/buildbox_service.rb4
-rw-r--r--app/models/project_services/ci_service.rb4
-rw-r--r--app/models/project_services/gitlab_ci_service.rb20
-rw-r--r--app/models/project_services/teamcity_service.rb4
-rw-r--r--app/models/project_wiki.rb2
-rw-r--r--app/models/repository.rb39
-rw-r--r--app/models/wiki_page.rb3
-rw-r--r--app/services/create_tag_service.rb3
-rw-r--r--app/services/git_push_service.rb62
-rw-r--r--app/services/git_tag_push_service.rb18
-rw-r--r--app/services/notification_service.rb2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml2
-rw-r--r--app/views/groups/show.html.haml15
-rw-r--r--app/views/profiles/accounts/show.html.haml21
-rw-r--r--app/views/profiles/show.html.haml3
-rw-r--r--app/views/projects/_commit_button.html.haml3
-rw-r--r--app/views/projects/issues/_discussion.html.haml12
-rw-r--r--app/views/projects/issues/_issue.html.haml2
-rw-r--r--app/views/projects/issues/_issue_context.html.haml4
-rw-r--r--app/views/projects/merge_requests/_discussion.html.haml10
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_mr_ci.html.haml6
-rw-r--r--app/views/projects/new.html.haml105
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/users/_profile.html.haml6
-rw-r--r--app/views/users/show.html.haml32
-rw-r--r--app/views/votes/_votes_block.html.haml14
-rw-r--r--app/views/votes/_votes_inline.html.haml4
-rw-r--r--app/workers/irker_worker.rb6
-rw-r--r--config/initializers/public_key.rb2
-rw-r--r--config/initializers/timeout.rb8
-rw-r--r--config/routes.rb36
-rw-r--r--config/unicorn.rb.example20
-rw-r--r--db/migrate/20150320234437_add_location_to_user.rb5
-rw-r--r--db/schema.rb3
-rw-r--r--doc/api/merge_requests.md2
-rw-r--r--doc/api/notes.md2
-rw-r--r--doc/install/requirements.md4
-rw-r--r--doc/integration/bitbucket.md17
-rw-r--r--doc/markdown/markdown.md2
-rw-r--r--doc/update/patch_versions.md2
-rw-r--r--doc/update/upgrader.md2
-rw-r--r--features/dashboard/new_project.feature13
-rw-r--r--features/steps/dashboard/new_project.rb27
-rw-r--r--features/steps/profile/profile.rb2
-rw-r--r--lib/backup/manager.rb43
-rw-r--r--lib/backup/repository.rb5
-rw-r--r--lib/gitlab/force_push_check.rb7
-rw-r--r--lib/gitlab/middleware/timeout.rb13
-rw-r--r--lib/gitlab/push_data_builder.rb6
-rw-r--r--lib/tasks/brakeman.rake2
-rw-r--r--lib/tasks/gitlab/cleanup.rake9
-rw-r--r--public/503.html13
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb14
-rw-r--r--spec/models/note_spec.rb153
-rw-r--r--spec/models/project_services/buildbox_service_spec.rb2
-rw-r--r--spec/models/project_services/gitlab_ci_service_spec.rb4
-rw-r--r--spec/models/wiki_page_spec.rb41
-rw-r--r--spec/services/git_push_service_spec.rb5
-rw-r--r--spec/services/git_tag_push_service_spec.rb52
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb63
98 files changed, 862 insertions, 482 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 2bcecb402a0..f5a53747881 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,14 +1,31 @@
Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased)
+ - Fix "Import projects from" button to show the correct instructions (Stan Hu)
+ - Fix dots in Wiki slugs causing errors (Stan Hu)
+ - 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)
- Disable reference creation for comments surrounded by code/preformatted blocks (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)
+ - Fix a link in the patch update guide
- Add a service to support external wikis (Hannes Rosenögger)
- List new commits for newly pushed branch in activity view.
+ - Add sidetiq gem dependency to match EE
- 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
+ - Fix print view for markdown files and wiki pages
+ - Improve GitLab performance when working with git repositories
+ - Add tag message and last commit to tag hook (Kamil Trzciński)
+ - Restrict permissions on backup files
+ - Improve oauth accounts UI in profile page
+ - Add ability to unlink connected accounts
v 7.9.0 (unreleased)
- Add HipChat integration documentation (Stan Hu)
@@ -87,6 +104,8 @@ v 7.9.0 (unreleased)
- Ability to unsubscribe/subscribe to issue or merge request
- Delete deploy key when last connection to a project is destroyed.
- 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
- Fix issue_tracker_id substitution in custom issue trackers
diff --git a/Gemfile b/Gemfile
index ad33116db3e..e7f75055f3f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -31,7 +31,7 @@ gem 'omniauth-shibboleth'
gem 'omniauth-kerberos'
gem 'omniauth-gitlab'
gem 'omniauth-bitbucket'
-gem 'doorkeeper', '2.1.0'
+gem 'doorkeeper', '2.1.3'
gem "rack-oauth2", "~> 1.0.5"
# Browser detection
@@ -48,7 +48,7 @@ gem 'gitlab-grack', '~> 2.0.0.rc2', require: 'grack'
gem 'gitlab_omniauth-ldap', '1.2.1', require: "omniauth-ldap"
# Git Wiki
-gem 'gollum-lib', '~> 4.0.0'
+gem 'gollum-lib', '~> 4.0.2'
# Language detection
gem "gitlab-linguist", "~> 3.0.1", require: "linguist"
@@ -121,6 +121,7 @@ gem "acts-as-taggable-on"
gem 'slim'
gem 'sinatra', require: nil
gem 'sidekiq', '~> 3.3'
+gem 'sidetiq', '0.6.3'
# HTTP requests
gem "httparty"
@@ -180,9 +181,6 @@ gem 'mousetrap-rails'
# Detect and convert string character encoding
gem 'charlock_holmes'
-# Shutting down requests that take too long
-gem "slowpoke"
-
gem "sass-rails", '~> 4.0.2'
gem "coffee-rails"
gem "uglifier"
diff --git a/Gemfile.lock b/Gemfile.lock
index a454461ec26..4f1cab43dd5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -136,8 +136,8 @@ GEM
diff-lcs (1.2.5)
diffy (3.0.3)
docile (1.1.5)
- doorkeeper (2.1.0)
- railties (>= 3.1)
+ doorkeeper (2.1.3)
+ railties (>= 3.2)
dotenv (0.9.0)
dropzonejs-rails (0.4.14)
rails (> 3.1)
@@ -147,7 +147,6 @@ GEM
enumerize (0.7.0)
activesupport (>= 3.2)
equalizer (0.0.8)
- errbase (0.0.2)
erubis (2.7.0)
escape_utils (0.2.4)
eventmachine (1.0.4)
@@ -224,11 +223,11 @@ GEM
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.3)
- gollum-grit_adapter (0.1.0)
- gitlab-grit (~> 2.7.1)
- gollum-lib (4.0.0)
+ gollum-grit_adapter (0.1.3)
+ gitlab-grit (~> 2.7, >= 2.7.1)
+ gollum-lib (4.0.2)
github-markup (~> 1.3.1)
- gollum-grit_adapter (~> 0.1.0)
+ gollum-grit_adapter (~> 0.1, >= 0.1.1)
nokogiri (~> 1.6.4)
rouge (~> 1.7.4)
sanitize (~> 2.1.0)
@@ -291,6 +290,7 @@ GEM
httpauth (0.2.1)
httpclient (2.5.3.3)
i18n (0.7.0)
+ ice_cube (0.11.1)
ice_nine (0.10.0)
jasmine (2.0.2)
jasmine-core (~> 2.0.0)
@@ -429,7 +429,6 @@ GEM
rack
rack-test (0.6.3)
rack (>= 1.0)
- rack-timeout (0.2.0)
rails (4.1.9)
actionmailer (= 4.1.9)
actionpack (= 4.1.9)
@@ -482,9 +481,7 @@ GEM
rest-client (1.6.7)
mime-types (>= 1.16)
rinku (1.7.3)
- robustly (0.0.3)
- errbase
- rouge (1.7.4)
+ rouge (1.7.7)
rspec (2.99.0)
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
@@ -519,7 +516,7 @@ GEM
rubyntlm (0.5.0)
rubypants (0.2.0)
rugged (0.21.4)
- rugments (1.0.0.beta4)
+ rugments (1.0.0.beta5)
safe_yaml (0.9.7)
sanitize (2.1.0)
nokogiri (>= 1.4.4)
@@ -550,6 +547,10 @@ GEM
json
redis (>= 3.0.6)
redis-namespace (>= 1.3.1)
+ sidetiq (0.6.3)
+ celluloid (>= 0.14.1)
+ ice_cube (= 0.11.1)
+ sidekiq (>= 3.0.0)
simple_oauth (0.1.9)
simplecov (0.9.0)
docile (~> 1.1.0)
@@ -566,9 +567,6 @@ GEM
temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1)
slop (3.6.0)
- slowpoke (0.0.5)
- rack-timeout (>= 0.1.0)
- robustly
spinach (0.8.7)
colorize (= 0.5.8)
gherkin-ruby (>= 0.3.1)
@@ -690,7 +688,7 @@ DEPENDENCIES
devise (= 3.2.4)
devise-async (= 0.9.0)
diffy (~> 3.0.3)
- doorkeeper (= 2.1.0)
+ doorkeeper (= 2.1.3)
dropzonejs-rails
email_spec
enumerize
@@ -708,7 +706,7 @@ DEPENDENCIES
gitlab_git (~> 7.1.2)
gitlab_meta (= 7.0)
gitlab_omniauth-ldap (= 1.2.1)
- gollum-lib (~> 4.0.0)
+ gollum-lib (~> 4.0.2)
gon (~> 5.0.0)
grape (~> 0.6.1)
grape-entity (~> 0.4.2)
@@ -771,12 +769,12 @@ DEPENDENCIES
settingslogic
shoulda-matchers (~> 2.7.0)
sidekiq (~> 3.3)
+ sidetiq (= 0.6.3)
simplecov
sinatra
six
slack-notifier (~> 1.0.0)
slim
- slowpoke
spinach-rails
spring (~> 1.3.1)
spring-commands-rspec (= 1.0.4)
diff --git a/app/assets/images/authbuttons/bitbucket_32.png b/app/assets/images/authbuttons/bitbucket_32.png
deleted file mode 100644
index 27702eb973d..00000000000
--- a/app/assets/images/authbuttons/bitbucket_32.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/authbuttons/github_32.png b/app/assets/images/authbuttons/github_32.png
deleted file mode 100644
index 0445b567bbc..00000000000
--- a/app/assets/images/authbuttons/github_32.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/authbuttons/gitlab_32.png b/app/assets/images/authbuttons/gitlab_32.png
deleted file mode 100644
index f3b78cb6efb..00000000000
--- a/app/assets/images/authbuttons/gitlab_32.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/authbuttons/gitlab_64.png b/app/assets/images/authbuttons/gitlab_64.png
index ff2945fe89e..31281a19444 100644
--- a/app/assets/images/authbuttons/gitlab_64.png
+++ b/app/assets/images/authbuttons/gitlab_64.png
Binary files differ
diff --git a/app/assets/images/authbuttons/google_32.png b/app/assets/images/authbuttons/google_32.png
deleted file mode 100644
index b03c3ec5207..00000000000
--- a/app/assets/images/authbuttons/google_32.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/authbuttons/twitter_32.png b/app/assets/images/authbuttons/twitter_32.png
deleted file mode 100644
index a3d4964f40f..00000000000
--- a/app/assets/images/authbuttons/twitter_32.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee
index f2753170478..bf71c144eaf 100644
--- a/app/assets/javascripts/issue.js.coffee
+++ b/app/assets/javascripts/issue.js.coffee
@@ -19,6 +19,6 @@ class @Issue
$('.issue-details').waitForImages ->
$('.issuable-affix').affix offset:
top: ->
- @top = $('.issue-details').outerHeight(true) + 25
+ @top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee
index 1fee9dc1892..09c202e42a5 100644
--- a/app/assets/javascripts/merge_request.js.coffee
+++ b/app/assets/javascripts/merge_request.js.coffee
@@ -23,7 +23,7 @@ class @MergeRequest
$('.merge-request-details').waitForImages ->
$('.issuable-affix').affix offset:
top: ->
- @top = $('.merge-request-details').outerHeight(true) + 91
+ @top = ($('.issuable-affix').offset().top - 70)
bottom: ->
@bottom = $('.footer').outerHeight(true)
@@ -110,7 +110,7 @@ class @MergeRequest
showCiState: (state) ->
$('.ci_widget').hide()
- allowed_states = ["failed", "running", "pending", "success"]
+ allowed_states = ["failed", "canceled", "running", "pending", "success"]
if state in allowed_states
$('.ci_widget.ci-' + state).show()
else
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index 90e6fd6d154..c366c98cf54 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -425,7 +425,7 @@ class @Notes
@removeDiscussionNoteForm(form)
updateVotes: ->
- (new NotesVotes).updateVotes()
+ true
###
Called after an attachment file has been selected.
diff --git a/app/assets/javascripts/notes_votes.js.coffee b/app/assets/javascripts/notes_votes.js.coffee
deleted file mode 100644
index 65c149b7886..00000000000
--- a/app/assets/javascripts/notes_votes.js.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-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)
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index 876eea72e8a..db393e08819 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -355,3 +355,22 @@ table {
bottom: 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;
+ }
+}
diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss
index 31fe5a03f37..266041403e0 100644
--- a/app/assets/stylesheets/generic/forms.scss
+++ b/app/assets/stylesheets/generic/forms.scss
@@ -15,10 +15,6 @@ input[type='text'].danger {
text-shadow: 0 1px 1px #fff
}
-fieldset legend {
- font-size: 16px;
-}
-
.datetime-controls {
select {
width: 100px;
diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss
index e408211fc7d..af9c83e5dc8 100644
--- a/app/assets/stylesheets/pages/dashboard.scss
+++ b/app/assets/stylesheets/pages/dashboard.scss
@@ -29,7 +29,7 @@
line-height: 24px;
.str-truncated {
- max-width: 75%;
+ max-width: 72%;
}
a {
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 83f65913ee6..7b7bb88bc20 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -11,8 +11,10 @@
z-index: 10;
> span {
- @include str-truncated(65%);
font-family: $monospace_font;
+ word-break: break-all;
+ margin-right: 200px;
+ display: block;
}
.diff-btn-group {
diff --git a/app/assets/stylesheets/pages/header.scss b/app/assets/stylesheets/pages/header.scss
index 26b4d04106e..dde19b801f8 100644
--- a/app/assets/stylesheets/pages/header.scss
+++ b/app/assets/stylesheets/pages/header.scss
@@ -31,7 +31,7 @@ header {
.navbar-toggle {
color: $style_color;
- margin: 0 -15px 0 0;
+ margin: 0;
padding: 10px;
border-radius: 0;
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index d8d12338859..a640a4e2051 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -25,7 +25,7 @@
}
.issuable-context-title {
- font-size: 15px;
+ font-size: 14px;
line-height: 1.4;
margin-bottom: 5px;
@@ -39,3 +39,9 @@
margin-right: 4px;
}
}
+
+.issuable-affix .context {
+ font-size: 13px;
+
+ .btn { font-size: 13px; }
+}
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index d366300511e..83b866c3a64 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -113,3 +113,12 @@
}
}
}
+
+.oauth-image-link {
+ margin-right: 10px;
+
+ img {
+ width: 32px;
+ height: 32px;
+ }
+}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 394b59b7e4b..d8fe339b7b3 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -155,6 +155,12 @@
background-color: #FAF1F1;
}
+ &.ci-canceled {
+ color: $gl-warning;
+ border-color: $gl-danger;
+ background-color: #FAF5F1;
+ }
+
&.ci-error {
color: $gl-danger;
border-color: $gl-danger;
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 81afe05162f..65655d4bfa3 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -1,31 +1,7 @@
.account-page {
fieldset {
margin-bottom: 15px;
- border-bottom: 1px dashed #ddd;
padding-bottom: 15px;
-
- &:last-child {
- border: none;
- }
-
- legend {
- border: none;
- margin-bottom: 10px;
- }
- }
-}
-
-.oauth_select_holder {
- img {
- padding: 2px;
- margin-right: 10px;
- }
- .active {
- img {
- border: 1px solid #4BD;
- background: $hover;
- @include border-radius(5px);
- }
}
}
@@ -41,11 +17,6 @@
}
}
-.user-show-username {
- font-weight: 200;
- color: #666;
-}
-
/*
* Appearance settings
*
@@ -106,3 +77,19 @@
}
}
}
+
+.oauth-buttons {
+ .btn-group {
+ margin-right: 10px;
+ }
+
+ .btn {
+ line-height: 36px;
+ height: 56px;
+
+ img {
+ width: 32px;
+ height: 32px;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 74755951670..6d55a5fa66e 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -49,16 +49,20 @@
@extend .clearfix;
margin-bottom: 15px;
+ .project-home-desc,
+ .star-fork-buttons {
+ font-size: 16px;
+ line-height: 1.3;
+ }
+
.project-home-desc {
float: left;
color: #666;
- font-size: 16px;
}
.star-fork-buttons {
float: right;
min-width: 200px;
- font-size: 14px;
font-weight: bold;
.star-buttons, .fork-buttons {
diff --git a/app/assets/stylesheets/pages/votes.scss b/app/assets/stylesheets/pages/votes.scss
index ba0a519dca6..dc9a7d71e8b 100644
--- a/app/assets/stylesheets/pages/votes.scss
+++ b/app/assets/stylesheets/pages/votes.scss
@@ -1,39 +1,4 @@
-.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 {
display: inline-block;
margin: 0 8px;
}
-
diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss
index 42dbf4d6ef3..1be0551ad3b 100644
--- a/app/assets/stylesheets/print.scss
+++ b/app/assets/stylesheets/print.scss
@@ -11,3 +11,7 @@ header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {di
.wiki h1 {font-size: 30px;}
.wiki h2 {font-size: 22px;}
.wiki h3 {font-size: 18px; font-weight: bold; }
+
+.sidebar-wrapper { display: none; }
+.nav { display: none; }
+.btn { display: none; }
diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb
index fe121691a10..9bd34fe2261 100644
--- a/app/controllers/profiles/accounts_controller.rb
+++ b/app/controllers/profiles/accounts_controller.rb
@@ -4,4 +4,10 @@ class Profiles::AccountsController < ApplicationController
def show
@user = current_user
end
+
+ def unlink
+ provider = params[:provider]
+ current_user.identities.find_by(provider: provider).destroy
+ redirect_to profile_account_path
+ end
end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 1b9a86ee42c..9252e85e8cc 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -25,7 +25,8 @@ class ProfilesController < ApplicationController
if @user.update_attributes(user_params)
flash[:notice] = "Profile was successfully updated"
else
- flash[:alert] = "Failed to update profile"
+ messages = @user.errors.full_messages.uniq.join('. ')
+ flash[:alert] = "Failed to update profile. #{messages}"
end
respond_to do |format|
@@ -68,7 +69,7 @@ class ProfilesController < ApplicationController
params.require(:user).permit(
:email, :password, :password_confirmation, :bio, :name, :username,
: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
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index c63a9b0cd44..e9b7d7e0083 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -160,10 +160,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def ci_status
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)
- 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
response = {
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 55926a1ed22..a3284c82d3f 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -2,34 +2,34 @@ class SearchController < ApplicationController
include SearchHelper
def show
+ return if params[:search].nil? || params[:search].blank?
@project = Project.find_by(id: params[:project_id]) if params[:project_id].present?
@group = Group.find_by(id: params[:group_id]) if params[:group_id].present?
@scope = params[:scope]
@show_snippets = params[:snippets].eql? 'true'
- @search_results = if @project
- return access_denied! unless can?(current_user, :download_code, @project)
-
- unless %w(blobs notes issues merge_requests wiki_blobs).
- include?(@scope)
- @scope = 'blobs'
- end
-
- Search::ProjectService.new(@project, current_user, params).execute
- elsif @show_snippets
- unless %w(snippet_blobs snippet_titles).include?(@scope)
- @scope = 'snippet_blobs'
- end
-
- Search::SnippetService.new(current_user, params).execute
- else
- unless %w(projects issues merge_requests).include?(@scope)
- @scope = 'projects'
- end
-
- Search::GlobalService.new(current_user, params).execute
- end
-
+ @search_results =
+ if @project
+ return access_denied! unless can?(current_user, :download_code, @project)
+
+ unless %w(blobs notes issues merge_requests wiki_blobs).
+ include?(@scope)
+ @scope = 'blobs'
+ end
+
+ Search::ProjectService.new(@project, current_user, params).execute
+ elsif @show_snippets
+ unless %w(snippet_blobs snippet_titles).include?(@scope)
+ @scope = 'snippet_blobs'
+ end
+
+ Search::SnippetService.new(current_user, params).execute
+ else
+ unless %w(projects issues merge_requests).include?(@scope)
+ @scope = 'projects'
+ end
+ Search::GlobalService.new(current_user, params).execute
+ end
@objects = @search_results.objects(@scope, params[:page])
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 8ed6d59c20d..38b5fc4a011 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -174,16 +174,10 @@ module ApplicationHelper
Digest::SHA1.hexdigest string
end
- def authbutton(provider, size = 64)
- file_name = "#{provider.to_s.split('_').first}_#{size}.png"
- image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}")
- end
-
def simple_sanitize(str)
sanitize(str, tags: %w(a span))
end
-
def body_data_page
path = controller.controller_path.split('/')
namespace = path.first if path.second
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index b005cb8e417..3386fac8657 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -47,6 +47,5 @@ module GitlabRoutingHelper
def project_snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
-
end
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 3b1589da57f..51b60770e0b 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -35,7 +35,7 @@ module MergeRequestsHelper
end
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
def merge_path_description(merge_request, separator)
diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb
index 1a0ad17b607..997b91de077 100644
--- a/app/helpers/oauth_helper.rb
+++ b/app/helpers/oauth_helper.rb
@@ -20,6 +20,15 @@ module OauthHelper
def additional_providers
enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')}
end
-
+
+ def oauth_image_tag(provider, size = 64)
+ file_name = "#{provider.to_s.split('_').first}_#{size}.png"
+ image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}")
+ end
+
+ def oauth_active?(provider)
+ current_user.identities.exists?(provider: provider.to_s)
+ end
+
extend self
end
diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb
index 9e37e44732a..780c7cd5133 100644
--- a/app/helpers/profile_helper.rb
+++ b/app/helpers/profile_helper.rb
@@ -1,10 +1,4 @@
module ProfileHelper
- def oauth_active_class(provider)
- if current_user.identities.exists?(provider: provider.to_s)
- 'active'
- end
- end
-
def show_profile_username_tab?
current_user.can_change_username?
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 4cbdc612297..798306f6dcc 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -95,11 +95,11 @@ class MergeRequest < ActiveRecord::Base
end
event :mark_as_mergeable do
- transition unchecked: :can_be_merged
+ transition [:unchecked, :cannot_be_merged] => :can_be_merged
end
event :mark_as_unmergeable do
- transition unchecked: :cannot_be_merged
+ transition [:unchecked, :can_be_merged] => :cannot_be_merged
end
state :unchecked
diff --git a/app/models/note.rb b/app/models/note.rb
index 649e9b4e852..27b583a869a 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -59,7 +59,7 @@ class Note < ActiveRecord::Base
class << self
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(
noteable: noteable,
@@ -95,9 +95,9 @@ class Note < ActiveRecord::Base
def create_milestone_change_note(noteable, project, author, milestone)
body = if milestone.nil?
- '_Milestone removed_'
+ 'Milestone removed'
else
- "_Milestone changed to #{milestone.title}_"
+ "Milestone changed to #{milestone.title}"
end
create(
@@ -110,7 +110,7 @@ class Note < ActiveRecord::Base
end
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({
noteable: noteable,
@@ -140,7 +140,7 @@ class Note < ActiveRecord::Base
end
message << ' ' << 'label'.pluralize(labels_count)
- body = "_#{message.capitalize}_"
+ body = "#{message.capitalize}"
create(
noteable: noteable,
@@ -170,14 +170,14 @@ class Note < ActiveRecord::Base
commits_text = ActionController::Base.helpers.pluralize(existing_commits.length, 'commit')
- branch =
+ branch =
if merge_request.for_fork?
"#{merge_request.target_project_namespace}:#{merge_request.target_branch}"
else
merge_request.target_branch
end
- message = "* #{commit_ids} - _#{commits_text} from branch `#{branch}`_"
+ message = "* #{commit_ids} - #{commits_text} from branch `#{branch}`"
body << message
body << "\n"
end
@@ -240,7 +240,7 @@ class Note < ActiveRecord::Base
where(noteable_id: noteable.id)
end
- notes.where('note like ?', cross_reference_note_content(gfm_reference)).
+ notes.where('note like ?', cross_reference_note_pattern(gfm_reference)).
system.any?
end
@@ -249,13 +249,18 @@ class Note < ActiveRecord::Base
end
def cross_reference_note_prefix
- '_mentioned in '
+ 'mentioned in '
end
private
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
# Prepend the mentioner's namespaced project path to the GFM reference for
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 0100f1e4a10..f968afe9fa8 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -93,7 +93,7 @@ class BambooService < CiService
end
end
- def build_page(sha)
+ def build_page(sha, ref)
build_info(sha) if @response.nil? || !@response.code
if @response.code != 200 || @response['results']['results']['size'] == '0'
@@ -106,7 +106,7 @@ class BambooService < CiService
end
end
- def commit_status(sha)
+ def commit_status(sha, ref)
build_info(sha) if @response.nil? || !@response.code
return :error unless @response.code == 200 || @response.code == 404
diff --git a/app/models/project_services/buildbox_service.rb b/app/models/project_services/buildbox_service.rb
index 270863c1576..fef1c9b7349 100644
--- a/app/models/project_services/buildbox_service.rb
+++ b/app/models/project_services/buildbox_service.rb
@@ -48,7 +48,7 @@ class BuildboxService < CiService
service_hook.execute(data)
end
- def commit_status(sha)
+ def commit_status(sha, ref)
response = HTTParty.get(commit_status_path(sha), verify: false)
if response.code == 200 && response['status']
@@ -62,7 +62,7 @@ class BuildboxService < CiService
"#{buildbox_endpoint('gitlab')}/status/#{status_token}.json?commit=#{sha}"
end
- def build_page(sha)
+ def build_page(sha, ref)
"#{project_url}/builds?commit=#{sha}"
end
diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb
index c6f6b4952c9..1a36e439245 100644
--- a/app/models/project_services/ci_service.rb
+++ b/app/models/project_services/ci_service.rb
@@ -34,7 +34,7 @@ class CiService < Service
# Ex.
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
#
- def build_page(sha)
+ def build_page(sha, ref)
# implement inside child
end
@@ -51,7 +51,7 @@ class CiService < Service
# # => 'running'
#
#
- def commit_status(sha)
+ def commit_status(sha, ref)
# implement inside child
end
end
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index d81623625c9..edaeeffc228 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -40,17 +40,17 @@ class GitlabCiService < CiService
service_hook.execute(data)
end
- def commit_status_path(sha)
- project_url + "/commits/#{sha}/status.json?token=#{token}"
+ def commit_status_path(sha, ref)
+ project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}"
end
- def get_ci_build(sha)
+ def get_ci_build(sha, ref)
@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
- def commit_status(sha)
- response = get_ci_build(sha)
+ def commit_status(sha, ref)
+ response = get_ci_build(sha, ref)
if response.code == 200 and response["status"]
response["status"]
@@ -59,16 +59,16 @@ class GitlabCiService < CiService
end
end
- def commit_coverage(sha)
- response = get_ci_build(sha)
+ def commit_coverage(sha, ref)
+ response = get_ci_build(sha, ref)
if response.code == 200 and response["coverage"]
response["coverage"]
end
end
- def build_page(sha)
- project_url + "/commits/#{sha}"
+ def build_page(sha, ref)
+ project_url + "/refs/#{ref}/commits/#{sha}"
end
def builds_path
diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb
index 7403e19da9a..c26bc551352 100644
--- a/app/models/project_services/teamcity_service.rb
+++ b/app/models/project_services/teamcity_service.rb
@@ -88,7 +88,7 @@ class TeamcityService < CiService
@response = HTTParty.get("#{url}", verify: false, basic_auth: auth)
end
- def build_page(sha)
+ def build_page(sha, ref)
build_info(sha) if @response.nil? || !@response.code
if @response.code != 200
@@ -103,7 +103,7 @@ class TeamcityService < CiService
end
end
- def commit_status(sha)
+ def commit_status(sha, ref)
build_info(sha) if @response.nil? || !@response.code
return :error unless @response.code == 200 || @response.code == 404
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 55438bee245..772c868d9cd 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -104,7 +104,7 @@ class ProjectWiki
def page_title_and_dir(title)
title_array = title.split("/")
title = title_array.pop
- [title.gsub(/\.[^.]*$/, ""), title_array.join("/")]
+ [title, title_array.join("/")]
end
def search_files(query)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index c6eaa485b8a..082ad7a0c6a 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -62,24 +62,28 @@ class Repository
def add_branch(branch_name, ref)
cache.expire(:branch_names)
+ @branches = nil
gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
end
def add_tag(tag_name, ref, message = nil)
cache.expire(:tag_names)
+ @tags = nil
gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
end
def rm_branch(branch_name)
cache.expire(:branch_names)
+ @branches = nil
gitlab_shell.rm_branch(path_with_namespace, branch_name)
end
def rm_tag(tag_name)
cache.expire(:tag_names)
+ @tags = nil
gitlab_shell.rm_tag(path_with_namespace, tag_name)
end
@@ -180,8 +184,17 @@ class Repository
end
end
+ def lookup_cache
+ @lookup_cache ||= {}
+ end
+
def method_missing(m, *args, &block)
- raw_repository.send(m, *args, &block)
+ if m == :lookup && !block_given?
+ lookup_cache[m] ||= {}
+ lookup_cache[m][args.join(":")] ||= raw_repository.send(m, *args, &block)
+ else
+ raw_repository.send(m, *args, &block)
+ end
end
def respond_to?(method)
@@ -235,12 +248,20 @@ class Repository
end
def head_commit
- commit(self.root_ref)
+ @head_commit ||= commit(self.root_ref)
+ end
+
+ def head_tree
+ @head_tree ||= Tree.new(self, head_commit.sha, nil)
end
def tree(sha = :head, path = nil)
if sha == :head
- sha = head_commit.sha
+ if path.nil?
+ return head_tree
+ else
+ sha = head_commit.sha
+ end
end
Tree.new(self, sha, path)
@@ -368,6 +389,18 @@ class Repository
end
end
+ def branches
+ @branches ||= raw_repository.branches
+ end
+
+ def tags
+ @tags ||= raw_repository.tags
+ end
+
+ def root_ref
+ @root_ref ||= raw_repository.root_ref
+ end
+
private
def cache
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 32981a0e664..e9413c34bae 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -179,7 +179,8 @@ class WikiPage
if valid? && project_wiki.send(method, *args)
page_details = if method == :update_page
- @page.path
+ # Use url_path instead of path to omit format extension
+ @page.url_path
else
title
end
diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb
index af4b537cb93..4115d689925 100644
--- a/app/services/create_tag_service.rb
+++ b/app/services/create_tag_service.rb
@@ -40,7 +40,8 @@ class CreateTagService < BaseService
end
def create_push_data(project, user, tag)
+ commits = [project.repository.commit(tag.target)].compact
Gitlab::PushDataBuilder.
- build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", [])
+ build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message)
end
end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 4885e1b2fc5..1f0b29dff5e 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -23,42 +23,40 @@ class GitPushService
project.repository.expire_cache
project.update_repository_size
- if push_to_branch?(ref)
- if push_remove_branch?(ref, newrev)
- @push_commits = []
- elsif push_to_new_branch?(ref, oldrev)
- # Re-find the pushed commits.
- if is_default_branch?(ref)
- # Initial push to the default branch. Take the full history of that branch as "newly pushed".
- @push_commits = project.repository.commits(newrev)
-
- # Set protection on the default branch if configured
- if (current_application_settings.default_branch_protection != PROTECTION_NONE)
- developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
- project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push })
- end
- else
- # Use the pushed commits that aren't reachable by the default branch
- # as a heuristic. This may include more commits than are actually pushed, but
- # that shouldn't matter because we check for existing cross-references later.
- @push_commits = project.repository.commits_between(project.default_branch, newrev)
-
- # don't process commits for the initial push to the default branch
- process_commit_messages(ref)
+ if push_remove_branch?(ref, newrev)
+ @push_commits = []
+ elsif push_to_new_branch?(ref, oldrev)
+ # Re-find the pushed commits.
+ if is_default_branch?(ref)
+ # Initial push to the default branch. Take the full history of that branch as "newly pushed".
+ @push_commits = project.repository.commits(newrev)
+
+ # Set protection on the default branch if configured
+ if (current_application_settings.default_branch_protection != PROTECTION_NONE)
+ developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false
+ project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push })
end
- elsif push_to_existing_branch?(ref, oldrev)
- # Collect data for this git push
- @push_commits = project.repository.commits_between(oldrev, newrev)
- project.update_merge_requests(oldrev, newrev, ref, @user)
+ else
+ # Use the pushed commits that aren't reachable by the default branch
+ # as a heuristic. This may include more commits than are actually pushed, but
+ # that shouldn't matter because we check for existing cross-references later.
+ @push_commits = project.repository.commits_between(project.default_branch, newrev)
+
+ # don't process commits for the initial push to the default branch
process_commit_messages(ref)
end
+ elsif push_to_existing_branch?(ref, oldrev)
+ # Collect data for this git push
+ @push_commits = project.repository.commits_between(oldrev, newrev)
+ project.update_merge_requests(oldrev, newrev, ref, @user)
+ process_commit_messages(ref)
+ end
- @push_data = build_push_data(oldrev, newrev, ref)
+ @push_data = build_push_data(oldrev, newrev, ref)
- EventCreateService.new.push(project, user, @push_data)
- project.execute_hooks(@push_data.dup, :push_hooks)
- project.execute_services(@push_data.dup, :push_hooks)
- end
+ EventCreateService.new.push(project, user, @push_data)
+ project.execute_hooks(@push_data.dup, :push_hooks)
+ project.execute_services(@push_data.dup, :push_hooks)
end
protected
@@ -109,7 +107,7 @@ class GitPushService
def push_to_existing_branch?(ref, oldrev)
# 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
def push_to_new_branch?(ref, oldrev)
diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb
index 0d8e6e85e47..bf203bbd692 100644
--- a/app/services/git_tag_push_service.rb
+++ b/app/services/git_tag_push_service.rb
@@ -3,7 +3,7 @@ class GitTagPushService
def execute(project, user, oldrev, newrev, ref)
@project, @user = project, user
-
+
@push_data = build_push_data(oldrev, newrev, ref)
EventCreateService.new.push(project, user, @push_data)
@@ -18,6 +18,20 @@ class GitTagPushService
private
def build_push_data(oldrev, newrev, ref)
- Gitlab::PushDataBuilder.build(project, user, oldrev, newrev, ref, [])
+ commits = []
+ message = nil
+
+ if !Gitlab::Git.blank_ref?(newrev)
+ tag_name = Gitlab::Git.ref_name(ref)
+ tag = project.repository.find_tag(tag_name)
+ if tag && tag.target == newrev
+ commit = project.repository.commit(tag.target)
+ commits = [commit].compact
+ message = tag.message
+ end
+ end
+
+ Gitlab::PushDataBuilder.
+ build(project, user, oldrev, newrev, ref, commits, message)
end
end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 848ed77ebf8..cc5853144c5 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -120,7 +120,7 @@ class NotificationService
return true unless note.noteable_type.present?
# 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
opts = { noteable_type: note.noteable_type, project_id: note.project_id }
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 4cd1c303b22..b647b906b71 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -5,6 +5,6 @@
- providers.each do |provider|
%span.light
- if default_providers.include?(provider)
- = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
+ = link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), class: 'oauth-image-link'
- else
= link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn"
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 25efe973d4f..8df9366ecbe 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -1,12 +1,13 @@
.dashboard
- %div
+ .header-with-avatar.clearfix
= image_tag group_icon(@group), class: "avatar group-avatar s90"
- .clearfix
- %h2
- = @group.name
- - if @group.description.present?
- %p
- = escaped_autolink(@group.description)
+ %h3
+ = @group.name
+ .username
+ @#{@group.path}
+ - if @group.description.present?
+ .description
+ = escaped_autolink(@group.description)
%hr
.row
%section.activities.col-md-8
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 6bafcb56551..5bffb4acc1d 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -1,11 +1,6 @@
-%h3.page-title
- Account Settings
-%p.light
- You can change your username and private token here.
- - if current_user.ldap_user?
+- if current_user.ldap_user?
+ .alert.alert-info
Some options are unavailable for LDAP accounts
-%hr
-
.account-page
%fieldset.update-token
@@ -33,12 +28,16 @@
- if show_profile_social_tab?
%fieldset
- %legend Social Accounts
- .oauth_select_holder.append-bottom-10
+ %legend Connected Accounts
+ .oauth-buttons.append-bottom-10
%p Click on icon to activate signin with one of the following services
- enabled_social_providers.each do |provider|
- %span{class: oauth_active_class(provider) }
- = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider)
+ .btn-group
+ = link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
+ class: "btn btn-lg #{'active' if oauth_active?(provider)}"
+ - if oauth_active?(provider)
+ = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
+ %i.fa.fa-close
- if show_profile_username_tab?
%fieldset.update-username
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 409b6b5a193..5a501e43149 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -54,6 +54,9 @@
= f.label :website_url, 'Website', class: "control-label"
.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
= f.label :bio, class: "control-label"
.col-sm-10
= f.text_area :bio, rows: 4, class: "form-control", maxlength: 250
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index fd8320adb8d..35f7e7bb34b 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -2,8 +2,5 @@
.commit-button-annotation
= button_tag 'Commit Changes',
class: 'btn commit-btn js-commit-button btn-create'
- .message
- to branch
- %strong= ref
= link_to 'Cancel', cancel_path,
class: 'btn btn-cancel', data: {confirm: leave_edit_message}
diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml
index fc3e35640dc..0d3028d50b4 100644
--- a/app/views/projects/issues/_discussion.html.haml
+++ b/app/views/projects/issues/_discussion.html.haml
@@ -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"
.row
%section.col-md-9
+ .votes-holder.pull-right
+ #votes= render 'votes/votes_block', votable: @issue
.participants
%span= pluralize(@issue.participants.count, 'participant')
- @issue.participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24)
-
.voting_notes#notes= render "projects/notes/notes_with_form"
%aside.col-md-3
.issuable-affix
@@ -20,15 +21,10 @@
%hr
.context
= render partial: 'issue_context', locals: { issue: @issue }
- %hr
- .clearfix
- .votes-holder
- %h6 Votes
- #votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any?
- %hr
- %h6 Labels
+ .issuable-context-title
+ %label Labels
.issue-show-labels
- @issue.labels.each do |label|
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 3b50ce01351..7b06fe72882 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -17,7 +17,7 @@
= issue.notes.count
.issue-info
- %span.light= "##{issue.iid}"
+ = link_to "##{issue.iid}", issue_path(issue), class: "light"
- if issue.assignee
assigned to #{link_to_member(@project, issue.assignee)}
- if issue.votes_count > 0
diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml
index d43ce0aa293..91fe0b68371 100644
--- a/app/views/projects/issues/_issue_context.html.haml
+++ b/app/views/projects/issues/_issue_context.html.haml
@@ -45,5 +45,5 @@
:coffeescript
$ ->
new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}")
-
- \ No newline at end of file
+
+
diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml
index 79a093dc775..eb72eaabd8b 100644
--- a/app/views/projects/merge_requests/_discussion.html.haml
+++ b/app/views/projects/merge_requests/_discussion.html.haml
@@ -7,6 +7,8 @@
.row
%section.col-md-9
+ .votes-holder.pull-right
+ #votes= render 'votes/votes_block', votable: @merge_request
= render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form"
%aside.col-md-3
@@ -17,14 +19,10 @@
%hr
.context
= 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?
- %hr
- %h6 Labels
+ .issuable-context-title
+ %label Labels
.merge-request-show-labels
- @merge_request.labels.each do |label|
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 1eba1a96b7b..ecbff722b42 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -22,7 +22,7 @@
%i.fa.fa-comments
= merge_request.mr_and_commit_notes.count
.merge-request-info
- %span.light= "##{merge_request.iid}"
+ = link_to "##{merge_request.iid}", merge_request_path(merge_request), class: "light"
- if merge_request.assignee
assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)}
- else
diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml
index 85a7103f3bc..ffa3f7b0e36 100644
--- a/app/views/projects/merge_requests/show/_mr_ci.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml
@@ -23,6 +23,12 @@
%i.fa.fa-spinner
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"}
%i.fa.fa-times
%span Cannot connect to the CI server. Please check your settings and try again.
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 7fc612c0c7d..9687c8ad87c 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -21,64 +21,65 @@
= f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2}
%hr
- .js-toggle-container
+
+ .project-import.js-toggle-container
.form-group
- .col-sm-2
+ %label.control-label Import project from
.col-sm-10
- = link_to "#", class: 'js-toggle-button' do
- %i.fa.fa-upload
- %span Import existing repository by URL
- .js-toggle-content.hide
- .form-group.import-url-data
- = f.label :import_url, class: 'control-label' do
- %span Import existing git repo
- .col-sm-10
- = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git'
- .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"}
+ - if github_import_enabled?
+ = 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'
- .project-import.form-group
- %label.control-label Import projects from
- .col-sm-10
- - if github_import_enabled?
- = 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
+ - 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-heart
- GitLab.com
- = render 'gitlab_import_modal'
+ %i.fa.fa-bitbucket
+ Bitbucket
+ = render 'bitbucket_import_modal'
- = link_to new_import_gitorious_path, class: 'btn' do
- %i.icon-gitorious.icon-gitorious-small
- Gitorious.org
+ - 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
+ = 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
@@ -111,6 +112,6 @@
$ ->
$('.how_to_import_link').bind 'click', (e) ->
e.preventDefault()
- import_modal = $(this).parent().find(".modal").show()
+ import_modal = $(this).next(".modal").show()
$('.modal-header .close').bind 'click', ->
$(".modal").hide()
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index cfa6cda0466..cfa6f558dd6 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -73,7 +73,7 @@
%span.light Created on
#{@project.created_at.stamp('Aug 22, 2013')}
%p
- %span.light Owned by
+ %span.light Owned by #{@project.group ? "the" : nil}
- if @project.group
#{link_to @project.group.name, @project.group} group
- else
diff --git a/app/views/users/_profile.html.haml b/app/views/users/_profile.html.haml
index 0a70b738071..bca71444956 100644
--- a/app/views/users/_profile.html.haml
+++ b/app/views/users/_profile.html.haml
@@ -21,7 +21,7 @@
%li
%span.light Website:
%strong= link_to user.short_website_url, user.full_website_url
- - unless user.bio.blank?
+ - unless user.location.blank?
%li
- %span.light Bio:
- %span= user.bio
+ %span.light Location:
+ %strong= user.location
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 6d6beb58711..fd96020d129 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -2,24 +2,28 @@
= link_to '#aside', class: 'show-aside' do
%i.fa.fa-angle-left
%section.col-md-8
- %h3.page-title
+ .header-with-avatar
= image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: ''
- = @user.name
- - if @user == current_user
- .pull-right
- = link_to profile_path, class: 'btn' do
- %i.fa.fa-pencil-square-o
- Edit Profile settings
- %br
- %span.user-show-username #{@user.username}
- %br
- %small member since #{@user.created_at.stamp("Nov 12, 2031")}
+ %h3
+ = @user.name
+ - if @user == current_user
+ .pull-right
+ = link_to profile_path, class: 'btn btn-sm' do
+ %i.fa.fa-pencil-square-o
+ Edit Profile settings
+ .username
+ @#{@user.username}
+ .description
+ - if @user.bio.present?
+ = @user.bio
+
.clearfix
- if @groups.any?
- %h4 Groups
- = render 'groups', groups: @groups
- %hr
+ .prepend-top-20
+ %h4 Groups
+ = render 'groups', groups: @groups
+ %hr
.hidden-xs
.user-calendar
diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml
index 788d9065a7b..36ea6742064 100644
--- a/app/views/votes/_votes_block.html.haml
+++ b/app/views/votes/_votes_block.html.haml
@@ -1,6 +1,10 @@
.votes.votes-block
- .progress
- .progress-bar.progress-bar-success{style: "width: #{votable.upvotes_in_percent}%;"}
- .progress-bar.progress-bar-danger{style: "width: #{votable.downvotes_in_percent}%;"}
- .upvotes= "#{votable.upvotes} up"
- .downvotes= "#{votable.downvotes} down"
+ .btn-group
+ - unless votable.upvotes.zero?
+ .btn.btn-sm.disabled.cgreen
+ %i.fa.fa-thumbs-up
+ = votable.upvotes
+ - unless votable.downvotes.zero?
+ .btn.btn-sm.disabled.cred
+ %i.fa.fa-thumbs-down
+ = votable.downvotes
diff --git a/app/views/votes/_votes_inline.html.haml b/app/views/votes/_votes_inline.html.haml
index ee805474830..2cb3ae04e1a 100644
--- a/app/views/votes/_votes_inline.html.haml
+++ b/app/views/votes/_votes_inline.html.haml
@@ -1,9 +1,9 @@
.votes.votes-inline
- unless votable.upvotes.zero?
- .upvotes
+ %span.upvotes.cgreen
+ #{votable.upvotes}
- unless votable.downvotes.zero?
\/
- unless votable.downvotes.zero?
- .downvotes
+ %span.downvotes.cred
\- #{votable.downvotes}
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index e1a99d9cad8..8b50f423984 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -57,9 +57,9 @@ class IrkerWorker
end
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
- elsif push_data['after'] == Gitlab::Git::BLANK_SHA
+ elsif Gitlab::Git.blank_ref?(push_data['after'])
send_del_branch repo_name, committer, branch
end
end
@@ -83,7 +83,7 @@ class IrkerWorker
return if push_data['total_commits_count'] == 0
# 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
push_data['before'] = before_on_new_branch push_data, project
end
diff --git a/config/initializers/public_key.rb b/config/initializers/public_key.rb
index 75d74e3625d..e4f09a2d020 100644
--- a/config/initializers/public_key.rb
+++ b/config/initializers/public_key.rb
@@ -1,2 +1,2 @@
-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)
diff --git a/config/initializers/timeout.rb b/config/initializers/timeout.rb
deleted file mode 100644
index bc88595cf26..00000000000
--- a/config/initializers/timeout.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# 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)
diff --git a/config/routes.rb b/config/routes.rb
index 0950bed3cf1..c30cd768572 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -184,7 +184,11 @@ Gitlab::Application.routes.draw do
end
scope module: :profiles do
- resource :account, only: [:show, :update]
+ resource :account, only: [:show, :update] do
+ member do
+ delete :unlink
+ end
+ end
resource :notifications, only: [:show, :update]
resource :password, only: [:new, :create, :edit, :update] do
member do
@@ -242,7 +246,7 @@ Gitlab::Application.routes.draw do
resources :group_members, only: [:index, :create, :update, :destroy] do
delete :leave, on: :collection
end
-
+
resource :avatar, only: [:destroy]
resources :milestones, only: [:index, :show, :update]
end
@@ -318,14 +322,6 @@ Gitlab::Application.routes.draw do
as: :tree
)
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
get(
@@ -336,8 +332,24 @@ Gitlab::Application.routes.draw do
)
end
- resources :network, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ }
- resources :graphs, only: [:show], constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ } do
+ scope 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
get :commits
end
diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example
index 3aee718097f..86a5512e761 100644
--- a/config/unicorn.rb.example
+++ b/config/unicorn.rb.example
@@ -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 "127.0.0.1:8080", :tcp_nopush => true
-# Kill workers after 1 hour.
-# 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.
-timeout 60 * 60
+# nuke workers after 30 seconds instead of 60 seconds (the default)
+#
+# NOTICE: git push over http depends on this value.
+# 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
pid "/home/git/gitlab/tmp/pids/unicorn.pid"
diff --git a/db/migrate/20150320234437_add_location_to_user.rb b/db/migrate/20150320234437_add_location_to_user.rb
new file mode 100644
index 00000000000..32731d37d75
--- /dev/null
+++ b/db/migrate/20150320234437_add_location_to_user.rb
@@ -0,0 +1,5 @@
+class AddLocationToUser < ActiveRecord::Migration
+ def change
+ add_column :users, :location, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 1be3782dcb3..e1a5b70532a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# 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
enable_extension "plpgsql"
@@ -473,6 +473,7 @@ ActiveRecord::Schema.define(version: 20150313012111) do
t.boolean "password_automatically_set", default: false
t.string "bitbucket_access_token"
t.string "bitbucket_access_token_secret"
+ t.string "location"
end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 1f3fd26a241..6a272539e45 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -375,7 +375,7 @@ Parameters:
}
},
{
- "note": "_Status changed to closed_",
+ "note": "Status changed to closed",
"author": {
"id": 11,
"username": "admin",
diff --git a/doc/api/notes.md b/doc/api/notes.md
index c22e493562a..ee2f9fa0eac 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -21,7 +21,7 @@ Parameters:
[
{
"id": 302,
- "body": "_Status changed to closed_",
+ "body": "Status changed to closed",
"attachment": null,
"author": {
"id": 1,
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index f42af65796f..7a3216dd2d2 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -76,7 +76,7 @@ Notice: The 25 workers of Sidekiq will show up as separate processes in your pro
## 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.
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
- 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)
- Opera (Latest released version)
-- IE 10+
+- IE 10+ \ No newline at end of file
diff --git a/doc/integration/bitbucket.md b/doc/integration/bitbucket.md
index cc6389f5aaf..d82e1f8b41b 100644
--- a/doc/integration/bitbucket.md
+++ b/doc/integration/bitbucket.md
@@ -2,7 +2,7 @@
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.
1. Sign in to Bitbucket.
@@ -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'
1. Select "Save".
-1. You should now see a Key and Secret in the list of OAuth customers.
- Keep this page open as you continue configuration.
+1. You should now see a Key and Secret in the list of OAuth customers.
+ Keep this page open as you continue configuration.
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.
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.
-Click the icon to begin the authentication process. Bitbucket will ask the user to sign in and authorize the GitLab application.
+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.
If everything goes well the user will be returned to GitLab and will be signed in.
## 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.
@@ -95,7 +95,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org
```sh
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.
- 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.
@@ -104,7 +104,7 @@ To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org
### 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:
@@ -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
```
+ 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**.
2. Restart GitLab to allow it to find the new public key.
diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md
index 64f28d46451..b66583bb363 100644
--- a/doc/markdown/markdown.md
+++ b/doc/markdown/markdown.md
@@ -6,7 +6,7 @@
* [Newlines](#newlines)
* [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)
* [Emoji](#emoji)
* [Special GitLab references](#special-gitlab-references)
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index ad302492556..e29ee2a7b3d 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -1,5 +1,5 @@
# Universal update guide for patch versions
-*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/patch_versions.md) for the most up to date instructions.*
+*Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.*
For example from 6.2.0 to 6.2.1, also see the [semantic versioning specification](http://semver.org/).
diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md
index d8476fb3457..f62a53d3340 100644
--- a/doc/update/upgrader.md
+++ b/doc/update/upgrader.md
@@ -24,7 +24,7 @@ If you have local changes to your GitLab repository the script will stash them a
## 2. Run GitLab upgrade tool
-Note: GitLab 7.9 adds nodejs as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies)
+Note: GitLab 7.9 adds `nodejs` as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies)
# Starting with GitLab version 7.0 upgrader script has been moved to bin directory
cd /home/git/gitlab
diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature
new file mode 100644
index 00000000000..431dc4ccfcb
--- /dev/null
+++ b/features/dashboard/new_project.feature
@@ -0,0 +1,13 @@
+@dashboard
+Feature: New Project
+Background:
+ Given I sign in as a user
+ And I own project "Shop"
+ And I visit dashboard page
+
+ @javascript
+ Scenario: I should see New projects page
+ Given I click "New project" link
+ Then I see "New project" page
+ When I click on "Import project from GitHub"
+ Then I see instructions on how to import from GitHub
diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb
new file mode 100644
index 00000000000..5e588ceb780
--- /dev/null
+++ b/features/steps/dashboard/new_project.rb
@@ -0,0 +1,27 @@
+class Spinach::Features::NewProject < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedProject
+
+ step 'I click "New project" link' do
+ click_link "New project"
+ end
+
+ step 'I see "New project" page' do
+ page.should have_content("Project path")
+ end
+
+ step 'I click on "Import project from GitHub"' do
+ first('.how_to_import_link').click
+ end
+
+ step 'I see instructions on how to import from GitHub' do
+ github_modal = first('.modal-body')
+ github_modal.should be_visible
+ github_modal.should have_content "To enable importing projects from GitHub"
+
+ all('.modal-body').each do |element|
+ element.should_not be_visible unless element == github_modal
+ end
+ end
+end
diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb
index bfbfe7af199..791982d16c3 100644
--- a/features/steps/profile/profile.rb
+++ b/features/steps/profile/profile.rb
@@ -11,6 +11,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
fill_in "user_linkedin", with: "testlinkedin"
fill_in "user_twitter", with: "testtwitter"
fill_in "user_website_url", with: "testurl"
+ fill_in "user_location", with: "Ukraine"
click_button "Save changes"
@user.reload
end
@@ -20,6 +21,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
@user.linkedin.should == 'testlinkedin'
@user.twitter.should == 'testtwitter'
@user.website_url.should == 'testurl'
+ find("#user_location").value.should == "Ukraine"
end
step 'I change my avatar' do
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index ab8db4e9837..c6087830b40 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -11,22 +11,27 @@ module Backup
s[:tar_version] = tar_version
tar_file = "#{s[:backup_created_at].to_i}_gitlab_backup.tar"
- Dir.chdir(Gitlab.config.backup.path)
+ Dir.chdir(Gitlab.config.backup.path) do
+ File.open("#{Gitlab.config.backup.path}/backup_information.yml",
+ "w+") do |file|
+ file << s.to_yaml.gsub(/^---\n/,'')
+ end
- File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file|
- file << s.to_yaml.gsub(/^---\n/,'')
- end
+ FileUtils.chmod_R(0700, %w{db uploads repositories})
- # create archive
- $progress.print "Creating backup archive: #{tar_file} ... "
- if Kernel.system('tar', '-cf', tar_file, *BACKUP_CONTENTS)
- $progress.puts "done".green
- else
- puts "creating archive #{tar_file} failed".red
- abort 'Backup failed'
- end
+ # create archive
+ $progress.print "Creating backup archive: #{tar_file} ... "
+ orig_umask = File.umask(0077)
+ if Kernel.system('tar', '-cf', tar_file, *BACKUP_CONTENTS)
+ $progress.puts "done".green
+ else
+ puts "creating archive #{tar_file} failed".red
+ abort 'Backup failed'
+ end
+ File.umask(orig_umask)
- upload(tar_file)
+ upload(tar_file)
+ end
end
def upload(tar_file)
@@ -51,11 +56,13 @@ module Backup
def cleanup
$progress.print "Deleting tmp directories ... "
- if Kernel.system('rm', '-rf', *BACKUP_CONTENTS)
- $progress.puts "done".green
- else
- puts "deleting tmp directory failed".red
- abort 'Backup failed'
+ BACKUP_CONTENTS.each do |dir|
+ if FileUtils.rm_rf(File.join(Gitlab.config.backup.path, dir))
+ $progress.puts "done".green
+ else
+ puts "deleting tmp directory '#{dir}' failed".red
+ abort 'Backup failed'
+ end
end
end
diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb
index e18bc804437..dfb2da9f84e 100644
--- a/lib/backup/repository.rb
+++ b/lib/backup/repository.rb
@@ -16,7 +16,7 @@ module Backup
if project.empty_repo?
$progress.puts "[SKIPPED]".cyan
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)
if status.zero?
$progress.puts "[DONE]".green
@@ -64,7 +64,8 @@ module Backup
project.namespace.ensure_dir_exist if project.namespace
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
cmd = %W(git init --bare #{path_to_repo(project)})
end
diff --git a/lib/gitlab/force_push_check.rb b/lib/gitlab/force_push_check.rb
index eae9773a067..fdb6a35c78d 100644
--- a/lib/gitlab/force_push_check.rb
+++ b/lib/gitlab/force_push_check.rb
@@ -3,11 +3,12 @@ module Gitlab
def self.force_push?(project, oldrev, newrev)
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.split("\n").size > 0
- else
- false
end
end
end
diff --git a/lib/gitlab/middleware/timeout.rb b/lib/gitlab/middleware/timeout.rb
deleted file mode 100644
index 015600392b9..00000000000
--- a/lib/gitlab/middleware/timeout.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-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
diff --git a/lib/gitlab/push_data_builder.rb b/lib/gitlab/push_data_builder.rb
index 694a30db5df..f8da452e4c0 100644
--- a/lib/gitlab/push_data_builder.rb
+++ b/lib/gitlab/push_data_builder.rb
@@ -21,7 +21,7 @@ module Gitlab
# total_commits_count: Fixnum
# }
#
- def build(project, user, oldrev, newrev, ref, commits = [])
+ def build(project, user, oldrev, newrev, ref, commits = [], message = nil)
# Total commits count
commits_count = commits.size
@@ -42,6 +42,7 @@ module Gitlab
after: newrev,
ref: ref,
checkout_sha: checkout_sha(project.repository, newrev, ref),
+ message: message,
user_id: user.id,
user_name: user.name,
user_email: user.email,
@@ -71,7 +72,8 @@ module Gitlab
end
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 = repository.find_tag(tag_name)
diff --git a/lib/tasks/brakeman.rake b/lib/tasks/brakeman.rake
index abcb5f0ae46..3a225801ff2 100644
--- a/lib/tasks/brakeman.rake
+++ b/lib/tasks/brakeman.rake
@@ -1,7 +1,7 @@
desc 'Security check via brakeman'
task :brakeman do
if system("brakeman --skip-files lib/backup/repository.rb -w3 -z")
- exit 0
+ puts 'Security check succeed'
else
puts 'Security check failed'
exit 1
diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake
index 189ad6090a4..3c9802a0be4 100644
--- a/lib/tasks/gitlab/cleanup.rake
+++ b/lib/tasks/gitlab/cleanup.rake
@@ -90,13 +90,14 @@ namespace :gitlab do
warn_user_is_not_gitlab
block_flag = ENV['BLOCK']
- User.ldap.each do |ldap_user|
- print "#{ldap_user.name} (#{ldap_user.extern_uid}) ..."
- if Gitlab::LDAP::Access.allowed?(ldap_user)
+ User.find_each do |user|
+ next unless user.ldap_user?
+ print "#{user.name} (#{user.ldap_identity.extern_uid}) ..."
+ if Gitlab::LDAP::Access.allowed?(user)
puts " [OK]".green
else
if block_flag
- ldap_user.block! unless ldap_user.blocked?
+ user.block! unless user.blocked?
puts " [BLOCKED]".red
else
puts " [NOT IN LDAP]".yellow
diff --git a/public/503.html b/public/503.html
deleted file mode 100644
index efdae0f512d..00000000000
--- a/public/503.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!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>
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 7e524aa95cf..b3f4bb5aeda 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -140,4 +140,18 @@ describe Gitlab::ReferenceExtractor do
expect(extracted[0][1].message).to eq(commit.message)
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
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 17cb439c90e..a7bf5081d5b 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -182,14 +182,14 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Status changed to #{status}/) }
+ it { is_expected.to eq("Status changed to #{status}") }
end
it 'appends a back-reference if a closing mentionable is supplied' do
commit = double('commit', gfm_reference: 'commit 123456')
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
@@ -197,7 +197,7 @@ describe Note do
let(:project) { create(:project) }
let(:thing) { create(:issue, project: project) }
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) }
@@ -227,7 +227,7 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Reassigned to @#{assignee.username}/) }
+ it { is_expected.to eq('Reassigned to @assigned_user') }
end
context 'assignee is removed' do
@@ -235,11 +235,95 @@ describe Note do
describe '#note' do
subject { super().note }
- it { is_expected.to match(/Assignee removed/) }
+ it { is_expected.to eq('Assignee removed') }
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
let(:project) { create(:project) }
let(:author) { create(:user) }
@@ -272,7 +356,7 @@ describe Note do
describe '#note' do
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
@@ -288,7 +372,7 @@ describe Note do
describe '#note' do
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
@@ -309,7 +393,7 @@ describe Note do
describe '#note' do
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
@@ -330,7 +414,7 @@ describe Note do
describe '#note' do
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
@@ -362,7 +446,7 @@ describe Note do
describe '#note' do
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
@@ -389,7 +473,7 @@ describe Note do
describe '#note' do
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
@@ -421,6 +505,41 @@ describe Note do
it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy }
it { expect(Note.cross_reference_exists?(commit1, commit0)).to be_falsey }
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
describe '#system?' do
@@ -429,6 +548,8 @@ describe Note do
let(:other) { create(:issue, project: project) }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
+ let(:label) { create(:label) }
+ let(:milestone) { create(:milestone) }
it 'should recognize user-supplied notes as non-system' do
@note = create(:note_on_issue)
@@ -449,6 +570,16 @@ describe Note do
@note = Note.create_assignee_change_note(issue, project, author, assignee)
expect(@note).to be_system
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
describe :authorization do
diff --git a/spec/models/project_services/buildbox_service_spec.rb b/spec/models/project_services/buildbox_service_spec.rb
index 39d7df54cf0..fcbf3e45b9a 100644
--- a/spec/models/project_services/buildbox_service_spec.rb
+++ b/spec/models/project_services/buildbox_service_spec.rb
@@ -59,7 +59,7 @@ describe BuildboxService do
describe :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'
)
end
diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb
index 8bfb19e524b..610f33c5823 100644
--- a/spec/models/project_services/gitlab_ci_service_spec.rb
+++ b/spec/models/project_services/gitlab_ci_service_spec.rb
@@ -39,11 +39,11 @@ describe GitlabCiService do
end
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
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
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index f3fd805783f..fceb7668cac 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -78,6 +78,47 @@ describe WikiPage do
end
end
+ describe "dot in the title" do
+ let(:title) { 'Index v1.2.3' }
+
+ before do
+ @wiki_attr = {title: title, content: "Home Page", format: "markdown"}
+ end
+
+ describe "#create" do
+ after do
+ destroy_page(title)
+ end
+
+ context "with valid attributes" do
+ it "saves the wiki page" do
+ subject.create(@wiki_attr)
+ expect(wiki.find_page(title)).not_to be_nil
+ end
+
+ it "returns true" do
+ expect(subject.create(@wiki_attr)).to eq(true)
+ end
+ end
+ end
+
+ describe "#update" do
+ before do
+ create_page(title, "content")
+ @page = wiki.find_page(title)
+ end
+
+ it "updates the content of the page" do
+ @page.update("new content")
+ @page = wiki.find_page(title)
+ end
+
+ it "returns true" do
+ expect(@page.update("more content")).to be_truthy
+ end
+ end
+ end
+
describe "#update" do
before do
create_page("Update", "content")
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 1b1e3ca5f8b..aa9b15dd9ec 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -145,11 +145,6 @@ describe GitPushService do
expect(project).to receive(:execute_hooks)
service.execute(project, user, 'oldrev', 'newrev', 'refs/heads/master')
end
-
- it "when pushing tags" do
- expect(project).not_to receive(:execute_hooks)
- service.execute(project, user, 'newrev', 'newrev', 'refs/tags/v1.0.0')
- end
end
end
diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb
index fcf462edbfc..a050fdf6c0e 100644
--- a/spec/services/git_tag_push_service_spec.rb
+++ b/spec/services/git_tag_push_service_spec.rb
@@ -1,32 +1,39 @@
require 'spec_helper'
describe GitTagPushService do
+ include RepoHelpers
+
let (:user) { create :user }
let (:project) { create :project }
let (:service) { GitTagPushService.new }
before do
- @ref = 'refs/tags/super-tag'
- @oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81'
- @newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb'
+ @oldrev = Gitlab::Git::BLANK_SHA
+ @newrev = "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b" # gitlab-test: git rev-parse refs/tags/v1.1.0
+ @ref = 'refs/tags/v1.1.0'
end
- describe 'Git Tag Push Data' do
+ describe "Git Tag Push Data" do
before do
service.execute(project, user, @oldrev, @newrev, @ref)
@push_data = service.push_data
+ @tag_name = Gitlab::Git.ref_name(@ref)
+ @tag = project.repository.find_tag(@tag_name)
+ @commit = project.repository.commit(@tag.target)
end
subject { @push_data }
+ it { is_expected.to include(object_kind: 'tag_push') }
it { is_expected.to include(ref: @ref) }
it { is_expected.to include(before: @oldrev) }
it { is_expected.to include(after: @newrev) }
+ it { is_expected.to include(message: @tag.message) }
it { is_expected.to include(user_id: user.id) }
it { is_expected.to include(user_name: user.name) }
it { is_expected.to include(project_id: project.id) }
- context 'With repository data' do
+ context "with repository data" do
subject { @push_data[:repository] }
it { is_expected.to include(name: project.name) }
@@ -34,6 +41,41 @@ describe GitTagPushService do
it { is_expected.to include(description: project.description) }
it { is_expected.to include(homepage: project.web_url) }
end
+
+ context "with commits" do
+ subject { @push_data[:commits] }
+
+ it { is_expected.to be_an(Array) }
+ it 'has 1 element' do
+ expect(subject.size).to eq(1)
+ end
+
+ context "the commit" do
+ subject { @push_data[:commits].first }
+
+ it { is_expected.to include(id: @commit.id) }
+ it { is_expected.to include(message: @commit.safe_message) }
+ it { is_expected.to include(timestamp: @commit.date.xmlschema) }
+ it do
+ is_expected.to include(
+ url: [
+ Gitlab.config.gitlab.url,
+ project.namespace.to_param,
+ project.to_param,
+ 'commit',
+ @commit.id
+ ].join('/')
+ )
+ end
+
+ context "with a author" do
+ subject { @push_data[:commits].first[:author] }
+
+ it { is_expected.to include(name: @commit.author_name) }
+ it { is_expected.to include(email: @commit.author_email) }
+ end
+ end
+ end
end
describe "Web Hooks" do
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 60942cc95fc..8a411b7720a 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -10,17 +10,17 @@ describe 'gitlab:app namespace rake task' do
Rake::Task.define_task :environment
end
+ def run_rake_task(task_name)
+ Rake::Task[task_name].reenable
+ Rake.application.invoke_task task_name
+ end
+
describe 'backup_restore' do
before do
# avoid writing task output to spec progress
allow($stdout).to receive :write
end
- let :run_rake_task do
- Rake::Task["gitlab:backup:restore"].reenable
- Rake.application.invoke_task "gitlab:backup:restore"
- end
-
context 'gitlab version' do
before do
Dir.stub glob: []
@@ -36,7 +36,9 @@ describe 'gitlab:app namespace rake task' do
it 'should fail on mismatch' do
YAML.stub load_file: {gitlab_version: "not #{gitlab_version}" }
- expect { run_rake_task }.to raise_error SystemExit
+ expect { run_rake_task('gitlab:backup:restore') }.to(
+ raise_error SystemExit
+ )
end
it 'should invoke restoration on mach' do
@@ -44,9 +46,56 @@ describe 'gitlab:app namespace rake task' do
expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke
expect(Rake::Task["gitlab:backup:repo:restore"]).to receive :invoke
expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke
- expect { run_rake_task }.to_not raise_error
+ expect { run_rake_task('gitlab:backup:restore') }.to_not raise_error
end
end
end # backup_restore task
+
+ describe 'backup_create' do
+ def tars_glob
+ Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar'))
+ end
+
+ before :all do
+ # Record the existing backup tars so we don't touch them
+ existing_tars = tars_glob
+
+ # Redirect STDOUT and run the rake task
+ orig_stdout = $stdout
+ $stdout = StringIO.new
+ run_rake_task('gitlab:backup:create')
+ $stdout = orig_stdout
+
+ @backup_tar = (tars_glob - existing_tars).first
+ end
+
+ after :all do
+ FileUtils.rm(@backup_tar)
+ end
+
+ it 'should set correct permissions on the tar file' do
+ expect(File.exist?(@backup_tar)).to be_truthy
+ expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100600')
+ end
+
+ it 'should set correct permissions on the tar contents' do
+ tar_contents, exit_status = Gitlab::Popen.popen(
+ %W{tar -tvf #{@backup_tar} db uploads repositories}
+ )
+ expect(exit_status).to eq(0)
+ expect(tar_contents).to match('db/')
+ expect(tar_contents).to match('uploads/')
+ expect(tar_contents).to match('repositories/')
+ expect(tar_contents).not_to match(/^.{4,9}[rwx]/)
+ end
+
+ it 'should delete temp directories' do
+ temp_dirs = Dir.glob(
+ File.join(Gitlab.config.backup.path, '{db,repositories,uploads}')
+ )
+
+ expect(temp_dirs).to be_empty
+ end
+ end # backup_create task
end # gitlab:app namespace